File
Blob: tests/client/components/page-mention/provider.dom.test.tsx
| 1 | import { StrictMode } from "react"; |
| 2 | import { act } from "react"; |
| 3 | import { createRoot, type Root } from "react-dom/client"; |
| 4 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
| 5 | |
| 6 | const resolveMock = vi.fn(); |
| 7 | |
| 8 | beforeEach(() => { |
| 9 | vi.resetModules(); |
| 10 | resolveMock.mockReset(); |
| 11 | vi.doMock("@/client/lib/api", () => ({ |
| 12 | api: { |
| 13 | pageMentions: { |
| 14 | resolve: resolveMock, |
| 15 | }, |
| 16 | }, |
| 17 | })); |
| 18 | }); |
| 19 | |
| 20 | afterEach(() => { |
| 21 | vi.restoreAllMocks(); |
| 22 | vi.unstubAllGlobals(); |
| 23 | }); |
| 24 | |
| 25 | async function flushReactWork() { |
| 26 | await act(async () => { |
| 27 | await Promise.resolve(); |
| 28 | await Promise.resolve(); |
| 29 | await Promise.resolve(); |
| 30 | }); |
| 31 | } |
| 32 | |
| 33 | describe("PageMentionProvider", () => { |
| 34 | it("keeps a live resolver under React StrictMode", async () => { |
| 35 | resolveMock.mockResolvedValue({ |
| 36 | mentions: [{ page_id: "page-2", accessible: true, title: "Roadmap", icon: null }], |
| 37 | }); |
| 38 | |
| 39 | const { PageMentionProvider } = await import("@/client/components/page-mention/provider"); |
| 40 | const { usePageMentionEntry } = await import("@/client/components/page-mention/context"); |
| 41 | |
| 42 | function Probe() { |
| 43 | const entry = usePageMentionEntry("page-2"); |
| 44 | return <span>{entry.title ?? entry.status}</span>; |
| 45 | } |
| 46 | |
| 47 | const host = document.createElement("div"); |
| 48 | document.body.appendChild(host); |
| 49 | let root: Root | null = createRoot(host); |
| 50 | |
| 51 | try { |
| 52 | await act(async () => { |
| 53 | root!.render( |
| 54 | <StrictMode> |
| 55 | <PageMentionProvider |
| 56 | workspaceId="workspace-1" |
| 57 | scopeKey="canonical:workspace-1:member" |
| 58 | cacheMode="live" |
| 59 | networkEnabled={true} |
| 60 | navigate={() => {}} |
| 61 | > |
| 62 | <Probe /> |
| 63 | </PageMentionProvider> |
| 64 | </StrictMode>, |
| 65 | ); |
| 66 | }); |
| 67 | await flushReactWork(); |
| 68 | |
| 69 | expect(resolveMock).toHaveBeenCalledWith("workspace-1", ["page-2"], undefined); |
| 70 | expect(host.textContent).toBe("Roadmap"); |
| 71 | } finally { |
| 72 | await act(async () => { |
| 73 | root?.unmount(); |
| 74 | }); |
| 75 | root = null; |
| 76 | host.remove(); |
| 77 | } |
| 78 | }); |
| 79 | }); |