fix(core-testing): handle batched paths + transformed errors in mock tRPC

httpBatchLink joins same-tick calls into one request whose path is a
comma-separated list of procedure paths; the stub matched the joined
string against a single mock key, so any batched pair failed with 'No
mock for a.one,a.two'. It now answers one element per procedure, in
order. Error bodies are also superjson-serialized — raw error JSON made
the client throw 'Unable to transform response' instead of surfacing
the intended error. Regression tests added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 16:32:03 +02:00
parent 8476712620
commit 0234e18425
2 changed files with 65 additions and 6 deletions

View File

@@ -10,12 +10,27 @@ export function createMockTrpcClient<TRouter extends AnyTRPCRouter>(
) {
const fetchStub: typeof fetch = async (input) => {
const url = typeof input === "string" ? input : (input as Request).url;
const path = new URL(url, "http://mock").pathname.replace(/^\/api\/trpc\//, "");
const result = mocks[path];
if (result === undefined) {
return new Response(JSON.stringify([{ error: { code: -32603, message: `No mock for ${path}` } }]), { status: 200 });
}
return new Response(JSON.stringify([{ result: { data: superjson.serialize(result) } }]), { status: 200 });
const path = new URL(url, "http://mock").pathname.replace(
/^\/api\/trpc\//,
"",
);
// httpBatchLink joins same-tick calls into one request whose path is the
// comma-separated list of procedure paths; respond with one element per
// call, in order.
const paths = path.split(",");
const body = paths.map((p) =>
Object.hasOwn(mocks, p)
? { result: { data: superjson.serialize(mocks[p]) } }
: {
// Error payloads pass through the transformer too — serialize
// them or the client throws "Unable to transform response".
error: superjson.serialize({
code: -32603,
message: `No mock for ${p}`,
}),
},
);
return new Response(JSON.stringify(body), { status: 200 });
};
// httpBatchLink<TRouter> requires a conditional TransformerOptions<TRouter> that