1
- /* eslint-disable jest/no-disabled-tests */
2
1
/**
3
2
* 주의: 이 통합 테스트는 현재 시간에 의존적입니다.
4
3
* getCurrentKSTDateString과 getKSTDateStringWithOffset 함수는 실제 시간을 기준으로
@@ -10,22 +9,21 @@ import dotenv from 'dotenv';
10
9
import pg , { Pool } from 'pg' ;
11
10
import { LeaderboardRepository } from '@/repositories/leaderboard.repository' ;
12
11
import { PostLeaderboardSortType , UserLeaderboardSortType } from '@/types' ;
12
+ import { getKSTDateStringWithOffset } from '@/utils/date.util' ;
13
13
14
14
dotenv . config ( ) ;
15
-
16
- jest . setTimeout ( 60000 ) ; // 각 케이스당 60초 타임아웃 설정
15
+ jest . setTimeout ( 30000 ) ; // 각 케이스당 30초 타임아웃 설정
17
16
18
17
/**
19
18
* LeaderboardRepository 통합 테스트
20
19
*
21
20
* 이 테스트 파일은 실제 데이터베이스와 연결하여 LeaderboardRepository의 모든 메서드를
22
21
* 실제 환경과 동일한 조건에서 테스트합니다.
23
22
*/
24
- describe . skip ( 'LeaderboardRepository 통합 테스트' , ( ) => {
23
+ describe ( 'LeaderboardRepository 통합 테스트' , ( ) => {
25
24
let testPool : Pool ;
26
25
let repo : LeaderboardRepository ;
27
26
28
- // eslint-disable-next-line @typescript-eslint/naming-convention
29
27
const DEFAULT_PARAMS = {
30
28
USER_SORT : 'viewCount' as UserLeaderboardSortType ,
31
29
POST_SORT : 'viewCount' as PostLeaderboardSortType ,
@@ -45,7 +43,7 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
45
43
idleTimeoutMillis : 30000 , // 연결 유휴 시간 (30초)
46
44
connectionTimeoutMillis : 5000 , // 연결 시간 초과 (5초)
47
45
allowExitOnIdle : false , // 유휴 상태에서 종료 허용
48
- statement_timeout : 60000 , // 쿼리 타임아웃 증가 (60초 )
46
+ statement_timeout : 30000 , // 쿼리 타임아웃 증가 (30초 )
49
47
} ;
50
48
51
49
// localhost 가 아니면 ssl 필수
@@ -80,10 +78,17 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
80
78
81
79
afterAll ( async ( ) => {
82
80
try {
83
- jest . clearAllMocks ( ) ;
84
-
85
- // 풀 완전 종료
86
- await testPool . end ( ) ;
81
+ // 모든 쿼리 완료 대기
82
+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
83
+
84
+ // 풀 완전 종료
85
+ if ( testPool ) {
86
+ // 강제 종료: 모든 활성 쿼리와 연결 중지
87
+ await testPool . end ( ) ;
88
+ }
89
+
90
+ // 추가 정리 시간
91
+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
87
92
88
93
logger . info ( 'LeaderboardRepository 통합 테스트 DB 연결 종료' ) ;
89
94
} catch ( error ) {
@@ -225,6 +230,16 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
225
230
expect ( user . username ) . not . toBeNull ( ) ;
226
231
} ) ;
227
232
} ) ;
233
+
234
+ it ( '데이터 수집이 비정상적인 유저는 리더보드에 포함되지 않아야 한다' , async ( ) => {
235
+ const result = await repo . getUserLeaderboard ( DEFAULT_PARAMS . USER_SORT , DEFAULT_PARAMS . DATE_RANGE , 30 ) ;
236
+
237
+ if ( ! isEnoughData ( result , 1 , '사용자 리더보드 비정상 유저 필터링' ) ) return ;
238
+
239
+ result . forEach ( ( user ) => {
240
+ expect ( Number ( user . total_views ) ) . not . toBe ( Number ( user . view_diff ) ) ;
241
+ } ) ;
242
+ } ) ;
228
243
} ) ;
229
244
230
245
describe ( 'getPostLeaderboard' , ( ) => {
@@ -342,6 +357,20 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
342
357
expect ( areDifferent ) . toBe ( true ) ;
343
358
}
344
359
} ) ;
360
+
361
+ it ( '데이터 수집이 비정상적인 게시물은 리더보드에 포함되지 않아야 한다' , async ( ) => {
362
+ const result = await repo . getPostLeaderboard ( DEFAULT_PARAMS . POST_SORT , DEFAULT_PARAMS . DATE_RANGE , 30 ) ;
363
+ const pastDateKST = getKSTDateStringWithOffset ( - DEFAULT_PARAMS . DATE_RANGE * 24 * 60 ) ;
364
+
365
+ if ( ! isEnoughData ( result , 1 , '게시물 리더보드 비정상 게시물 필터링' ) ) return ;
366
+
367
+ result . forEach ( ( post ) => {
368
+ if ( post . released_at < pastDateKST ) {
369
+ // eslint-disable-next-line jest/no-conditional-expect
370
+ expect ( Number ( post . total_views ) ) . not . toBe ( Number ( post . view_diff ) ) ;
371
+ }
372
+ } ) ;
373
+ } ) ;
345
374
} ) ;
346
375
} ) ;
347
376
0 commit comments