Skip to content

Commit a5e233d

Browse files
authored
Add requestContext to staticHandler query/queryRoute (#9696)
1 parent 5dba8ed commit a5e233d

File tree

4 files changed

+192
-53
lines changed

4 files changed

+192
-53
lines changed

.changeset/afraid-snakes-cough.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@remix-run/router": patch
3+
---
4+
5+
Add `requestContext` support to static handler `query`/`queryRoute`
6+
7+
- Note that the unstable API of `queryRoute(path, routeId)` has been changed to `queryRoute(path, { routeId, requestContext })`

packages/router/__tests__/router-test.ts

Lines changed: 132 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10932,6 +10932,42 @@ describe("a router", () => {
1093210932
expect(childLoaderRequest.url).toBe("http://localhost/child");
1093310933
});
1093410934

10935+
it("should support a requestContext passed to loaders and actions", async () => {
10936+
let requestContext = { sessionId: "12345" };
10937+
let rootStub = jest.fn(() => "ROOT");
10938+
let childStub = jest.fn(() => "CHILD");
10939+
let actionStub = jest.fn(() => "CHILD ACTION");
10940+
let arg = (s) => s.mock.calls[0][0];
10941+
let { query } = createStaticHandler([
10942+
{
10943+
id: "root",
10944+
path: "/",
10945+
loader: rootStub,
10946+
children: [
10947+
{
10948+
id: "child",
10949+
path: "child",
10950+
action: actionStub,
10951+
loader: childStub,
10952+
},
10953+
],
10954+
},
10955+
]);
10956+
10957+
await query(createRequest("/child"), { requestContext });
10958+
expect(arg(rootStub).context.sessionId).toBe("12345");
10959+
expect(arg(childStub).context.sessionId).toBe("12345");
10960+
10961+
actionStub.mockClear();
10962+
rootStub.mockClear();
10963+
childStub.mockClear();
10964+
10965+
await query(createSubmitRequest("/child"), { requestContext });
10966+
expect(arg(actionStub).context.sessionId).toBe("12345");
10967+
expect(arg(rootStub).context.sessionId).toBe("12345");
10968+
expect(arg(childStub).context.sessionId).toBe("12345");
10969+
});
10970+
1093510971
describe("statusCode", () => {
1093610972
it("should expose a 200 status code by default", async () => {
1093710973
let { query } = createStaticHandler([
@@ -11254,7 +11290,7 @@ describe("a router", () => {
1125411290
isError ? Promise.reject(data) : Promise.resolve(data),
1125511291
},
1125611292
]);
11257-
return handler.queryRoute(req, routeId);
11293+
return handler.queryRoute(req, { routeId });
1125811294
}
1125911295

1126011296
return {
@@ -11307,7 +11343,9 @@ describe("a router", () => {
1130711343
data = await queryRoute(createRequest("/parent?index"));
1130811344
expect(data).toBe("PARENT INDEX LOADER");
1130911345

11310-
data = await queryRoute(createRequest("/parent/child"), "child");
11346+
data = await queryRoute(createRequest("/parent/child"), {
11347+
routeId: "child",
11348+
});
1131111349
expect(data).toBe("CHILD LOADER");
1131211350
});
1131311351

@@ -11324,19 +11362,27 @@ describe("a router", () => {
1132411362
let data;
1132511363

1132611364
// Layout route
11327-
data = await queryRoute(createRequest("/parent"), "parent");
11365+
data = await queryRoute(createRequest("/parent"), {
11366+
routeId: "parent",
11367+
});
1132811368
expect(data).toBe("PARENT LOADER");
1132911369

1133011370
// Index route
11331-
data = await queryRoute(createRequest("/parent"), "parentIndex");
11371+
data = await queryRoute(createRequest("/parent"), {
11372+
routeId: "parentIndex",
11373+
});
1133211374
expect(data).toBe("PARENT INDEX LOADER");
1133311375

1133411376
// Parent in nested route
11335-
data = await queryRoute(createRequest("/parent/child"), "parent");
11377+
data = await queryRoute(createRequest("/parent/child"), {
11378+
routeId: "parent",
11379+
});
1133611380
expect(data).toBe("PARENT LOADER");
1133711381

1133811382
// Child in nested route
11339-
data = await queryRoute(createRequest("/parent/child"), "child");
11383+
data = await queryRoute(createRequest("/parent/child"), {
11384+
routeId: "child",
11385+
});
1134011386
expect(data).toBe("CHILD LOADER");
1134111387

1134211388
// Non-undefined falsey values should count
@@ -11464,19 +11510,27 @@ describe("a router", () => {
1146411510
let data;
1146511511

1146611512
// Layout route
11467-
data = await queryRoute(createRequest("/base/parent"), "parent");
11513+
data = await queryRoute(createRequest("/base/parent"), {
11514+
routeId: "parent",
11515+
});
1146811516
expect(data).toBe("PARENT LOADER");
1146911517

1147011518
// Index route
11471-
data = await queryRoute(createRequest("/base/parent"), "parentIndex");
11519+
data = await queryRoute(createRequest("/base/parent"), {
11520+
routeId: "parentIndex",
11521+
});
1147211522
expect(data).toBe("PARENT INDEX LOADER");
1147311523

1147411524
// Parent in nested route
11475-
data = await queryRoute(createRequest("/base/parent/child"), "parent");
11525+
data = await queryRoute(createRequest("/base/parent/child"), {
11526+
routeId: "parent",
11527+
});
1147611528
expect(data).toBe("PARENT LOADER");
1147711529

1147811530
// Child in nested route
11479-
data = await queryRoute(createRequest("/base/parent/child"), "child");
11531+
data = await queryRoute(createRequest("/base/parent/child"), {
11532+
routeId: "child",
11533+
});
1148011534
expect(data).toBe("CHILD LOADER");
1148111535

1148211536
// Non-undefined falsey values should count
@@ -11494,19 +11548,27 @@ describe("a router", () => {
1149411548
let data;
1149511549

1149611550
// Layout route
11497-
data = await queryRoute(createSubmitRequest("/parent"), "parent");
11551+
data = await queryRoute(createSubmitRequest("/parent"), {
11552+
routeId: "parent",
11553+
});
1149811554
expect(data).toBe("PARENT ACTION");
1149911555

1150011556
// Index route
11501-
data = await queryRoute(createSubmitRequest("/parent"), "parentIndex");
11557+
data = await queryRoute(createSubmitRequest("/parent"), {
11558+
routeId: "parentIndex",
11559+
});
1150211560
expect(data).toBe("PARENT INDEX ACTION");
1150311561

1150411562
// Parent in nested route
11505-
data = await queryRoute(createSubmitRequest("/parent/child"), "parent");
11563+
data = await queryRoute(createSubmitRequest("/parent/child"), {
11564+
routeId: "parent",
11565+
});
1150611566
expect(data).toBe("PARENT ACTION");
1150711567

1150811568
// Child in nested route
11509-
data = await queryRoute(createSubmitRequest("/parent/child"), "child");
11569+
data = await queryRoute(createSubmitRequest("/parent/child"), {
11570+
routeId: "child",
11571+
});
1151011572
expect(data).toBe("CHILD ACTION");
1151111573

1151211574
// Non-undefined falsey values should count
@@ -11525,19 +11587,19 @@ describe("a router", () => {
1152511587

1152611588
data = await queryRoute(
1152711589
createSubmitRequest("/parent", { method: "PUT" }),
11528-
"parent"
11590+
{ routeId: "parent" }
1152911591
);
1153011592
expect(data).toBe("PARENT ACTION");
1153111593

1153211594
data = await queryRoute(
1153311595
createSubmitRequest("/parent", { method: "PATCH" }),
11534-
"parent"
11596+
{ routeId: "parent" }
1153511597
);
1153611598
expect(data).toBe("PARENT ACTION");
1153711599

1153811600
data = await queryRoute(
1153911601
createSubmitRequest("/parent", { method: "DELETE" }),
11540-
"parent"
11602+
{ routeId: "parent" }
1154111603
);
1154211604
expect(data).toBe("PARENT ACTION");
1154311605
});
@@ -11697,10 +11759,9 @@ describe("a router", () => {
1169711759
],
1169811760
},
1169911761
]);
11700-
let response = await queryRoute(
11701-
createRequest("/parent/child"),
11702-
"child"
11703-
);
11762+
let response = await queryRoute(createRequest("/parent/child"), {
11763+
routeId: "child",
11764+
});
1170411765
expect(response instanceof Response).toBe(true);
1170511766
expect((response as Response).status).toBe(302);
1170611767
expect((response as Response).headers.get("Location")).toBe("/parent");
@@ -11724,10 +11785,9 @@ describe("a router", () => {
1172411785
],
1172511786
},
1172611787
]);
11727-
let response = await queryRoute(
11728-
createSubmitRequest("/parent/child"),
11729-
"child"
11730-
);
11788+
let response = await queryRoute(createSubmitRequest("/parent/child"), {
11789+
routeId: "child",
11790+
});
1173111791
expect(response instanceof Response).toBe(true);
1173211792
expect((response as Response).status).toBe(302);
1173311793
expect((response as Response).headers.get("Location")).toBe("/parent");
@@ -11749,7 +11809,9 @@ describe("a router", () => {
1174911809
loader: () => redirect(url),
1175011810
},
1175111811
]);
11752-
let response = await handler.queryRoute(createRequest("/"), "root");
11812+
let response = await handler.queryRoute(createRequest("/"), {
11813+
routeId: "root",
11814+
});
1175311815
expect(response instanceof Response).toBe(true);
1175411816
expect((response as Response).status).toBe(302);
1175511817
expect((response as Response).headers.get("Location")).toBe(url);
@@ -11766,7 +11828,7 @@ describe("a router", () => {
1176611828
},
1176711829
]);
1176811830
let request = createRequest("/");
11769-
let data = await queryRoute(request, "root");
11831+
let data = await queryRoute(request, { routeId: "root" });
1177011832
expect(data instanceof Response).toBe(true);
1177111833
expect(await data.json()).toEqual({ key: "value" });
1177211834
});
@@ -11781,7 +11843,7 @@ describe("a router", () => {
1178111843
},
1178211844
]);
1178311845
let request = createSubmitRequest("/");
11784-
let data = await queryRoute(request, "root");
11846+
let data = await queryRoute(request, { routeId: "root" });
1178511847
expect(data instanceof Response).toBe(true);
1178611848
expect(await data.json()).toEqual({ key: "value" });
1178711849
});
@@ -11801,7 +11863,7 @@ describe("a router", () => {
1180111863
});
1180211864
let e;
1180311865
try {
11804-
let statePromise = queryRoute(request, "root");
11866+
let statePromise = queryRoute(request, { routeId: "root" });
1180511867
controller.abort();
1180611868
// This should resolve even though we never resolved the loader
1180711869
await statePromise;
@@ -11826,7 +11888,7 @@ describe("a router", () => {
1182611888
});
1182711889
let e;
1182811890
try {
11829-
let statePromise = queryRoute(request, "root");
11891+
let statePromise = queryRoute(request, { routeId: "root" });
1183011892
controller.abort();
1183111893
// This should resolve even though we never resolved the loader
1183211894
await statePromise;
@@ -11841,7 +11903,7 @@ describe("a router", () => {
1184111903
let request = createRequest("/", { signal: undefined });
1184211904
let e;
1184311905
try {
11844-
await queryRoute(request, "index");
11906+
await queryRoute(request, { routeId: "index" });
1184511907
} catch (_e) {
1184611908
e = _e;
1184711909
}
@@ -11850,6 +11912,38 @@ describe("a router", () => {
1185011912
);
1185111913
});
1185211914

11915+
it("should support a requestContext passed to loaders and actions", async () => {
11916+
let requestContext = { sessionId: "12345" };
11917+
let childStub = jest.fn(() => "CHILD");
11918+
let actionStub = jest.fn(() => "CHILD ACTION");
11919+
let arg = (s) => s.mock.calls[0][0];
11920+
let { queryRoute } = createStaticHandler([
11921+
{
11922+
path: "/",
11923+
children: [
11924+
{
11925+
id: "child",
11926+
path: "child",
11927+
action: actionStub,
11928+
loader: childStub,
11929+
},
11930+
],
11931+
},
11932+
]);
11933+
11934+
await queryRoute(createRequest("/child"), {
11935+
routeId: "child",
11936+
requestContext,
11937+
});
11938+
expect(arg(childStub).context.sessionId).toBe("12345");
11939+
11940+
await queryRoute(createSubmitRequest("/child"), {
11941+
routeId: "child",
11942+
requestContext,
11943+
});
11944+
expect(arg(actionStub).context.sessionId).toBe("12345");
11945+
});
11946+
1185311947
describe("Errors with Status Codes", () => {
1185411948
/* eslint-disable jest/no-conditional-expect */
1185511949
let { queryRoute } = createStaticHandler([
@@ -11887,7 +11981,7 @@ describe("a router", () => {
1188711981

1188811982
it("should handle not found routeIds with a 403 Response", async () => {
1188911983
try {
11890-
await queryRoute(createRequest("/"), "junk");
11984+
await queryRoute(createRequest("/"), { routeId: "junk" });
1189111985
expect(false).toBe(true);
1189211986
} catch (data) {
1189311987
expect(isRouteErrorResponse(data)).toBe(true);
@@ -11899,7 +11993,7 @@ describe("a router", () => {
1189911993
}
1190011994

1190111995
try {
11902-
await queryRoute(createSubmitRequest("/"), "junk");
11996+
await queryRoute(createSubmitRequest("/"), { routeId: "junk" });
1190311997
expect(false).toBe(true);
1190411998
} catch (data) {
1190511999
expect(isRouteErrorResponse(data)).toBe(true);
@@ -11913,7 +12007,7 @@ describe("a router", () => {
1191312007

1191412008
it("should handle missing loaders with a 400 Response", async () => {
1191512009
try {
11916-
await queryRoute(createRequest("/"), "root");
12010+
await queryRoute(createRequest("/"), { routeId: "root" });
1191712011
expect(false).toBe(true);
1191812012
} catch (data) {
1191912013
expect(isRouteErrorResponse(data)).toBe(true);
@@ -11930,7 +12024,7 @@ describe("a router", () => {
1193012024

1193112025
it("should handle missing actions with a 405 Response", async () => {
1193212026
try {
11933-
await queryRoute(createSubmitRequest("/"), "root");
12027+
await queryRoute(createSubmitRequest("/"), { routeId: "root" });
1193412028
expect(false).toBe(true);
1193512029
} catch (data) {
1193612030
expect(isRouteErrorResponse(data)).toBe(true);
@@ -11947,7 +12041,9 @@ describe("a router", () => {
1194712041

1194812042
it("should handle unsupported methods with a 405 Response", async () => {
1194912043
try {
11950-
await queryRoute(createRequest("/", { method: "OPTIONS" }), "root");
12044+
await queryRoute(createRequest("/", { method: "OPTIONS" }), {
12045+
routeId: "root",
12046+
});
1195112047
expect(false).toBe(true);
1195212048
} catch (data) {
1195312049
expect(isRouteErrorResponse(data)).toBe(true);

0 commit comments

Comments
 (0)