Files
cloudflare__vinext/tests/navigation-planner-prefetch-reuse.test.ts
T
Nathan Nguyen 1b3a35606e refactor(navigation): drop V0 suffix from planner types (#2008)
The navigation planner's public and internal types were suffixed `V0`
(RouteSnapshotV0, NavigationDecisionV0, FlightResultV0, and 19 others).
The suffix implied a versioning scheme that never materialized — there is
no V1, and the schema-version concerns it hinted at are carried explicitly
elsewhere (NAVIGATION_TRACE_SCHEMA_VERSION, CACHE_PROOF_MODEL_SCHEMA_VERSION).
The bare suffix was pure noise at every call site.

Rename all 22 `…V0` planner types to their unsuffixed names across the
planner, the browser state/entry/action modules, and the planner test
suite. Pure mechanical rename: no behavior change, all 295 planner and
browser-entry tests pass unchanged.
2026-06-14 23:32:10 +01:00

263 lines
7.0 KiB
TypeScript

import { describe, expect, it } from "vite-plus/test";
import {
NAVIGATION_TRACE_SCHEMA_VERSION,
NavigationTraceReasonCodes,
} from "../packages/vinext/src/server/navigation-trace.js";
import {
navigationPlanner,
type NavigationReuseDecision,
type NavigationReuseFacts,
type VisitedResponseCacheCandidateFacts,
} from "../packages/vinext/src/server/navigation-planner.js";
function createReuseFacts(overrides: Partial<NavigationReuseFacts> = {}): NavigationReuseFacts {
return {
bypassNavigationCache: false,
navigationKind: "navigate",
optimisticRouteShell: { status: "available" },
prefetch: { status: "unavailable" },
targetHref: "/dashboard",
visitedResponse: { status: "unavailable" },
...overrides,
};
}
function classifyReuse(overrides: Partial<NavigationReuseFacts> = {}): NavigationReuseDecision {
return navigationPlanner.classifyNavigationReuse(createReuseFacts(overrides));
}
describe("navigationPlanner prefetch reuse classification", () => {
it("skips prefetch probes when a visited response is already reusable", () => {
expect(
navigationPlanner.classifyNavigationPrefetchProbe({
bypassNavigationCache: false,
navigationKind: "navigate",
visitedResponse: { status: "available" },
}),
).toEqual({
kind: "skip",
reason: "visitedResponseAvailable",
});
});
it("probes prefetch only for non-refresh cacheable visited-response misses", () => {
expect(
navigationPlanner.classifyNavigationPrefetchProbe({
bypassNavigationCache: false,
navigationKind: "navigate",
visitedResponse: { status: "unavailable" },
}),
).toEqual({ kind: "probe" });
expect(
navigationPlanner.classifyNavigationPrefetchProbe({
bypassNavigationCache: false,
navigationKind: "refresh",
visitedResponse: { status: "unavailable" },
}),
).toEqual({
kind: "skip",
reason: "refresh",
});
expect(
navigationPlanner.classifyNavigationPrefetchProbe({
bypassNavigationCache: true,
navigationKind: "navigate",
visitedResponse: { status: "unavailable" },
}),
).toEqual({
kind: "skip",
reason: "cacheBypassed",
});
});
it("reuses visited responses before prefetch or optimistic candidates", () => {
const decision = classifyReuse({
prefetch: { status: "available" },
visitedResponse: { status: "available" },
});
expect(decision).toEqual({
kind: "reuseVisitedResponse",
trace: {
schemaVersion: NAVIGATION_TRACE_SCHEMA_VERSION,
entries: [
{
code: NavigationTraceReasonCodes.visitedResponseReuse,
fields: {
eventKind: "navigate",
targetHref: "/dashboard",
},
},
],
},
});
});
it("consumes an eligible prefetch when no visited response exists", () => {
const decision = classifyReuse({
prefetch: { status: "available" },
});
expect(decision).toMatchObject({
kind: "consumePrefetch",
trace: {
entries: [
{
code: NavigationTraceReasonCodes.prefetchResponseReuse,
},
],
},
});
});
it("attempts an optimistic route shell for navigate misses with a route manifest", () => {
const decision = classifyReuse();
expect(decision).toMatchObject({
kind: "attemptOptimisticRouteShell",
trace: {
entries: [
{
code: NavigationTraceReasonCodes.optimisticRouteShell,
},
],
},
});
});
it("skips visited and prefetch reuse when navigation cache is bypassed", () => {
const decision = classifyReuse({
bypassNavigationCache: true,
prefetch: { status: "available" },
visitedResponse: { status: "available" },
});
expect(decision.kind).toBe("attemptOptimisticRouteShell");
});
it("fetches fresh for refresh even when cache candidates exist", () => {
const decision = classifyReuse({
navigationKind: "refresh",
prefetch: { status: "available" },
visitedResponse: { status: "available" },
});
expect(decision).toEqual({
kind: "fetchFresh",
reason: "refresh",
trace: {
schemaVersion: NAVIGATION_TRACE_SCHEMA_VERSION,
entries: [
{
code: NavigationTraceReasonCodes.fetchFresh,
fields: {
eventKind: "refresh",
freshFetchReason: "refresh",
targetHref: "/dashboard",
},
},
],
},
});
});
it("fetches fresh for traverse misses instead of attempting optimistic shells", () => {
const decision = classifyReuse({
navigationKind: "traverse",
});
expect(decision).toMatchObject({
kind: "fetchFresh",
reason: "cacheMiss",
});
});
it("fetches fresh for navigate misses without an optimistic shell candidate", () => {
const decision = classifyReuse({
optimisticRouteShell: { reason: "routeManifestMissing", status: "unavailable" },
});
expect(decision).toMatchObject({
kind: "fetchFresh",
reason: "routeManifestMissing",
});
});
it("fetches fresh for bypassed navigate misses without an optimistic shell candidate", () => {
const decision = classifyReuse({
bypassNavigationCache: true,
optimisticRouteShell: { reason: "routeManifestMissing", status: "unavailable" },
prefetch: { status: "available" },
visitedResponse: { status: "available" },
});
expect(decision).toMatchObject({
kind: "fetchFresh",
reason: "cacheBypassed",
});
});
});
describe("navigationPlanner visited-response cache candidate classification", () => {
function classifyVisited(
overrides: Partial<Extract<VisitedResponseCacheCandidateFacts, { candidate: "present" }>> = {},
) {
return navigationPlanner.classifyVisitedResponseCacheCandidate({
candidate: "present",
fresh: true,
mountedSlotsMatch: true,
navigationKind: "navigate",
...overrides,
});
}
it("reuses fresh matching candidates", () => {
expect(classifyVisited()).toEqual({ kind: "reuse" });
});
it("misses absent candidates", () => {
expect(
navigationPlanner.classifyVisitedResponseCacheCandidate({
candidate: "missing",
navigationKind: "navigate",
}),
).toEqual({ kind: "miss" });
});
it("evicts slot-mismatched candidates before evaluating freshness", () => {
expect(
classifyVisited({
fresh: false,
mountedSlotsMatch: false,
}),
).toEqual({
kind: "evict",
reason: "mountedSlotsMismatch",
});
});
it("evicts refresh candidates even when still fresh", () => {
expect(
classifyVisited({
navigationKind: "refresh",
}),
).toEqual({
kind: "evict",
reason: "refresh",
});
});
it("evicts stale candidates", () => {
expect(
classifyVisited({
fresh: false,
}),
).toEqual({
kind: "evict",
reason: "stale",
});
});
});