@@ -17,7 +17,11 @@ vi.mock('@/lib/webhooks/providers/slack', () => ({
1717} ) )
1818
1919import { dispatchResolvedWebhookTarget } from '@/lib/webhooks/processor'
20- import { dispatchSlackWebhooks } from '@/lib/webhooks/slack-dispatch'
20+ import {
21+ dispatchSlackWebhooks ,
22+ getSlackDispatchFailureResponse ,
23+ getSlackDispatchResponse ,
24+ } from '@/lib/webhooks/slack-dispatch'
2125
2226describe ( 'dispatchSlackWebhooks' , ( ) => {
2327 it ( 'dispatches at most ten targets concurrently and preserves result order' , async ( ) => {
@@ -68,4 +72,43 @@ describe('dispatchSlackWebhooks', () => {
6872 Array . from ( { length : 12 } , ( _ , index ) => 200 + index )
6973 )
7074 } )
75+
76+ it ( 'returns the failure when no Slack target is acknowledged' , ( ) => {
77+ const response = getSlackDispatchResponse ( [
78+ {
79+ outcome : 'failed' ,
80+ response : new NextResponse ( null , { status : 500 } ) ,
81+ reason : 'queue-failed' ,
82+ } ,
83+ ] )
84+
85+ expect ( response . status ) . toBe ( 500 )
86+ } )
87+
88+ it ( 'acknowledges a mixed fan-out when at least one Slack target queues' , ( ) => {
89+ const response = getSlackDispatchResponse ( [
90+ {
91+ outcome : 'failed' ,
92+ response : new NextResponse ( null , { status : 500 } ) ,
93+ reason : 'queue-failed' ,
94+ } ,
95+ {
96+ outcome : 'queued' ,
97+ response : new NextResponse ( null , { status : 200 } ) ,
98+ reason : 'queued' ,
99+ } ,
100+ ] )
101+
102+ expect ( response . status ) . toBe ( 200 )
103+ } )
104+
105+ it ( 'fails fast when a failed Slack dispatch carries a successful response' , ( ) => {
106+ expect ( ( ) =>
107+ getSlackDispatchFailureResponse ( {
108+ outcome : 'failed' ,
109+ response : new NextResponse ( null , { status : 200 } ) ,
110+ reason : 'queue-failed' ,
111+ } )
112+ ) . toThrow ( 'Failed Slack dispatch returned successful HTTP status 200' )
113+ } )
71114} )
0 commit comments