1- /* eslint-disable jest/no-disabled-tests */
21/**
32 * 주의: 이 통합 테스트는 현재 시간에 의존적입니다.
43 * getCurrentKSTDateString과 getKSTDateStringWithOffset 함수는 실제 시간을 기준으로
@@ -10,22 +9,21 @@ import dotenv from 'dotenv';
109import pg , { Pool } from 'pg' ;
1110import { LeaderboardRepository } from '@/repositories/leaderboard.repository' ;
1211import { PostLeaderboardSortType , UserLeaderboardSortType } from '@/types' ;
12+ import { getKSTDateStringWithOffset } from '@/utils/date.util' ;
1313
1414dotenv . config ( ) ;
15-
16- jest . setTimeout ( 60000 ) ; // 각 케이스당 60초 타임아웃 설정
15+ jest . setTimeout ( 30000 ) ; // 각 케이스당 30초 타임아웃 설정
1716
1817/**
1918 * LeaderboardRepository 통합 테스트
2019 *
2120 * 이 테스트 파일은 실제 데이터베이스와 연결하여 LeaderboardRepository의 모든 메서드를
2221 * 실제 환경과 동일한 조건에서 테스트합니다.
2322 */
24- describe . skip ( 'LeaderboardRepository 통합 테스트' , ( ) => {
23+ describe ( 'LeaderboardRepository 통합 테스트' , ( ) => {
2524 let testPool : Pool ;
2625 let repo : LeaderboardRepository ;
2726
28- // eslint-disable-next-line @typescript-eslint/naming-convention
2927 const DEFAULT_PARAMS = {
3028 USER_SORT : 'viewCount' as UserLeaderboardSortType ,
3129 POST_SORT : 'viewCount' as PostLeaderboardSortType ,
@@ -45,7 +43,7 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
4543 idleTimeoutMillis : 30000 , // 연결 유휴 시간 (30초)
4644 connectionTimeoutMillis : 5000 , // 연결 시간 초과 (5초)
4745 allowExitOnIdle : false , // 유휴 상태에서 종료 허용
48- statement_timeout : 60000 , // 쿼리 타임아웃 증가 (60초 )
46+ statement_timeout : 30000 , // 쿼리 타임아웃 증가 (30초 )
4947 } ;
5048
5149 // localhost 가 아니면 ssl 필수
@@ -80,10 +78,17 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
8078
8179 afterAll ( async ( ) => {
8280 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 ) ) ;
8792
8893 logger . info ( 'LeaderboardRepository 통합 테스트 DB 연결 종료' ) ;
8994 } catch ( error ) {
@@ -225,6 +230,16 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
225230 expect ( user . username ) . not . toBeNull ( ) ;
226231 } ) ;
227232 } ) ;
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+ } ) ;
228243 } ) ;
229244
230245 describe ( 'getPostLeaderboard' , ( ) => {
@@ -342,6 +357,20 @@ describe.skip('LeaderboardRepository 통합 테스트', () => {
342357 expect ( areDifferent ) . toBe ( true ) ;
343358 }
344359 } ) ;
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+ } ) ;
345374 } ) ;
346375} ) ;
347376
0 commit comments