11import { Test , TestingModule } from '@nestjs/testing' ;
2- import { AbuseState } from '@prisma/client' ;
32
43import { ChatsRepository } from './chats.repository' ;
5- import { ChatSaveDto , ChatsService } from './chats.service' ;
6- import {
7- MOCK_CHAT_DATA ,
8- MOCK_CHAT_DATA_NO_NICKNAME ,
9- MOCK_SAVED_CHAT ,
10- MOCK_SAVED_CHAT_NO_NICKNAME ,
11- } from './test-chats.mock' ;
12-
13- import { LoggerService } from '@logger/logger.service' ;
4+ import { ChatsService } from './chats.service' ;
5+ import { MOCK_CHAT_DATA , MOCK_CHAT_DATA_NO_NICKNAME } from './test-chats.mock' ;
146
157describe ( 'ChatsService' , ( ) => {
168 let service : ChatsService ;
179 let chatsRepository : jest . Mocked < ChatsRepository > ;
18- let fetchMock : jest . SpyInstance ;
1910
2011 beforeEach ( async ( ) => {
2112 const module : TestingModule = await Test . createTestingModule ( {
@@ -26,78 +17,19 @@ describe('ChatsService', () => {
2617 useValue : {
2718 save : jest . fn ( ) ,
2819 getChatsForInfiniteScroll : jest . fn ( ) ,
29- getChatsForFilter : jest . fn ( ) ,
30- update : jest . fn ( ) ,
31- } ,
32- } ,
33- {
34- provide : LoggerService ,
35- useValue : {
36- log : jest . fn ( ) ,
37- error : jest . fn ( ) ,
38- warn : jest . fn ( ) ,
39- debug : jest . fn ( ) ,
4020 } ,
4121 } ,
4222 ] ,
4323 } ) . compile ( ) ;
4424
4525 service = module . get < ChatsService > ( ChatsService ) ;
4626 chatsRepository = module . get ( ChatsRepository ) ;
47-
48- fetchMock = jest . spyOn ( global , 'fetch' ) . mockImplementation ( ( ) =>
49- Promise . resolve ( {
50- ok : true ,
51- text : ( ) => Promise . resolve ( JSON . stringify ( { predicted : '일반어' , probability : 0.9 } ) ) ,
52- } as Response ) ,
53- ) ;
5427 } ) ;
5528
5629 it ( '서비스가 정의되어 있어야 한다' , ( ) => {
5730 expect ( service ) . toBeDefined ( ) ;
5831 } ) ;
5932
60- describe ( 'saveChat' , ( ) => {
61- it ( '채팅을 저장하고 저장된 데이터를 반환해야 한다' , async ( ) => {
62- const data : ChatSaveDto = {
63- sessionId : '123' ,
64- token : 'mockToken' ,
65- body : 'Test message' ,
66- } ;
67-
68- chatsRepository . save . mockResolvedValue ( MOCK_SAVED_CHAT ) ;
69-
70- const result = await service . saveChat ( data ) ;
71- expect ( chatsRepository . save ) . toHaveBeenCalledWith ( data ) ;
72- expect ( result ) . toEqual ( {
73- chattingId : 1 ,
74- nickname : 'TestUser' ,
75- content : 'Test chat message' ,
76- abuse : false ,
77- } ) ;
78- } ) ;
79-
80- it ( '사용자의 닉네임이 없는 경우 "익명"을 반환해야 한다' , async ( ) => {
81- const data : ChatSaveDto = {
82- sessionId : '123' ,
83- token : 'mockToken' ,
84- body : 'Test message' ,
85- } ;
86-
87- chatsRepository . save . mockResolvedValue ( MOCK_SAVED_CHAT_NO_NICKNAME ) ;
88-
89- const result = await service . saveChat ( data ) ;
90-
91- expect ( chatsRepository . save ) . toHaveBeenCalledWith ( data ) ;
92- expect ( result ) . toEqual ( {
93- chattingId : 1 ,
94- nickname : '익명' ,
95- content : 'Test message' ,
96- abuse : false ,
97- } ) ;
98- } ) ;
99- } ) ;
100-
10133 describe ( 'getChatsForInfiniteScroll' , ( ) => {
10234 it ( '무한 스크롤을 위한 채팅 목록을 조회해야 한다' , async ( ) => {
10335 const sessionId = '123' ;
@@ -126,73 +58,4 @@ describe('ChatsService', () => {
12658 expect ( result ) . toEqual ( [ { chattingId : 10 , nickname : '익명' , content : 'Message 1' , abuse : false } ] ) ;
12759 } ) ;
12860 } ) ;
129-
130- describe ( 'detectAbuseBatch' , ( ) => {
131- it ( '새로운 채팅들을 필터링하고 상태를 업데이트해야 한다' , async ( ) => {
132- const SAFE_WORD = 'Hello' ;
133- const BAD_WORD = 'Bad word' ;
134-
135- const mockChats = [
136- { ...MOCK_SAVED_CHAT , chattingId : 1 , body : SAFE_WORD } ,
137- { ...MOCK_SAVED_CHAT , chattingId : 2 , body : BAD_WORD } ,
138- ] ;
139-
140- chatsRepository . getChatsForFilter . mockResolvedValue ( mockChats ) ;
141-
142- fetchMock
143- . mockResolvedValueOnce ( {
144- ok : true ,
145- text : ( ) => Promise . resolve ( JSON . stringify ( { predicted : '일반어' , probability : 0.9 } ) ) ,
146- } as Response )
147- . mockResolvedValueOnce ( {
148- ok : true ,
149- text : ( ) => Promise . resolve ( JSON . stringify ( { predicted : '욕설' , probability : 0.9 } ) ) ,
150- } as Response ) ;
151-
152- await service . detectAbuseBatch ( ) ;
153-
154- expect ( chatsRepository . update ) . toHaveBeenCalledWith ( 1 , AbuseState . SAFE ) ;
155- expect ( chatsRepository . update ) . toHaveBeenCalledWith ( 2 , AbuseState . BLOCKED ) ;
156- } ) ;
157- } ) ;
158-
159- describe ( 'checkAbuse' , ( ) => {
160- it ( '욕설이 감지되면 true를 반환해야 한다' , async ( ) => {
161- fetchMock . mockResolvedValueOnce ( {
162- ok : true ,
163- text : ( ) => Promise . resolve ( JSON . stringify ( { predicted : '욕설' , probability : 0.9 } ) ) ,
164- } as Response ) ;
165-
166- const result = await service . checkAbuse ( '욕설 내용' ) ;
167- expect ( result ) . toBe ( true ) ;
168- } ) ;
169-
170- it ( '일반어가 감지되면 false를 반환해야 한다' , async ( ) => {
171- fetchMock . mockResolvedValueOnce ( {
172- ok : true ,
173- text : ( ) => Promise . resolve ( JSON . stringify ( { predicted : '일반어' , probability : 0.9 } ) ) ,
174- } as Response ) ;
175-
176- const result = await service . checkAbuse ( '일반 내용' ) ;
177- expect ( result ) . toBe ( false ) ;
178- } ) ;
179-
180- it ( 'API 요청이 실패하면 false를 반환해야 한다' , async ( ) => {
181- fetchMock . mockResolvedValueOnce ( {
182- ok : false ,
183- status : 500 ,
184- statusText : 'Internal Server Error' ,
185- } as Response ) ;
186-
187- const result = await service . checkAbuse ( '테스트 내용' ) ;
188- expect ( result ) . toBe ( false ) ;
189- } ) ;
190-
191- it ( '네트워크 에러가 발생하면 false를 반환해야 한다' , async ( ) => {
192- fetchMock . mockRejectedValueOnce ( new Error ( 'Network error' ) ) ;
193-
194- const result = await service . checkAbuse ( '테스트 내용' ) ;
195- expect ( result ) . toBe ( false ) ;
196- } ) ;
197- } ) ;
19861} ) ;
0 commit comments