mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.97k stars 519 forks source link

Headers created before `server.listen()` are not being considered after changed with `headers.set()` or `headers.append()` #2297

Closed diego-aquino closed 1 week ago

diego-aquino commented 1 month ago

Prerequisites

Environment check

Node.js version

v20.17.0

Reproduction repository

https://github.com/diego-aquino/msw-headers-init-repro-with-vitest

Reproduction steps

  1. Clone the reproduction repository
  2. npm install
  3. npm run test

Current behavior

The README.md of the reproduction repository contains a more detailed explanation. Here's a summary:

I created two identical test suites, except for the imported MSW version:

Before starting the MSW server, each suite creates a Headers instance with initial values, appends a new header and checks if the initial values are preserved and the instance contains the correct values.

After starting the server with server.listen(), the suites append yet another header to the instance and re-run the checks. With msw@2.4.3, the existing values are preserved and the new header is appended. However, the current headers are lost with msw@2.4.9 when used in a Request or fetch call. The only kept header is the one appended after starting the server, as if the instance was empty before.

The problem does not appear to occur when using the headers directly, because only the last expect reading the headers from a Request fails.

Expected behavior

For headers created before server.listen(), Request and fetch should consider their previous values after changed with set or append. This was the behavior with msw@2.4.3 and appears to have changed in msw@2.4.4 and later.

Let me know if there is anything unclear I could clarify!

jeanpaze commented 1 month ago

I can confirm, this is also happening to me.

Previously this test was working:

expect(response.headers.get("Content-Type")).toBe("text/html");

But started to fail with version 2.4.4 and above:

- Expected: 
"text/html"

+ Received: 
null
plavski commented 1 month ago

Any potential movement here? This is holding off our upgrade as we have a lot of tests designed this way.

cythrawll commented 1 month ago

I just got bit by this bug. couldn't figure why my remix server was serving everything as plain/text for a few hours now when MSW mocks were turned on, only to find out my express server stopped sending Content-Type headers at all.

worked around this bug by loading my mock setupServer script with npm command instead of inline in my express server so now doing something like in my package.json:

scripts: {
  dev: 'tsx -r ./mocks/index.ts server.ts'
}
kettanaito commented 1 week ago

Update

2269 and #2278 have been fixed and look suspiciously similar to what you are describing. I recommend updating to the latest of msw to verify.

@diego-aquino, I confirm that your reproduction repo has the tests passing on msw@latest:

 ✓ tests/failing-on-2.4.9.test.ts (1)
   ✓ preserves init values in headers created before the server was started

Just make sure to remove the pervious msw version because it looks like npm is resolving @mswjs/interceptors from the 2.4.3, which is an extremely old version that doesn't contain the fix.