From 68ee76c6b75c25ab130312bb204ce577f0f91da1 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Thu, 23 Apr 2026 00:03:54 -0700 Subject: [PATCH] fix(canvas): add getState to useCanvasStore mock in ContextMenu keyboard test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ContextMenu.tsx reads parent-workspace children via useCanvasStore.getState().nodes.filter(...) — a direct .getState() call, not the selector-calling form. The existing vi.mock exposed only the selector form, so rendering crashed with "TypeError: useCanvasStore.getState is not a function". Restructure the vi.mock factory to return Object.assign(fn, { getState: () => mockStore }) so both call shapes resolve. Factory body builds the function locally because vi.mock hoists above outer-scope variable declarations and can't reference `mockStore` via closure. Verified: all 15 tests in the file pass after the change. Unblocks the Canvas (Next.js) CI check on PR #1743 (staging→main sync). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../__tests__/ContextMenu.keyboard.test.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/canvas/src/components/__tests__/ContextMenu.keyboard.test.tsx b/canvas/src/components/__tests__/ContextMenu.keyboard.test.tsx index 085db159..cc7a65df 100644 --- a/canvas/src/components/__tests__/ContextMenu.keyboard.test.tsx +++ b/canvas/src/components/__tests__/ContextMenu.keyboard.test.tsx @@ -48,11 +48,20 @@ const mockStore = { nodes: [] as Array<{ id: string; data: { parentId: string | null } }>, }; -vi.mock("@/store/canvas", () => ({ - useCanvasStore: vi.fn( - (selector: (s: typeof mockStore) => unknown) => selector(mockStore) - ), -})); +// useCanvasStore.getState() is called directly by ContextMenu to read `nodes` +// for parent-filtering (see ContextMenu.tsx childNodes computation). The mock +// must expose both the selector-calling function form AND the .getState() +// form so production code using either pattern doesn't hit "not a function". +// Factory body runs under vi.mock's hoist — cannot reference outer scope, +// so we build the mock function inside and reach `mockStore` via `globalThis`. +vi.mock("@/store/canvas", () => { + const fn = vi.fn((selector: (s: typeof mockStore) => unknown) => + selector(mockStore), + ); + return { + useCanvasStore: Object.assign(fn, { getState: () => mockStore }), + }; +}); // ── Component under test — imported AFTER mocks ─────────────────────────────── import { ContextMenu } from "../ContextMenu";