msw icon indicating copy to clipboard operation
msw copied to clipboard

Response patching is misbehave with FormData

Open QzCurious opened this issue 4 years ago • 4 comments

Describe the bug

FormData was not sent alone with ctx.fetch(req), an empty object instead.

Environment

  • msw: 0.39.1
  • nodejs: 16.13.2
  • npm: 8.5.0
  • firefox: 97.0.1

To Reproduce

handler:

export const handlers = [
  rest.post("/post", async (req, res, ctx) => {
    console.log("msw body:", req.body);
    const proxy = await ctx.fetch(req);

    return res(
      ctx.status(proxy.status),
      ctx.body(await proxy.text())
    );
  }),
];

invoke:

const formData = new FormData();
formData.append("key", "value");
fetch("/post", { method: "POST", body: formData });

The original request has form data: image

But request by msw has no form data: image

Expected behavior

I'm expecting that ctx.fetch(req) behaves exact the same way as it without thourgh msw.

I'm not sure why this happens. Maybe fetch with content-type: multipart/form-data can't deal with plain object? Sorry, I can not reproduce a precise fetch request to confirm my guessing.

FormData is converted to an plain object (see also issue-599): https://github.com/mswjs/msw/blob/0f0827c00d185533af258da8c0bb1285ab1f9b4c/src/context/fetch.ts#L29-L34

QzCurious avatar Mar 09 '22 18:03 QzCurious

Hey, @QzCurious. Thanks for reporting this.

My hutch is that since the req (MockedRequest) instance always contains a text body, it attempts to send the text body when you perform ctx.fetch(req). This needs to be confirmed, though.

Why is the request/response body always text? So we could send it between the worker and the client threads (only text can be transmitted). It's also a natural shared denominator for variable request/response body types (text/Buffer/stream/FormData/Blob/etc.).

I'd be thankful for any help with investigating this 🙏

kettanaito avatar Mar 10 '22 17:03 kettanaito

Hi, @kettanaito. Could you give me some hint how to test/debug a library like this one? What I it to be like:

  1. Setup up msw by go through with the doc
  2. Run a debugger (topically quokkajs/wallabyjs) to step through to see what steps that msw is doing from setting itself up to produce the mock

What I'm stuck is that service worker should be invoked by browser. I have no idea how do I load and initiate msw properly for the purpose of debugging (without browser).

QzCurious avatar Mar 25 '22 06:03 QzCurious

@QzCurious, we don't have a built-in debugger as of now. This is something I'd like to add but it needs to be designed properly. I hope to get to this some time in the future.

What I'm stuck is that service worker should be invoked by browser. I have no idea how do I load and initiate msw properly for the purpose of debugging (without browser).

You still need browser, and you will be using browser to debug MSW in a browser anyway. Register the worker as you usually do. You can put debugger in the worker script and forcefully unregister the worker in "Applications > Service Workers" in your browser's DevTools. This will force the changes to the worker to take immediate effect.

The same applies to the library: it runs client-side as a part of your app, so you can go to its source and use debugger in relevant places (i.e. in src/context/fetch.ts, only its built *.js counterpart).

kettanaito avatar Mar 25 '22 12:03 kettanaito

@kettanaito, you might misunderstood what I meant. I was not going to require a MSW debugger. I was looking for a way to investigate how MSW works. And then solve this issue and make a PR, hopefully.

I had run MSW with @msw/node with wallabyjs successfully. Will try the browser way that you state.

QzCurious avatar Mar 25 '22 13:03 QzCurious

Hi @kettanaito, Congratulation for MSW v2. I thought this issue can be closed. With the new http handle I can read request.formData() without problem.

QzCurious avatar Oct 26 '23 02:10 QzCurious

@QzCurious, thank you! This issue should've been marked as the one fixed by the 2.0 pull request. Closing it now.

kettanaito avatar Oct 27 '23 10:10 kettanaito