mswjs / msw

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

Using the wildcard token to try to match random ports doesn't work if preceded by a colon #2204

Open silvenon opened 4 months ago

silvenon commented 4 months ago

Prerequisites

Environment check

Node.js version

v20.15.1

Reproduction repository

https://github.com/silvenon/repro/tree/msw-wildcard-port

Reproduction steps

The reproduction branch contains a project with two test, both of them are passing, but the the first one is set to fail using test.fails.

In a situation where you have to match an unknown port, atttempt to match it in MSW with something like this:

import { setupServer } from "msw/node";
import { http, HttpResponse } from "msw";

const server = setupServer(
  http.get("http://localhost:*", () => HttpResponse.text("Hello world!")),
);

server.listen();

Then attempt to fetch something from localhost endpoints with random ports:

const res = await fetch("http://localhost:3000");
const result = await res.text();

Current behavior

Currently the library for matching the endpoint, path-to-regexp, seems to detect this as the parameter:

{"name":"TypeError","message":"Missing parameter name at 17","stack":"TypeError: Missing parameter name at 17
    at lexer (/Users/silvenon/Code/repro/node_modules/path-to-regexp/src/index.ts:72:24)
    at parse (/Users/silvenon/Code/repro/node_modules/path-to-regexp/src/index.ts:141:18)
    at stringToRegexp (/Users/silvenon/Code/repro/node_modules/path-to-regexp/src/index.ts:493:25)
    at pathToRegexp (/Users/silvenon/Code/repro/node_modules/path-to-regexp/src/index.ts:620:10)
    at match (/Users/silvenon/Code/repro/node_modules/path-to-regexp/src/index.ts:379:14)
    at matchRequestUrl (file:///Users/silvenon/Code/repro/node_modules/msw/src/core/utils/matching/matchRequestUrl.ts:66:18)
    at HttpHandler.parse (file:///Users/silvenon/Code/repro/node_modules/msw/src/core/handlers/HttpHandler.ts:114:19)
    at HttpHandler.run (file:///Users/silvenon/Code/repro/node_modules/msw/src/core/handlers/RequestHandler.ts:239:37)
    at executeHandlers (file:///Users/silvenon/Code/repro/node_modules/msw/src/core/utils/executeHandlers.ts:36:28)
    at file:///Users/silvenon/Code/repro/node_modules/msw/src/core/utils/handleRequest.ts:64:12"}

If I remove the colon it acts as expected.

Expected behavior

Regardless of whether the wildcard is used with or without colon it should achieve a similar result:

I.e. for this use case it should work. Except that in the latter pattern I would expect the hostname to not only match localhost, but also localhostable etc., so I consider it to be a workaround rather than a solution.

kettanaito commented 4 months ago

Thanks for raising this, @silvenon.

The issue occurs because of the way MSW coerces the * into a regular expression. We are using path-to-regexp for path matching, and the version we depend on doesn't understand wildcards.

Some later versions do but they ship their own breaking changes, some of which are still incompatible with the path matching in MSW.

In attempts to resolve this, I've tried the standard URLPattern API (#2209). It does resolve your issue! But it has one new of its own (tracked in the PR). I will wait for the folks behind the spec to comment before I continue with this.