fix(web-modules): I-1 пакет вики инвалидирует весь wiki/<проект>, включая status
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8abc390f0e
commit
3a6ec3e602
@ -246,4 +246,25 @@ describe("страница «Вики»", () => {
|
||||
open("/wiki?project=AWPCA&page=DOC-2");
|
||||
expect(await screen.findByText(/Eva не ответила: 502/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("I-1: пакет wiki_sync завершён — подзаголовок «обновлено …» и дерево обновляются без перезагрузки", async () => {
|
||||
let synced = false;
|
||||
const fresh = { ...STATUS, synced_at: "2026-10-24T12:00:00+00:00" };
|
||||
const empty = { ...STATUS, synced_at: null, pages: 0 };
|
||||
mockFetch((method, url) => {
|
||||
if (url.pathname === "/wiki/status") return json(200, synced ? fresh : empty);
|
||||
if (url.pathname === "/wiki/sync" && method === "POST") { synced = true; return json(202, { batch_id: 5 }); }
|
||||
if (url.pathname === "/batches/5") return json(200, { id: 5, status: "done", module: "wiki", commands: [{ type: "wiki_sync", status: "done" }], author: "viewer", title: "t", created_at: "2026-10-24T12:00:00+00:00" });
|
||||
if (url.pathname === "/wiki/tree") return json(200, TREE);
|
||||
if (url.pathname === "/agents") return json(200, { agents: [] });
|
||||
const m = /^\/wiki\/pages\/([^/]+)$/.exec(url.pathname);
|
||||
if (m) return json(200, page(decodeURIComponent(m[1])));
|
||||
return json(404, { error: "not_found" });
|
||||
});
|
||||
open("/wiki?project=AWPCA");
|
||||
await screen.findByText("Вики ещё не синхронизирована. Нажмите «Обновить вики».");
|
||||
await userEvent.click(screen.getByRole("button", { name: "Обновить вики" }));
|
||||
expect(await screen.findByText(`Корень · 3 страниц · обновлено ${fmtStamp(fresh.synced_at)}`, {}, { timeout: 8000 })).toBeInTheDocument();
|
||||
expect(await screen.findByRole("treeitem", { name: /Модель данных/ })).toBeInTheDocument();
|
||||
}, 15000);
|
||||
});
|
||||
|
||||
@ -19,6 +19,7 @@ export const wikiStatus: ModuleStatus = {
|
||||
},
|
||||
invalidate: (qc, project) => {
|
||||
if (project === null) return;
|
||||
for (const key of ["tree", "page", "search"]) void qc.invalidateQueries({ queryKey: [...wikiQk.project(project), key] });
|
||||
// всё про проект разом: status (подзаголовок «обновлено …», появление дерева у проекта без синхронизаций), tree, page, search
|
||||
void qc.invalidateQueries({ queryKey: wikiQk.project(project) });
|
||||
},
|
||||
};
|
||||
|
||||
@ -398,7 +398,7 @@ describe("ActivityProvider", () => {
|
||||
await act(() => m.now().wiki.start());
|
||||
await waitFor(() => expect(m.now().wiki.event).toEqual({ kind: "batch-done", id: 7 }));
|
||||
const keys = spy.mock.calls.map(([f]) => (f as { queryKey: unknown[] }).queryKey);
|
||||
expect(keys).toEqual(expect.arrayContaining([["wiki", "AWPCA", "tree"], ["wiki", "AWPCA", "page"], ["wiki", "AWPCA", "search"], ["projects"]]));
|
||||
expect(keys).toEqual(expect.arrayContaining([["wiki", "AWPCA"], ["projects"]]));
|
||||
expect(keys.map((k) => k[0])).not.toContain("board");
|
||||
expect(keys.map((k) => k[0])).not.toContain("issues");
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user