返回 DeepSeek-Reasonix
startup-gate-lifecycle.test.tsx
根目录 / desktop / frontend / src / __tests__ / startup-gate-lifecycle.test.tsx
1 import assert from "node:assert/strict";
2 import React, { act, StrictMode } from "react";
3 import { createRoot } from "react-dom/client";
4 import { JSDOM } from "jsdom";
5 import { StartupGateLifecycle } from "../app-runtime/StartupGateLifecycle";
6 import { useAppNavigationStore } from "../store/appNavigation";
7 import { useOverlayStore } from "../store/overlays";
8 import { installDesktopHostStub } from "./desktopHostStub";
9
10 const dom = new JSDOM("<div id='root'></div>", { url: "http://localhost" });
11 Object.assign(globalThis, { window: dom.window, document: dom.window.document,
12 localStorage: dom.window.localStorage, IS_REACT_ACT_ENVIRONMENT: true });
13 const pending: Array<(needs: boolean) => void> = [];
14 installDesktopHostStub({
15 NeedsOnboarding: () => new Promise<boolean>((resolve) => { pending.push(resolve); }),
16 });
17 async function mount() {
18 localStorage.clear();
19 useAppNavigationStore.setState({ page: { kind: "workspace" }, generation: 0, settingsFocus: null });
20 useOverlayStore.getState().setProviderSetupNeeded(false);
21 const root = createRoot(document.getElementById("root")!);
22 await act(async () => root.render(<StrictMode><StartupGateLifecycle /></StrictMode>));
23 return root;
24 }
25 try {
26 let root = await mount();
27 assert.equal(pending.length, 2);
28 await act(async () => pending.shift()!(true));
29 assert.equal(useOverlayStore.getState().providerSetupNeeded, false, "retired StrictMode probe cannot publish");
30 await act(async () => pending.shift()!(true));
31 assert.deepEqual(useAppNavigationStore.getState().settingsFocus, { target: "model-access", onboarding: true });
32 assert.deepEqual(useAppNavigationStore.getState().page, { kind: "settings", tab: "providers" });
33 await act(async () => root.unmount());
34
35 root = await mount();
36 useAppNavigationStore.getState().openPage({ kind: "trash" });
37 await act(async () => { pending.splice(0).forEach(resolve => resolve(true)); });
38 assert.deepEqual(useAppNavigationStore.getState().page, { kind: "trash" }, "late setup result cannot replace a newer navigation intent");
39 assert.equal(useOverlayStore.getState().providerSetupNeeded, true, "current probe still publishes advisory setup status");
40 await act(async () => root.unmount());
41
42 root = await mount();
43 await act(async () => root.unmount());
44 await act(async () => { pending.splice(0).forEach(resolve => resolve(true)); });
45 assert.equal(useOverlayStore.getState().providerSetupNeeded, false, "unmounted probe cannot publish setup state");
46 assert.deepEqual(useAppNavigationStore.getState().page, { kind: "workspace" });
47 console.log("startup gate: direct setup, StrictMode retirement, navigation generation and unmount passed");
48 } finally { dom.window.close(); }
49
49 lines Plain Text