From 00da9cad4249b61732ee375d9dbefeb76028cc2b Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Fri, 6 Dec 2024 13:57:14 +0100 Subject: [PATCH] fix(setupServer): reapply interception after calling `server.listen()` after `server.close()` (#2383) --- src/node/SetupServerCommonApi.ts | 5 +- .../2370-listen-after-close.test.ts | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/node/regressions/2370-listen-after-close.test.ts diff --git a/src/node/SetupServerCommonApi.ts b/src/node/SetupServerCommonApi.ts index 0f054749a..0c6050f4c 100644 --- a/src/node/SetupServerCommonApi.ts +++ b/src/node/SetupServerCommonApi.ts @@ -48,8 +48,6 @@ export class SetupServerCommonApi }) this.resolvedOptions = {} as RequiredDeep - - this.init() } /** @@ -141,7 +139,10 @@ export class SetupServerCommonApi ) as RequiredDeep // Apply the interceptor when starting the server. + // Attach the event listeners to the interceptor here + // so they get re-attached whenever `.listen()` is called. this.interceptor.apply() + this.init() this.subscriptions.push(() => this.interceptor.dispose()) // Apply the WebSocket interception. diff --git a/test/node/regressions/2370-listen-after-close.test.ts b/test/node/regressions/2370-listen-after-close.test.ts new file mode 100644 index 000000000..0dcad912d --- /dev/null +++ b/test/node/regressions/2370-listen-after-close.test.ts @@ -0,0 +1,61 @@ +/** + * @see https://github.com/mswjs/msw/issues/2370 + */ +// @vitest-environment node +import { http, HttpResponse } from 'msw' +import { setupServer } from 'msw/node' +import { HttpServer } from '@open-draft/test-server/http' + +const server = setupServer() + +const httpServer = new HttpServer((app) => { + app.get('/resource', (_req, res) => { + res.send('original') + }) +}) + +beforeAll(async () => { + server.listen() + await httpServer.listen() +}) + +afterEach(() => { + server.resetHandlers() +}) + +afterAll(async () => { + server.close() + await httpServer.close() +}) + +it('intercepts a request once `server.listen()` is called after `server.close()`', async () => { + const requestUrl = httpServer.http.url('/resource') + + server.use( + http.get(requestUrl, () => { + return HttpResponse.text('mocked') + }), + ) + + // Must respond with a mocked response while MSW is active. + { + const response = await fetch(requestUrl) + await expect(response.text()).resolves.toBe('mocked') + } + + server.close() + + // Must respond with the original response once MSW is closed. + { + const response = await fetch(requestUrl) + await expect(response.text()).resolves.toBe('original') + } + + server.listen() + + // Must respond with the mocked response once MSW is active again. + { + const response = await fetch(requestUrl) + await expect(response.text()).resolves.toBe('mocked') + } +})