@@ -220,213 +220,4 @@ describe("CopilotEndpoint middleware", () => {
220220 "Error running after request middleware"
221221 ) ;
222222 } ) ;
223-
224- it ( "processes request through webhook middleware URLs" , async ( ) => {
225- const beforeURL = "https://hooks.example.com/before" ;
226- const afterURL = "https://hooks.example.com/after" ;
227- setupFetchMock ( beforeURL , afterURL ) ;
228-
229- const runtime = dummyRuntime ( {
230- beforeRequestMiddleware : beforeURL ,
231- afterRequestMiddleware : afterURL ,
232- } ) ;
233-
234- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
235- const response = await endpoint . fetch (
236- new Request ( "https://example.com/info" , {
237- headers : { foo : "bar" } ,
238- method : "GET" ,
239- } )
240- ) ;
241-
242- // Wait a bit more for async afterRequestMiddleware
243- await new Promise ( ( r ) => setTimeout ( r , 50 ) ) ;
244-
245- expect ( fetchMock ) . toHaveBeenCalledTimes ( 2 ) ;
246-
247- // Assert payload for before-hook
248- const beforeCall = fetchMock ! . mock . calls [ 0 ] ;
249- expect ( beforeCall [ 0 ] ) . toBe ( beforeURL ) ;
250- expect ( beforeCall [ 1 ] ) . toBeDefined ( ) ;
251- expect ( beforeCall [ 1 ] ! . body ) . toBeDefined ( ) ;
252- const beforePayload = JSON . parse ( beforeCall [ 1 ] ! . body as string ) ;
253- expect ( beforePayload ) . toMatchObject ( {
254- method : "GET" ,
255- path : "/info" ,
256- query : "" ,
257- headers : expect . objectContaining ( { foo : "bar" } ) ,
258- } ) ;
259- const headers = beforeCall [ 1 ] ! . headers as Record < string , string > ;
260- expect ( headers [ "X-CopilotKit-Webhook-Stage" ] ) . toBe (
261- WebhookStage . BeforeRequest
262- ) ;
263-
264- // Assert payload for after-hook
265- const afterCall = fetchMock ! . mock . calls [ 1 ] ;
266- expect ( afterCall [ 0 ] ) . toBe ( afterURL ) ;
267- expect ( afterCall [ 1 ] ) . toBeDefined ( ) ;
268- expect ( afterCall [ 1 ] ! . body ) . toBeDefined ( ) ;
269- const afterPayload = JSON . parse ( afterCall [ 1 ] ! . body as string ) ;
270- expect ( afterPayload ) . toMatchObject ( {
271- status : 200 ,
272- headers : expect . objectContaining ( {
273- "content-type" : "application/json" ,
274- } ) ,
275- body : expect . any ( String ) ,
276- } ) ;
277- const afterHeaders = afterCall [ 1 ] ! . headers as Record < string , string > ;
278- expect ( afterHeaders [ "X-CopilotKit-Webhook-Stage" ] ) . toBe (
279- WebhookStage . AfterRequest
280- ) ;
281-
282- // Response should still be successful
283- expect ( response . status ) . toBe ( 200 ) ;
284- const body = await response . json ( ) ;
285- expect ( body ) . toHaveProperty ( "version" ) ;
286- } ) ;
287-
288- it ( "applies webhook middleware request modifications" , async ( ) => {
289- const beforeURL = "https://hooks.example.com/before" ;
290- const afterURL = "https://hooks.example.com/after" ;
291- setupFetchMock ( beforeURL , afterURL ) ;
292-
293- const runtime = dummyRuntime ( {
294- beforeRequestMiddleware : beforeURL ,
295- afterRequestMiddleware : afterURL ,
296- } ) ;
297-
298- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
299-
300- // Make a POST request to info endpoint since it's simpler
301- const response = await endpoint . fetch (
302- new Request ( "https://example.com/info" , {
303- headers : { foo : "bar" } ,
304- method : "GET" ,
305- } )
306- ) ;
307-
308- // Should get a successful response
309- expect ( response . status ) . toBe ( 200 ) ;
310-
311- // Wait for async afterRequestMiddleware
312- await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
313-
314- // The webhook middleware should have been called
315- expect ( fetchMock ) . toHaveBeenCalledTimes ( 2 ) ;
316- } ) ;
317-
318- it ( "handles webhook middleware timeout" , async ( ) => {
319- const beforeURL = "https://hooks.example.com/before" ;
320- originalFetch = global . fetch ;
321-
322- // Create an AbortController to simulate timeout
323- let abortSignal : AbortSignal | undefined ;
324- fetchMock = vi
325- . fn ( )
326- . mockImplementation ( async ( _url : string , init ?: RequestInit ) => {
327- abortSignal = init ?. signal ;
328- // Wait for abort signal
329- return new Promise < Response > ( ( _resolve , reject ) => {
330- if ( abortSignal ) {
331- abortSignal . addEventListener ( "abort" , ( ) => {
332- reject ( new Error ( "Aborted" ) ) ;
333- } ) ;
334- }
335- } ) ;
336- } ) ;
337- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
338- // @ts -ignore
339- global . fetch = fetchMock as unknown as typeof fetch ;
340-
341- const runtime = dummyRuntime ( {
342- beforeRequestMiddleware : beforeURL ,
343- } ) ;
344-
345- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
346-
347- // Should return 502 on timeout
348- const response = await endpoint . fetch (
349- new Request ( "https://example.com/info" )
350- ) ;
351-
352- expect ( response . status ) . toBe ( 502 ) ;
353-
354- // Verify that the fetch was aborted due to timeout
355- expect ( abortSignal ?. aborted ) . toBe ( true ) ;
356- } ) ;
357-
358- it ( "handles webhook middleware error responses" , async ( ) => {
359- const beforeURL = "https://hooks.example.com/before" ;
360- originalFetch = global . fetch ;
361- fetchMock = vi . fn ( ) . mockImplementation ( async ( ) => {
362- return new Response ( "Bad request" , { status : 400 } ) ;
363- } ) ;
364- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
365- // @ts -ignore
366- global . fetch = fetchMock as unknown as typeof fetch ;
367-
368- const runtime = dummyRuntime ( {
369- beforeRequestMiddleware : beforeURL ,
370- } ) ;
371-
372- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
373-
374- // Should pass through error response
375- const response = await endpoint . fetch (
376- new Request ( "https://example.com/info" )
377- ) ;
378-
379- expect ( response . status ) . toBe ( 400 ) ;
380- expect ( await response . text ( ) ) . toBe ( "Bad request" ) ;
381- } ) ;
382-
383- it ( "handles webhook middleware server error" , async ( ) => {
384- const beforeURL = "https://hooks.example.com/before" ;
385- originalFetch = global . fetch ;
386- fetchMock = vi . fn ( ) . mockImplementation ( async ( ) => {
387- return new Response ( "Server error" , { status : 500 } ) ;
388- } ) ;
389- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
390- // @ts -ignore
391- global . fetch = fetchMock as unknown as typeof fetch ;
392-
393- const runtime = dummyRuntime ( {
394- beforeRequestMiddleware : beforeURL ,
395- } ) ;
396-
397- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
398-
399- // Should return 502 on server error
400- const response = await endpoint . fetch (
401- new Request ( "https://example.com/info" )
402- ) ;
403-
404- expect ( response . status ) . toBe ( 502 ) ;
405- } ) ;
406-
407- it ( "handles webhook middleware 204 response" , async ( ) => {
408- const beforeURL = "https://hooks.example.com/before" ;
409- originalFetch = global . fetch ;
410- fetchMock = vi . fn ( ) . mockImplementation ( async ( ) => {
411- return new Response ( null , { status : 204 } ) ;
412- } ) ;
413- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
414- // @ts -ignore
415- global . fetch = fetchMock as unknown as typeof fetch ;
416-
417- const runtime = dummyRuntime ( {
418- beforeRequestMiddleware : beforeURL ,
419- } ) ;
420-
421- const endpoint = createCopilotEndpoint ( { runtime, basePath : "/" } ) ;
422-
423- // Should continue with original request on 204
424- const response = await endpoint . fetch (
425- new Request ( "https://example.com/info" )
426- ) ;
427-
428- expect ( response . status ) . toBe ( 200 ) ;
429- const body = await response . json ( ) ;
430- expect ( body ) . toHaveProperty ( "version" ) ;
431- } ) ;
432223} ) ;
0 commit comments