question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ctx.fetch() not keeping original headers

See original GitHub issue

Describe the bug

When mocking a REST API using rest.get i have a request containing headers, specifically “Authorization” header, and when i call ctx.fetch() with this request, in order to get the original response, i have an unauthorized response. This is due to the fact that my “Authorization” header is missing.

After taking a look at src/context/fetch.ts, specifically the augmentRequestInit() function, it seems that the type of my request headers is Headers, and not string[][] nor Record<string, string> (see HeadersInittype). I think that the spread operator is not working for the type Headers, therefore the headers are not kept :

const augmentRequestInit = (requestInit: RequestInit): RequestInit => {
  return {
    ...requestInit,
    headers: {
      ...requestInit.headers,
      'x-msw-bypass': 'true',
    },
  }
}

Environment

  • msw: 0.15.5

  • nodejs: 12.16.1

  • npm: 6.13.4

  • browser version: Chrome 81.0.4044.129

To Reproduce

Steps to reproduce the behavior:

  1. make a request with “Authorization” header in an authent context
  2. call ctx.fetch() function with the original request
  3. you will see an “401 Unauthorized (from ServiceWorker)” request in your network

My mock :

rest.get('/path/to/my/resource', async (req, res, ctx) => {
        const mockedResponse = [
            "Val 1",
            "Val 2",
            "Val 3"
        ];

        const originalResponse = await ctx.fetch(req)

        return res(
            ctx.status(200),
            ctx.json(originalResponse && originalResponse.length ? originalResponse : mockedResponse)
        );
    })

Expected behavior

Headers are kept.

Temporary Solution

I implemented my own fetch() duplicating the existing one, and i change the implementation of the augmentRequestInit() function. My working version :

const augmentRequestInit = (requestInit: RequestInit): RequestInit => {
    const headersCopy: Record<string, string> = {}
    if (requestInit.headers instanceof Headers) {
        requestInit.headers.forEach((value: string, name: string) => {
            headersCopy[name] = value
        });
    }
    
    // TODO handle the other types : string[][] and Record<string, string>

    return {
        ...requestInit,
        headers: {
            ...headersCopy,
            'x-msw-bypass': 'true',
        },
    }
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
juhanakristiancommented, May 9, 2020

Yeah, that sounds great!

0reactions
kettanaitocommented, May 11, 2020

Big thanks to @juhanakristian for providing a fix on this.

The fix is published in 0.15.8. Could you please update and let me know that it functions as expected? The workaround you’ve introduced should no longer be needed, original request headers must be proxied via ctx.fetch(). Thanks.

Read more comments on GitHub >

github_iconTop Results From Across the Web

fetch() does not send headers?
I have tried to create Request and specifically add headers using req.headers.append() . The headers still wouldn't send. javascript · http ...
Read more >
Stop mocking fetch
If it's not much more difficult then sure! But we don't want to actually make fetch requests right? So let's mock out window.fetch...
Read more >
HTTP | Node.js v19.3.0 Documentation
It is good practice, to destroy() an Agent instance when it is no longer in use, ... Not to be confused with the...
Read more >
Data Fetching: getServerSideProps
Learn how to fetch data on each request with Next.js. ... Imports used will not be bundled for the client-side. This means you...
Read more >
Context
The Ctx struct represents the Context which hold the HTTP request and response. It has methods for the request query string, parameters, body,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found