Files
rea/tests/acceptance/applications/javascriptNextRouteSegmentIdentity.test.ts
T
morluto ddd7ac7b84 fix(javascript): preserve Next filesystem route spelling
Apply Next-specific uppercase %5F normalization while retaining ordinary percent sequences, encoded separators, and literal percent characters as distinct source segments.

Fixes #6641
2026-10-24 00:11:41 +08:00

51 lines
2.1 KiB
TypeScript

import { expect } from "vitest";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import { writeFixtureFiles } from "../../support/javascriptApplicationFixture.js";
cliTest(
"preserves literal percent bytes in Next route source segments",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-next-route-segment-");
const page = (name: string) =>
`export default function Page${name}(){return null;}`;
await writeFixtureFiles(root, {
"app/%61/page.js": page("EncodedA"),
"app/a/page.js": page("PlainA"),
"app/100%/page.js": page("Percent"),
"app/team%2Fadmin/page.js": page("EncodedSlash"),
"app/%5Fpublic/page.js": page("EscapedUnderscore"),
"app/blog/%5fdraft/page.js": page("LowercaseEscape"),
});
const response = await cli.run({
arguments: ["analyze-javascript-application", root, "--format", "json"],
});
expect(response.exitCode, response.stdout + response.stderr).toBe(0);
const analysis = javascriptApplicationAnalysisResultSchema.parse(
parseEvidence(response.json).normalized_result,
);
expect(
analysis.route_inventory?.routes
.map(({ path, source_count }) => ({ path, source_count }))
.sort((left, right) =>
left.path < right.path ? -1 : left.path > right.path ? 1 : 0,
),
).toEqual([
{ path: "/%61", source_count: 1 },
{ path: "/100%", source_count: 1 },
{ path: "/_public", source_count: 1 },
{ path: "/a", source_count: 1 },
{ path: "/blog/%5fdraft", source_count: 1 },
{ path: "/team%2Fadmin", source_count: 1 },
]);
expect(analysis.route_inventory?.coverage).toMatchObject({
source_parsing: "complete",
candidate_enumeration: "complete",
application_routes: "unknown",
});
},
);