mirror of
https://github.com/cloudflare/vinext.git
synced 2026-09-14 19:04:59 +08:00
573997382e
* perf(client): omit unused server action client * fix(client): capture server action state before lazy load --------- Co-authored-by: James <james@eli.cx>
91 lines
3.0 KiB
TypeScript
91 lines
3.0 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
|
|
import { createClientNavigationRenderSnapshot } from "../packages/vinext/src/shims/navigation.js";
|
|
import { createServerActionInitiationSnapshot } from "../packages/vinext/src/server/app-browser-action-result.js";
|
|
import { invokeClientServerAction } from "../packages/vinext/src/server/app-browser-server-action-client.js";
|
|
import type { AppRouterState } from "../packages/vinext/src/server/app-browser-state.js";
|
|
import {
|
|
AppElementsWire,
|
|
normalizeAppElements,
|
|
} from "../packages/vinext/src/server/app-elements.js";
|
|
import { ACTION_REDIRECT_HEADER } from "../packages/vinext/src/server/headers.js";
|
|
import { navigationPlanner } from "../packages/vinext/src/server/navigation-planner.js";
|
|
|
|
vi.mock("@vitejs/plugin-rsc/browser", () => ({
|
|
createFromFetch: vi.fn(),
|
|
createTemporaryReferenceSet: vi.fn(() => new Map()),
|
|
encodeReply: vi.fn(async () => "encoded-action-args"),
|
|
}));
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
describe("app browser server action client", () => {
|
|
it("uses action state captured before the lazy client loads", async () => {
|
|
const elements = normalizeAppElements(
|
|
AppElementsWire.createMetadataEntries({
|
|
interception: null,
|
|
interceptionContext: null,
|
|
layoutIds: [AppElementsWire.encodeLayoutId("/")],
|
|
rootLayoutTreePath: "/",
|
|
routeId: "route:/original",
|
|
slotBindings: [],
|
|
}),
|
|
);
|
|
const routerState: AppRouterState = {
|
|
activeOperation: null,
|
|
bfcacheIds: {},
|
|
elements,
|
|
interception: null,
|
|
interceptionContext: null,
|
|
layoutFlags: {},
|
|
layoutIds: [AppElementsWire.encodeLayoutId("/")],
|
|
navigationSnapshot: createClientNavigationRenderSnapshot("https://example.com/original", {}),
|
|
previousNextUrl: null,
|
|
renderId: 0,
|
|
rootLayoutTreePath: "/",
|
|
routeId: "route:/original",
|
|
slotBindings: [],
|
|
visibleCommitVersion: 0,
|
|
};
|
|
const actionInitiation = createServerActionInitiationSnapshot({
|
|
href: "https://example.com/original?tab=1",
|
|
navigationId: 42,
|
|
routerState,
|
|
});
|
|
vi.stubGlobal("window", {
|
|
location: {
|
|
href: "https://example.com/newer",
|
|
origin: "https://example.com",
|
|
},
|
|
});
|
|
const fetchMock = vi.fn().mockResolvedValue(
|
|
new Response(null, {
|
|
status: 303,
|
|
headers: {
|
|
[ACTION_REDIRECT_HEADER]: "/target",
|
|
"content-type": "text/plain",
|
|
},
|
|
}),
|
|
);
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
|
|
await invokeClientServerAction("action-id", [], actionInitiation, {
|
|
basePath: "",
|
|
clearClientNavigationCaches: vi.fn(),
|
|
clientRscCompatibilityId: null,
|
|
commitSameUrlNavigatePayload: vi.fn(),
|
|
navigationPlanner,
|
|
performHardNavigation: vi.fn(),
|
|
renderRedirectPayload: vi.fn(),
|
|
syncCurrentHistoryState: vi.fn(),
|
|
syncServerActionHttpFallbackHead: vi.fn(),
|
|
});
|
|
|
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
"/original?tab=1",
|
|
expect.objectContaining({ method: "POST" }),
|
|
);
|
|
});
|
|
});
|