1+ // @vitest -environment node
12/**
2- * @vitest -environment node
3+ * @see https://github.com/mswjs/interceptors/pull/722
34 */
5+ import { afterAll , afterEach , beforeAll , beforeEach , expect , it } from 'vitest'
6+ import path from 'node:path'
47import http from 'node:http'
5- import { tmpdir } from 'node:os' ;
6- import { afterAll , beforeAll , describe , expect , it } from 'vitest'
7- import { DeferredPromise } from '@open-draft/deferred-promise'
8+ import { promisify } from 'node:util'
89import { ClientRequestInterceptor } from '../../../../src/interceptors/ClientRequest'
910import { waitForClientRequest } from '../../../helpers'
10- import exp from 'node:constants' ;
1111
12- const interceptor = new ClientRequestInterceptor ( )
12+ // const HTTP_SOCKET_PATH = mockFs.resolve('./test.sock')
13+ const HTTP_SOCKET_PATH = path . join ( __dirname , './test-http.sock' )
14+
15+ const httpServer = http . createServer ( ( req , res ) => {
16+ res . writeHead ( 200 , req . headers )
1317
14- const socketPath = tmpdir ( ) + '/socket.sock'
15- const httpServer = new http . Server ( ( req , res ) => {
16- res . end ( 'hello world' )
18+ if ( req . method === 'POST' ) {
19+ req . pipe ( res )
20+ } else {
21+ res . end ( )
22+ }
1723} )
1824
25+ const interceptor = new ClientRequestInterceptor ( )
26+
1927beforeAll ( async ( ) => {
20- interceptor . apply ( )
21- const serverListenPromise = new DeferredPromise < void > ( )
22- httpServer . listen ( socketPath , ( ) => {
23- serverListenPromise . resolve ( )
28+ await new Promise < void > ( ( resolve ) => {
29+ httpServer . listen ( HTTP_SOCKET_PATH , resolve )
2430 } )
25- await serverListenPromise
31+
32+ interceptor . apply ( )
33+ } )
34+
35+ afterEach ( ( ) => {
36+ interceptor . removeAllListeners ( )
2637} )
2738
2839afterAll ( async ( ) => {
2940 interceptor . dispose ( )
30- const serverClosePromise = new DeferredPromise < void > ( )
31- httpServer . close ( ( error ) => {
32- if ( error ) {
33- serverClosePromise . reject ( error )
34- }
35- serverClosePromise . resolve ( )
41+ await promisify ( httpServer . close . bind ( httpServer ) ) ( )
42+ } )
43+
44+ it ( 'supports passthrough HTTP GET requests over a unix socket' , async ( ) => {
45+ const request = http . get ( {
46+ socketPath : HTTP_SOCKET_PATH ,
47+ path : '/irrelevant' ,
48+ headers : {
49+ 'X-Custom-Header' : 'custom-value' ,
50+ } ,
3651 } )
37- await serverClosePromise
52+ const { res } = await waitForClientRequest ( request )
53+
54+ expect . soft ( res . statusCode ) . toBe ( 200 )
55+ expect . soft ( res . headers [ 'x-custom-header' ] ) . toBe ( 'custom-value' )
3856} )
3957
40- describe ( 'Unix socket' , ( ) => {
41- it ( 'dispatches a GET request to a Unix socket' , async ( ) => {
42- const request = http . get ( {
43- socketPath,
44- path : '/test-get' ,
45- } )
58+ it ( 'supports passthrough HTTP POST requests over a unix socket' , async ( ) => {
59+ const request = http . request ( {
60+ method : 'POST' ,
61+ socketPath : HTTP_SOCKET_PATH ,
62+ path : '/irrelevant' ,
63+ headers : {
64+ 'Content-Type' : 'application/json' ,
65+ 'Content-Length' : 11 ,
66+ } ,
67+ } )
68+ request . end ( 'hello world' )
4669
47- const { text } = await waitForClientRequest ( request )
70+ const { res , text } = await waitForClientRequest ( request )
4871
49- expect ( await text ( ) ) . toBe ( 'hello world' )
72+ expect . soft ( res . statusCode ) . toBe ( 200 )
73+ expect . soft ( res . headers ) . toMatchObject ( {
74+ 'content-type' : 'application/json' ,
75+ 'content-length' : '11' ,
5076 } )
77+ await expect . soft ( text ( ) ) . resolves . toBe ( 'hello world' )
78+ } )
5179
52- it ( 'intercepts a GET request to a Unix socket' , async ( ) => {
53- const requestListenerPromise = new DeferredPromise < string > ( )
54- interceptor . on ( 'request' , ( { controller, request } ) => {
55- requestListenerPromise . resolve ( request . url )
56- controller . respondWith ( new Response ( 'hello world' , { status : 200 } ) )
57- } )
80+ it ( 'supports passthrough HTTP GET requests to a non-existing unix socket' , async ( ) => {
81+ const request = http . get ( {
82+ socketPath : path . join ( 'non-existing.sock' ) ,
83+ path : '/irrelevant' ,
84+ } )
5885
59- const request = http . get ( {
60- socketPath,
61- path : '/test-get' ,
86+ await expect ( waitForClientRequest ( request ) ) . rejects . toThrow (
87+ expect . objectContaining ( {
88+ code : 'ENOENT' ,
89+ message : 'connect ENOENT non-existing.sock' ,
6290 } )
91+ )
92+ } )
93+
94+ it ( 'mocks a response to HTTP GET requests over a unix socket' , async ( ) => {
95+ interceptor . on ( 'request' , ( { request, controller } ) => {
96+ controller . respondWith ( new Response ( 'hello world' , request ) )
97+ } )
98+
99+ const request = http . get ( {
100+ socketPath : HTTP_SOCKET_PATH ,
101+ path : '/irrelevant' ,
102+ headers : {
103+ 'X-Custom-Header' : 'custom-value' ,
104+ } ,
105+ } )
106+ const { res, text } = await waitForClientRequest ( request )
107+
108+ expect . soft ( res . statusCode ) . toBe ( 200 )
109+ expect . soft ( res . headers [ 'x-custom-header' ] ) . toBe ( 'custom-value' )
110+ await expect . soft ( text ( ) ) . resolves . toBe ( 'hello world' )
111+ } )
63112
64- const { text } = await waitForClientRequest ( request )
113+ it ( 'mocks a response to HTTP POST requests over a unix socket' , async ( ) => {
114+ interceptor . on ( 'request' , ( { request, controller } ) => {
115+ controller . respondWith (
116+ new Response ( request . body , {
117+ headers : request . headers ,
118+ } )
119+ )
120+ } )
65121
66- expect ( await text ( ) ) . toBe ( 'hello world' )
67- await expect ( requestListenerPromise ) . resolves . toStrictEqual ( 'http://localhost/test-get' )
122+ const request = http . request ( {
123+ method : 'POST' ,
124+ socketPath : HTTP_SOCKET_PATH ,
125+ path : '/irrelevant' ,
126+ headers : {
127+ 'X-Custom-Header' : 'custom-value' ,
128+ } ,
68129 } )
69- } )
130+ request . end ( 'request-payload' )
131+
132+ const { res, text } = await waitForClientRequest ( request )
133+
134+ expect . soft ( res . statusCode ) . toBe ( 200 )
135+ expect . soft ( res . headers [ 'x-custom-header' ] ) . toBe ( 'custom-value' )
136+ await expect . soft ( text ( ) ) . resolves . toBe ( 'request-payload' )
137+ } )
0 commit comments