返回 DeepSeek-Reasonix
project-tree-organization-reset.test.tsx
根目录 / desktop / frontend / src / __tests__ / project-tree-organization-reset.test.tsx
1 // Run: pnpm exec tsx src/__tests__/project-tree-organization-reset.test.tsx
2 import assert from "node:assert/strict";
3 import { JSDOM } from "jsdom";
4 import React, { act } from "react";
5 import { createRoot } from "react-dom/client";
6 import { useProjectTreeOrganization } from "../components/ProjectTreeOrganization";
7 import type { ProjectNode, ProjectTreeOrganizationBindings } from "../lib/types";
8 import type { SessionOrganizationMutation, SessionOrganizationSnapshot } from "../generated/desktopContract.generated";
9 import { ToastProvider } from "../lib/toast";
10 import { LocaleProvider, t } from "../lib/i18n";
11
12 const dom = new JSDOM('<html><body><div id="root"></div></body></html>', { url: "http://localhost/" });
13 Object.assign(globalThis, { window: dom.window, document: dom.window.document, Node: dom.window.Node, Element: dom.window.Element,
14 HTMLElement: dom.window.HTMLElement, IS_REACT_ACT_ENVIRONMENT: true });
15
16 const folder: ProjectNode = { key: "project-/repo", kind: "project", label: "Repo", root: "/repo", children: [] };
17 const initialOrder = ["ref\0local\0older", "ref\0local\0newer"];
18 let snapshot: SessionOrganizationSnapshot = { revision: 1, applied: true, manualOrderEnabled: true, order: initialOrder, groups: [] };
19 const mutations: SessionOrganizationMutation[] = [];
20 let refreshes = 0;
21 const bindings: ProjectTreeOrganizationBindings = {
22 GetSessionOrganization: async () => snapshot,
23 UpdateSessionOrganization: async (_workspace, revision, mutation) => {
24 assert.equal(revision, snapshot.revision);
25 mutations.push(mutation);
26 snapshot = { ...snapshot, revision: revision + 1, manualOrderEnabled: false };
27 return snapshot;
28 },
29 };
30
31 function Harness() {
32 const organization = useProjectTreeOrganization({ tree: [folder], refresh: async () => { refreshes += 1; }, bindings });
33 const resetItem = organization.resetOrderMenuItems(folder, t, () => {});
34 return <><output id="order">{organization.orderFor?.(folder).join(",")}</output>
35 {resetItem.map(item => <button key={item.key} id="reset" onClick={item.onSelect}>Reset</button>)}</>;
36 }
37
38 const root = createRoot(document.getElementById("root")!);
39 const flush = async () => { await act(async () => { await new Promise(resolve => setTimeout(resolve, 0)); }); };
40 try {
41 await act(async () => root.render(<LocaleProvider><ToastProvider><Harness /></ToastProvider></LocaleProvider>));
42 await flush();
43 assert.equal(document.getElementById("order")?.textContent, initialOrder.join(","));
44 await act(async () => { document.getElementById("reset")!.click(); });
45 await flush();
46 assert.deepEqual(mutations.map(mutation => mutation.kind), ["reset-order"]);
47 assert.equal(document.getElementById("order")?.textContent, "");
48 assert.equal(refreshes, 1);
49 } finally {
50 await act(async () => root.unmount());
51 dom.window.close();
52 }
53
53 lines Plain Text