@@ -2,7 +2,6 @@ import 'reflect-metadata';
2
2
import { Request , Response } from 'express' ;
3
3
import { WebhookController } from '@/controllers/webhook.controller' ;
4
4
import { sendSlackMessage } from '@/modules/slack/slack.notifier' ;
5
- import { SentryWebhookData } from '@/types' ;
6
5
7
6
// Mock dependencies
8
7
jest . mock ( '@/modules/slack/slack.notifier' ) ;
@@ -44,15 +43,16 @@ describe('WebhookController', () => {
44
43
} ) ;
45
44
46
45
describe ( 'handleSentryWebhook' , ( ) => {
47
- const mockSentryData : SentryWebhookData = {
46
+ // 실제 동작에 필요한 필수 값만 사용하도록 타입 미적용
47
+ const mockSentryData = {
48
48
action : 'created' ,
49
49
data : {
50
50
issue : {
51
51
id : 'test-issue-123' ,
52
52
title : '테스트 오류입니다' ,
53
53
culprit : 'TestFile.js:10' ,
54
54
status : 'unresolved' ,
55
- count : 5 ,
55
+ count : "5" ,
56
56
userCount : 3 ,
57
57
firstSeen : '2024-01-01T12:00:00.000Z' ,
58
58
permalink : 'https://velog-dashboardv2.sentry.io/issues/test-issue-123/' ,
@@ -179,6 +179,61 @@ describe('WebhookController', () => {
179
179
) ;
180
180
} ) ;
181
181
182
+ it ( 'assigned 액션에 대해 올바른 메시지를 생성해야 한다' , async ( ) => {
183
+ const assignedData = {
184
+ ...mockSentryData ,
185
+ action : 'assigned' as const ,
186
+ data : {
187
+ ...mockSentryData . data ,
188
+ issue : {
189
+ ...mockSentryData . data . issue ,
190
+ status : 'unresolved' as const
191
+ }
192
+ }
193
+ } ;
194
+ mockRequest . body = assignedData ;
195
+ mockSendSlackMessage . mockResolvedValue ( ) ;
196
+
197
+ await webhookController . handleSentryWebhook (
198
+ mockRequest as Request ,
199
+ mockResponse as Response ,
200
+ nextFunction
201
+ ) ;
202
+
203
+ expect ( mockSendSlackMessage ) . toHaveBeenCalledWith (
204
+ expect . stringContaining ( '🚨 *오류가 할당되었습니다*' )
205
+ ) ;
206
+ } ) ;
207
+
208
+ it ( 'archived 액션에 대해 올바른 메시지를 생성해야 한다' , async ( ) => {
209
+ const archivedData = {
210
+ ...mockSentryData ,
211
+ action : 'archived' as const ,
212
+ data : {
213
+ ...mockSentryData . data ,
214
+ issue : {
215
+ ...mockSentryData . data . issue ,
216
+ status : 'archived' as const
217
+ }
218
+ }
219
+ } ;
220
+ mockRequest . body = archivedData ;
221
+ mockSendSlackMessage . mockResolvedValue ( ) ;
222
+
223
+ await webhookController . handleSentryWebhook (
224
+ mockRequest as Request ,
225
+ mockResponse as Response ,
226
+ nextFunction
227
+ ) ;
228
+
229
+ expect ( mockSendSlackMessage ) . toHaveBeenCalledWith (
230
+ expect . stringContaining ( '🚨 *오류가 아카이브되었습니다*' )
231
+ ) ;
232
+ expect ( mockSendSlackMessage ) . toHaveBeenCalledWith (
233
+ expect . stringContaining ( '📦 *제목:*' )
234
+ ) ;
235
+ } ) ;
236
+
182
237
it ( '알 수 없는 액션에 대해 기본 메시지를 생성해야 한다' , async ( ) => {
183
238
const unknownActionData = {
184
239
...mockSentryData ,
@@ -281,15 +336,16 @@ describe('WebhookController', () => {
281
336
282
337
describe ( 'formatSentryMessage (private method integration test)' , ( ) => {
283
338
it ( '완전한 Sentry 데이터로 올바른 형식의 메시지를 생성해야 한다' , async ( ) => {
284
- const completeData : SentryWebhookData = {
339
+ // 실제 동작에 필요한 필수 값만 사용하도록 타입 미적용
340
+ const completeData = {
285
341
action : 'created' ,
286
342
data : {
287
343
issue : {
288
344
id : 'issue-456' ,
289
345
title : 'TypeError: Cannot read property of undefined' ,
290
346
culprit : 'components/UserProfile.tsx:25' ,
291
347
status : 'unresolved' ,
292
- count : 12 ,
348
+ count : "12" ,
293
349
userCount : 8 ,
294
350
firstSeen : '2024-01-15T14:30:00.000Z' ,
295
351
permalink : 'https://velog-dashboardv2.sentry.io/issues/issue-456/' ,
0 commit comments