@@ -76,7 +76,7 @@ describe('WebhookController', () => {
7676 ) ;
7777
7878 expect ( mockSendSlackMessage ) . toHaveBeenCalledWith (
79- expect . stringContaining ( '🚨 *새로운 오류가 발생했습니다 *' )
79+ expect . stringContaining ( '🚨 *새로운 오류가 발생하였습니다 *' )
8080 ) ;
8181 expect ( mockSendSlackMessage ) . toHaveBeenCalledWith (
8282 expect . stringContaining ( '🔴 *제목:* 테스트 오류입니다' )
@@ -135,6 +135,133 @@ describe('WebhookController', () => {
135135 expect ( nextFunction ) . toHaveBeenCalledWith ( slackError ) ;
136136 expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
137137 } ) ;
138+
139+ // Invalid Body 케이스 테스트들
140+ it ( 'action이 created가 아닌 경우 400 에러를 반환해야 한다' , async ( ) => {
141+ mockRequest . body = { action : 'resolved' } ;
142+
143+ await webhookController . handleSentryWebhook (
144+ mockRequest as Request ,
145+ mockResponse as Response ,
146+ nextFunction
147+ ) ;
148+
149+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 400 ) ;
150+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( {
151+ success : true ,
152+ message : 'Sentry 웹훅 처리에 실패했습니다' ,
153+ data : { } ,
154+ error : null
155+ } ) ;
156+ expect ( nextFunction ) . not . toHaveBeenCalled ( ) ;
157+ } ) ;
158+
159+ it ( '빈 body인 경우 400 에러를 반환해야 한다' , async ( ) => {
160+ mockRequest . body = { } ;
161+
162+ await webhookController . handleSentryWebhook (
163+ mockRequest as Request ,
164+ mockResponse as Response ,
165+ nextFunction
166+ ) ;
167+
168+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 400 ) ;
169+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( {
170+ success : true ,
171+ message : 'Sentry 웹훅 처리에 실패했습니다' ,
172+ data : { } ,
173+ error : null
174+ } ) ;
175+ } ) ;
176+
177+ it ( 'action이 없는 경우 400 에러를 반환해야 한다' , async ( ) => {
178+ mockRequest . body = { data : { issue : { } } } ;
179+
180+ await webhookController . handleSentryWebhook (
181+ mockRequest as Request ,
182+ mockResponse as Response ,
183+ nextFunction
184+ ) ;
185+
186+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 400 ) ;
187+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( {
188+ success : true ,
189+ message : 'Sentry 웹훅 처리에 실패했습니다' ,
190+ data : { } ,
191+ error : null
192+ } ) ;
193+ } ) ;
194+
195+ it ( '전혀 다른 형태의 객체인 경우 400 에러를 반환해야 한다' , async ( ) => {
196+ mockRequest . body = {
197+ username : 'test' ,
198+ password : '123456' ,
199+ email : 'test@example.com'
200+ } ;
201+
202+ await webhookController . handleSentryWebhook (
203+ mockRequest as Request ,
204+ mockResponse as Response ,
205+ nextFunction
206+ ) ;
207+
208+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 400 ) ;
209+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( {
210+ success : true ,
211+ message : 'Sentry 웹훅 처리에 실패했습니다' ,
212+ data : { } ,
213+ error : null
214+ } ) ;
215+ } ) ;
216+
217+ it ( 'action은 created이지만 필수 필드가 없는 경우 에러를 전달해야 한다' , async ( ) => {
218+ mockRequest . body = {
219+ action : 'created' ,
220+ data : {
221+ issue : {
222+ // 필수 필드들이 누락됨
223+ }
224+ }
225+ } ;
226+
227+ await webhookController . handleSentryWebhook (
228+ mockRequest as Request ,
229+ mockResponse as Response ,
230+ nextFunction
231+ ) ;
232+
233+ expect ( nextFunction ) . toHaveBeenCalledWith (
234+ expect . objectContaining ( {
235+ message : 'Sentry 웹훅 데이터가 올바르지 않습니다'
236+ } )
237+ ) ;
238+ expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
239+ } ) ;
240+
241+ it ( 'action은 created이지만 data가 없는 경우 에러를 전달해야 한다' , async ( ) => {
242+ mockRequest . body = { action : 'created' } ;
243+
244+ await webhookController . handleSentryWebhook (
245+ mockRequest as Request ,
246+ mockResponse as Response ,
247+ nextFunction
248+ ) ;
249+
250+ expect ( nextFunction ) . toHaveBeenCalled ( ) ;
251+ expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
252+ } ) ;
253+
254+ it ( '잘못된 타입의 body인 경우 400 에러를 반환해야 한다' , async ( ) => {
255+ mockRequest . body = 'invalid string body' ;
256+
257+ await webhookController . handleSentryWebhook (
258+ mockRequest as Request ,
259+ mockResponse as Response ,
260+ nextFunction
261+ ) ;
262+
263+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 400 ) ;
264+ } ) ;
138265 } ) ;
139266
140267 describe ( 'formatSentryMessage (private method integration test)' , ( ) => {
@@ -170,7 +297,7 @@ describe('WebhookController', () => {
170297 nextFunction
171298 ) ;
172299
173- const expectedMessage = `🚨 *새로운 오류가 발생했습니다 *
300+ const expectedMessage = `🚨 *새로운 오류가 발생하였습니다 *
174301
175302🔴 *제목:* TypeError: Cannot read property of undefined
176303
0 commit comments