Skip to content

Commit ddca616

Browse files
authored
Remove trailing slash data request flag (#15100)
1 parent 7db438c commit ddca616

33 files changed

Lines changed: 111 additions & 335 deletions

integration/error-data-request-test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ test.describe("ErrorBoundary", () => {
108108

109109
test("returns a 200 empty response on a data fetch to a path with no loaders", async () => {
110110
let { status, headers, data } =
111-
await fixture.requestSingleFetchData("/_root.data");
111+
await fixture.requestSingleFetchData("/_.data");
112112
expect(status).toBe(200);
113113
expect(headers.has("X-Remix-Response")).toBe(true);
114114
expect(data).toEqual({});
115115
});
116116

117117
test("returns a 405 on a data fetch POST to a path with no action", async () => {
118118
let { status, headers, data } = await fixture.requestSingleFetchData(
119-
"/_root.data?index",
119+
"/_.data?index",
120120
{
121121
method: "POST",
122122
},
@@ -127,11 +127,11 @@ test.describe("ErrorBoundary", () => {
127127
error: new ErrorResponseImpl(
128128
405,
129129
"Method Not Allowed",
130-
'Error: You made a POST request to "/_root.data" but did not provide an `action` for route "routes/_index", so there is no way to handle the request.',
130+
'Error: You made a POST request to "/_.data" but did not provide an `action` for route "routes/_index", so there is no way to handle the request.',
131131
),
132132
});
133133
assertLoggedErrorInstance(
134-
'You made a POST request to "/_root.data" but did not provide an `action` for route "routes/_index", so there is no way to handle the request.',
134+
'You made a POST request to "/_.data" but did not provide an `action` for route "routes/_index", so there is no way to handle the request.',
135135
);
136136
});
137137

integration/error-sanitization-test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ test.describe("Error Sanitization", () => {
230230
});
231231

232232
test("returns data without errors", async () => {
233-
let { data } = await fixture.requestSingleFetchData("/_root.data");
233+
let { data } = await fixture.requestSingleFetchData("/_.data");
234234
expect(data).toEqual({
235235
"routes/_index": {
236236
data: "LOADER",
@@ -239,7 +239,7 @@ test.describe("Error Sanitization", () => {
239239
});
240240

241241
test("sanitizes loader errors in data requests", async () => {
242-
let { data } = await fixture.requestSingleFetchData("/_root.data?loader");
242+
let { data } = await fixture.requestSingleFetchData("/_.data?loader");
243243
expect(data).toEqual({
244244
"routes/_index": {
245245
error: new Error("Unexpected Server Error"),
@@ -388,7 +388,7 @@ test.describe("Error Sanitization", () => {
388388
});
389389

390390
test("returns data without errors", async () => {
391-
let { data } = await fixture.requestSingleFetchData("/_root.data");
391+
let { data } = await fixture.requestSingleFetchData("/_.data");
392392
expect(data).toEqual({
393393
"routes/_index": {
394394
data: "LOADER",
@@ -397,7 +397,7 @@ test.describe("Error Sanitization", () => {
397397
});
398398

399399
test("does not sanitize loader errors in data requests", async () => {
400-
let { data } = await fixture.requestSingleFetchData("/_root.data?loader");
400+
let { data } = await fixture.requestSingleFetchData("/_.data?loader");
401401
expect(data).toEqual({
402402
"routes/_index": {
403403
error: new Error("Loader Error"),
@@ -634,7 +634,7 @@ test.describe("Error Sanitization", () => {
634634
});
635635

636636
test("returns data without errors", async () => {
637-
let { data } = await fixture.requestSingleFetchData("/_root.data");
637+
let { data } = await fixture.requestSingleFetchData("/_.data");
638638
expect(data).toEqual({
639639
"routes/_index": {
640640
data: "LOADER",
@@ -643,15 +643,15 @@ test.describe("Error Sanitization", () => {
643643
});
644644

645645
test("sanitizes loader errors in data requests", async () => {
646-
let { data } = await fixture.requestSingleFetchData("/_root.data?loader");
646+
let { data } = await fixture.requestSingleFetchData("/_.data?loader");
647647
expect(data).toEqual({
648648
"routes/_index": {
649649
error: new Error("Unexpected Server Error"),
650650
},
651651
});
652652
expect(errorLogs[0][0]).toEqual("App Specific Error Logging:");
653653
expect(errorLogs[1][0]).toEqual(
654-
" Request: GET test://test/_root.data?loader",
654+
" Request: GET test://test/_.data?loader",
655655
);
656656
expect(errorLogs[2][0]).toEqual(" Error: Loader Error");
657657
expect(errorLogs[3][0]).toMatch(" at ");

integration/http-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ test.describe("HTTP behavior", () => {
5959
expect(await response.text()).toBe("RESOURCE");
6060

6161
let singleFetchResponse =
62-
await appFixture.requestSingleFetchData("/_root.data");
62+
await appFixture.requestSingleFetchData("/_.data");
6363
expect(response.status).toBe(202);
6464
expect(singleFetchResponse.data).toEqual({
6565
"routes/_index": { data: "INDEX" },
@@ -78,7 +78,7 @@ test.describe("HTTP behavior", () => {
7878
expect(response.body).toBe(null);
7979

8080
let singleFetchResponse = await appFixture.requestSingleFetchData(
81-
"/_root.data",
81+
"/_.data",
8282
{ method: "HEAD" },
8383
);
8484
expect(response.status).toBe(202);

integration/loader-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ test.describe("loader", () => {
5252
});
5353

5454
test("returns responses for single fetch routes", async () => {
55-
let { data } = await fixture.requestSingleFetchData("/_root.data");
55+
let { data } = await fixture.requestSingleFetchData("/_.data");
5656
expect(data).toEqual({
5757
root: { data: ROOT_DATA },
5858
"routes/_index": { data: INDEX_DATA },

integration/multiple-cookies-test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ test.describe("pathless layout routes", () => {
6767
let app = new PlaywrightFixture(appFixture, page);
6868
await app.goto("/");
6969
// do this after the first request so that it doesnt appear in our next assertions
70-
let responses = app.collectResponses(
71-
(url) => url.pathname === "/_root.data",
72-
);
70+
let responses = app.collectResponses((url) => url.pathname === "/_.data");
7371
await page.click("button[type=submit]");
7472
await page.waitForSelector(`[data-testid="action-success"]`);
7573
let setCookies = await responses[0].headerValues("set-cookie");

integration/passthrough-requests-test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,29 +120,29 @@ test.describe("pass through requests", () => {
120120
// Client-side navigation with query params
121121
await app.clickLink("/?a=1");
122122
expect(await page.locator("[data-loader-url]").textContent()).toBe(
123-
"/_root.data?a=1",
123+
"/_.data?a=1",
124124
);
125125
expect(await page.locator("[data-loader-path]").textContent()).toBe(
126126
"/?a=1",
127127
);
128-
expect(requests).toEqual(["/_root.data?a=1"]);
128+
expect(requests).toEqual(["/_.data?a=1"]);
129129
requests = [];
130130

131131
// Client-side form submission with query params
132132
await app.clickElement('button[type="submit"]');
133133
expect(await page.locator("[data-action-url]").textContent()).toBe(
134-
"/_root.data?index&a=1",
134+
"/_.data?index&a=1",
135135
);
136136
expect(await page.locator("[data-action-path]").textContent()).toBe(
137137
"/?a=1",
138138
);
139139
expect(await page.locator("[data-loader-url]").textContent()).toBe(
140-
"/_root.data?a=1",
140+
"/_.data?a=1",
141141
);
142142
expect(await page.locator("[data-loader-path]").textContent()).toBe(
143143
"/?a=1",
144144
);
145-
expect(requests).toEqual(["/_root.data?index&a=1", "/_root.data?a=1"]);
145+
expect(requests).toEqual(["/_.data?index&a=1", "/_.data?a=1"]);
146146
requests = [];
147147

148148
// Navigate to new page

integration/request-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ test("loader request on CSR GET requests", async ({ page }) => {
120120
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML());
121121
expect(loaderData.method).toEqual("GET");
122122
expect(loaderData.url).toMatch(
123-
/^http:\/\/localhost:\d+\/_root\.data\?type=csr$/,
123+
/^http:\/\/localhost:\d+\/_.data\?type=csr$/,
124124
);
125125
expect(loaderData.headers.cookie).toEqual("cookie=nomnom");
126126
expect(loaderData.body).toEqual(null);
@@ -168,14 +168,14 @@ test("action + loader requests on CSR POST requests", async ({ page }) => {
168168
let actionData = JSON.parse(await page.locator("#action-data").innerHTML());
169169
expect(actionData.method).toEqual("POST");
170170
expect(actionData.url).toMatch(
171-
/^http:\/\/localhost:\d+\/_root\.data\?index$/,
171+
/^http:\/\/localhost:\d+\/_.data\?index$/,
172172
);
173173
expect(actionData.headers.cookie).toEqual("cookie=nomnom");
174174
expect(actionData.body).toEqual({ type: "csr" });
175175

176176
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML());
177177
expect(loaderData.method).toEqual("GET");
178-
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/_root\.data$/);
178+
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/_.data$/);
179179
expect(loaderData.headers.cookie).toEqual("cookie=nomnom");
180180
expect(loaderData.body).toEqual(null);
181181
});

integration/single-fetch-test.ts

Lines changed: 8 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ test.describe("single-fetch", () => {
205205
let fixture = await createFixture({
206206
files,
207207
});
208-
let res = await fixture.requestSingleFetchData("/_root.data");
208+
let res = await fixture.requestSingleFetchData("/_.data");
209209
expect(res.data).toEqual({
210210
root: {
211211
data: {
@@ -1141,7 +1141,7 @@ test.describe("single-fetch", () => {
11411141
expect(await page.locator("#data").innerText()).toBe(
11421142
'[["root",{"count":3}],["routes/_index",null]]',
11431143
);
1144-
expect(urls).toEqual(["/_root.data"]);
1144+
expect(urls).toEqual(["/_.data"]);
11451145
urls.splice(0, urls.length);
11461146

11471147
await app.clickLink("/page?optout");
@@ -1960,7 +1960,7 @@ test.describe("single-fetch", () => {
19601960
await app.clickLink("/base/");
19611961
await expect(page.getByText("Index")).toBeVisible();
19621962

1963-
expect(requests).toEqual(["/base/data.data", "/base/_root.data"]);
1963+
expect(requests).toEqual(["/base/data.data", "/base/_.data"]);
19641964
});
19651965

19661966
test("processes redirects when a basename is present", async ({ page }) => {
@@ -2497,8 +2497,8 @@ test.describe("single-fetch", () => {
24972497

24982498
expect(await page.innerText("[data-submit]")).toEqual("no content!");
24992499
expect(requests).toEqual([
2500-
["POST", 204, "/_root.data?index"],
2501-
["GET", 200, "/_root.data"],
2500+
["POST", 204, "/_.data?index"],
2501+
["GET", 200, "/_.data"],
25022502
]);
25032503
});
25042504

@@ -2538,7 +2538,7 @@ test.describe("single-fetch", () => {
25382538
expect(await documentRes.text()).toBe("");
25392539

25402540
// Data requests
2541-
let dataRes = await fixture.requestSingleFetchData("/_root.data");
2541+
let dataRes = await fixture.requestSingleFetchData("/_.data");
25422542
expect(dataRes.data).toEqual({
25432543
root: {
25442544
data: {
@@ -2551,7 +2551,7 @@ test.describe("single-fetch", () => {
25512551
},
25522552
},
25532553
});
2554-
dataRes = await fixture.requestSingleFetchData("/_root.data", {
2554+
dataRes = await fixture.requestSingleFetchData("/_.data", {
25552555
headers: {
25562556
"If-None-Match": "1234",
25572557
},
@@ -4566,7 +4566,7 @@ test.describe("single-fetch", () => {
45664566
expect(await app.getHtml("h1")).toMatch("It worked!");
45674567
});
45684568

4569-
test("always uses /{path}.data without future.v8_trailingSlashAwareDataRequests flag", async ({
4569+
test("uses {path}.data or {path}/_.data depending on trailing slash", async ({
45704570
page,
45714571
}) => {
45724572
let fixture = await createFixture({
@@ -4644,105 +4644,6 @@ test.describe("single-fetch", () => {
46444644
expect(await page.locator("#pathname").innerText()).toEqual("/about/");
46454645
expect(await page.locator("#trailing-slash").innerText()).toEqual("true");
46464646

4647-
// Client-side navigation with trailing slash
4648-
await app.goto("/");
4649-
await app.clickLink("/about/");
4650-
await page.waitForSelector("#pathname");
4651-
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4652-
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4653-
expect(requests).toEqual(["/about.data"]);
4654-
requests = [];
4655-
4656-
// Client-side navigation back to /
4657-
await app.clickLink("/");
4658-
await page.waitForSelector("h1:has-text('Home')");
4659-
expect(requests).toEqual(["/_root.data"]);
4660-
requests = [];
4661-
});
4662-
4663-
test("uses {path}.data or {path}/_.data depending on trailing slash with future.v8_trailingSlashAwareDataRequests flag", async ({
4664-
page,
4665-
}) => {
4666-
let fixture = await createFixture({
4667-
files: {
4668-
...files,
4669-
"react-router.config.ts": reactRouterConfig({
4670-
future: {
4671-
v8_trailingSlashAwareDataRequests: true,
4672-
},
4673-
}),
4674-
"app/routes/_index.tsx": js`
4675-
import { Link } from "react-router";
4676-
4677-
export default function Index() {
4678-
return (
4679-
<div>
4680-
<h1>Home</h1>
4681-
<Link to="/about/">Go to About (with trailing slash)</Link>
4682-
<Link to="/about">Go to About (without trailing slash)</Link>
4683-
</div>
4684-
);
4685-
}
4686-
`,
4687-
"app/routes/about.tsx": js`
4688-
import { Link, useLoaderData } from "react-router";
4689-
4690-
export function loader({ request }) {
4691-
let pathname = new URL(request.url).pathname
4692-
.replace(/_\.data$/, "")
4693-
.replace(/\.data$/, "");
4694-
return {
4695-
pathname,
4696-
hasTrailingSlash: pathname.endsWith("/"),
4697-
};
4698-
}
4699-
4700-
export default function About() {
4701-
let { pathname, hasTrailingSlash } = useLoaderData();
4702-
return (
4703-
<div>
4704-
<h1>About</h1>
4705-
<p id="pathname">{pathname}</p>
4706-
<p id="trailing-slash">{String(hasTrailingSlash)}</p>
4707-
<Link to="/">Go back home</Link>
4708-
</div>
4709-
);
4710-
}
4711-
`,
4712-
},
4713-
});
4714-
let appFixture = await createAppFixture(fixture);
4715-
let app = new PlaywrightFixture(appFixture, page);
4716-
4717-
let requests: string[] = [];
4718-
page.on("request", (req) => {
4719-
let url = new URL(req.url());
4720-
if (url.pathname.endsWith(".data")) {
4721-
requests.push(url.pathname + url.search);
4722-
}
4723-
});
4724-
4725-
// Document load without trailing slash
4726-
await app.goto("/about");
4727-
await page.waitForSelector("#pathname");
4728-
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4729-
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4730-
4731-
// Client-side navigation without trailing slash
4732-
await app.goto("/");
4733-
await app.clickLink("/about");
4734-
await page.waitForSelector("#pathname");
4735-
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4736-
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4737-
expect(requests).toEqual(["/about.data"]);
4738-
requests = [];
4739-
4740-
// Document load with trailing slash
4741-
await app.goto("/about/");
4742-
await page.waitForSelector("#pathname");
4743-
expect(await page.locator("#pathname").innerText()).toEqual("/about/");
4744-
expect(await page.locator("#trailing-slash").innerText()).toEqual("true");
4745-
47464647
// Client-side navigation with trailing slash
47474648
await app.goto("/");
47484649
await app.clickLink("/about/");

0 commit comments

Comments
 (0)