Skip to content

Commit

Permalink
Added custom fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-sachs committed Sep 29, 2023
1 parent 7817f5b commit 9c384c0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 24 deletions.
29 changes: 9 additions & 20 deletions packages/connect-msw/src/create-worker-handlers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { MethodIdempotency } from "@bufbuild/protobuf";
import type {
CallOptions,
ConnectRouter,
HandlerContext,
} from "@connectrpc/connect";
import type { ConnectRouter, HandlerContext } from "@connectrpc/connect";
import type { UniversalHandler } from "@connectrpc/connect/protocol";
import { http, HttpResponse, passthrough as mswPassthrough } from "msw";
import { http, HttpResponse, passthrough as mswPassthrough, bypass } from "msw";
import type { RequestHandler, ResponseResolver } from "msw";

const passthroughHeader = "x-passthrough";
Expand All @@ -15,20 +11,13 @@ export function passthrough(ctx: HandlerContext) {
return {};
}

export function createBypassOptions(callOptions: CallOptions): CallOptions {
return {
...callOptions,
headers: {
// We could make this more consistent with the exposed bypass() function provided by msw
// IFF we could specify interceptors on a request by request basis. At least in theory, bypass()
// works on a standard Request object so we'd need a converter from the interceptor UnaryRequest/StreamRequest
// to a standard request to pass it to bypass() and out again.
// Otherwise, we just need to make sure this keeps in sync with https://github.com/mswjs/msw/blob/8855956f561ad4afd4ce7ae6500ca706757bb5a9/src/core/bypass.ts
"x-msw-intention": "bypass",
...callOptions.headers,
},
};
}
/**
* Creates a custom fetch that will bypass MSW. This can be passed to
* as custom transport in order to to explicitly bypass MSW.
*/
export const bypassFetch: typeof globalThis.fetch = (input, init) => {
return fetch(bypass(input, init));
};

function createResponseResolver(handler: UniversalHandler): ResponseResolver {
return async ({ request }) => {
Expand Down
19 changes: 15 additions & 4 deletions packages/connect-msw/src/service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
} from "@connectrpc/connect-web";
import { Code, ConnectError, createPromiseClient } from "@connectrpc/connect";
import type { ServiceImpl } from "@connectrpc/connect";
import { createBypassOptions, passthrough } from "./create-worker-handlers.js";
import { bypassFetch, passthrough } from "./create-worker-handlers.js";

type MockConnectTransportOptions = Omit<ConnectTransportOptions, "baseUrl">;
type ConnectTestDef = {
Expand Down Expand Up @@ -86,6 +86,7 @@ function createElizaMock({
...transportOptions,
})
);

server.listen({ onUnhandledRequest: "error" });
return {
dispose: () => {
Expand Down Expand Up @@ -217,16 +218,26 @@ it("handles bypassing the mock", async () => {
},
},
});
const bypassClient = createPromiseClient(
ElizaService,
createConnectTransport({
baseUrl: "https://example.com/api",
fetch: bypassFetch,
})
);
try {
// Expect this to fail since the mock is bypassed. And will hit the real transport (and fail due to timeout)
await expectAsync(
client.say(
bypassClient.say(
{ sentence: "Bypassing msw mock" },
createBypassOptions({
{
timeoutMs: 10,
})
}
)
).toBeRejectedWithError(ConnectError, /\[deadline_exceeded\]/);
// This call will succeed since it uses the mock.
const response = await client.say({ sentence: "Hello" });
expect(response.sentence).toBe("Faked response");
} finally {
dispose();
}
Expand Down

0 comments on commit 9c384c0

Please sign in to comment.