test(web): правки по триажу финального ревью (T5.1, T5.2, T7.1, T8.1, M-4, M-5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fbc14f6366
commit
41f290c0e3
@ -1,5 +1,6 @@
|
|||||||
import { act, renderHook } from "@testing-library/react";
|
import { act, renderHook } from "@testing-library/react";
|
||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import { readPrefs } from "./storage.ts";
|
||||||
import type { BoardModel } from "./types.ts";
|
import type { BoardModel } from "./types.ts";
|
||||||
import { useBoardPrefs } from "./useBoardPrefs.ts";
|
import { useBoardPrefs } from "./useBoardPrefs.ts";
|
||||||
|
|
||||||
@ -18,10 +19,10 @@ describe("useBoardPrefs: два переключения в одном такт
|
|||||||
|
|
||||||
it("два toggle одного флага в одном такте возвращают исходное значение, в хранилище то же", () => {
|
it("два toggle одного флага в одном такте возвращают исходное значение, в хранилище то же", () => {
|
||||||
const { result } = renderHook(() => useBoardPrefs(model, "P"));
|
const { result } = renderHook(() => useBoardPrefs(model, "P"));
|
||||||
const before = result.current.snap, stored = JSON.stringify(localStorage);
|
const before = result.current.snap;
|
||||||
act(() => { result.current.toggle("snap"); result.current.toggle("snap"); });
|
act(() => { result.current.toggle("snap"); result.current.toggle("snap"); });
|
||||||
expect(result.current.snap).toBe(before);
|
expect(result.current.snap).toBe(before);
|
||||||
expect(JSON.stringify(localStorage)).toBe(stored === "{}" ? JSON.stringify(localStorage) : stored);
|
expect(readPrefs().snap).toBe(before);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("toggleHidden двух значений скрывает оба", () => {
|
it("toggleHidden двух значений скрывает оба", () => {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ describe("карточка задачи", () => {
|
|||||||
expect(screen.getByRole("link", { name: "AURORA-9002" }).closest(".issue")).not.toBeNull(); // O-10: цвет темы
|
expect(screen.getByRole("link", { name: "AURORA-9002" }).closest(".issue")).not.toBeNull(); // O-10: цвет темы
|
||||||
});
|
});
|
||||||
|
|
||||||
it("связь на ключ вне зеркала ведёт в Jira, а не в карточку (#103)", async () => {
|
it("связь на ключ вне зеркала ведёт в Jira, а не в карточку (#42 M-5)", async () => {
|
||||||
mockFetch((_m, url) => url.pathname === "/settings" ? json(200, settings) : json(200, issue("AURORA-9001", {
|
mockFetch((_m, url) => url.pathname === "/settings" ? json(200, settings) : json(200, issue("AURORA-9001", {
|
||||||
links_out: [{ target_key: "AURORA-1999", link_type: "ASUPR_Связанные", summary: null, status: null }], links_in: [],
|
links_out: [{ target_key: "AURORA-1999", link_type: "ASUPR_Связанные", summary: null, status: null }], links_in: [],
|
||||||
})));
|
})));
|
||||||
@ -84,7 +84,7 @@ describe("карточка задачи", () => {
|
|||||||
expect(link.closest("li")).toHaveTextContent("нет в зеркале");
|
expect(link.closest("li")).toHaveTextContent("нет в зеркале");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("«Прочие поля»: вид работы отдельно от меток (#42 M-5)", async () => {
|
it("«Прочие поля»: вид работы отдельно от меток (#103)", async () => {
|
||||||
mockFetch((_m, url) => url.pathname === "/settings" ? json(200, settings) : json(200, issue("AURORA-9001", { labels: ["AWPCA", "kind-dev"] })));
|
mockFetch((_m, url) => url.pathname === "/settings" ? json(200, settings) : json(200, issue("AURORA-9001", { labels: ["AWPCA", "kind-dev"] })));
|
||||||
open("/jira/issues/AURORA-9001");
|
open("/jira/issues/AURORA-9001");
|
||||||
await screen.findByRole("heading", { level: 2, name: "Тема AURORA-9001" });
|
await screen.findByRole("heading", { level: 2, name: "Тема AURORA-9001" });
|
||||||
|
|||||||
@ -117,7 +117,7 @@ describe("useAttachmentDownload", () => {
|
|||||||
|
|
||||||
it("failed при опросе — ошибка команды; повторное start сбрасывает ошибку", async () => {
|
it("failed при опросе — ошибка команды; повторное start сбрасывает ошибку", async () => {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
mockFetch((m) => m === "POST" ? json(200, st("fetching")) : json(200, ++n === 1 ? st("failed", { error: "Jira: 404", ok: false }) : st("fetching")));
|
mockFetch((m) => m === "POST" ? json(200, st("fetching")) : json(200, ++n === 1 ? st("failed", { error: "Jira: 404" }) : st("fetching")));
|
||||||
const { result } = renderHook(() => useAttachmentDownload("AURORA-1650"), { wrapper });
|
const { result } = renderHook(() => useAttachmentDownload("AURORA-1650"), { wrapper });
|
||||||
act(() => result.current.start(att));
|
act(() => result.current.start(att));
|
||||||
await flush();
|
await flush();
|
||||||
|
|||||||
@ -124,7 +124,7 @@ function useTracker(m: (typeof TRACKED)[number], { qc, project, pollMs, agents }
|
|||||||
}, [qc, status, setActiveNow]);
|
}, [qc, status, setActiveNow]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// #116: ответ обрабатывается, только если отслеживаемый пакет — тот же объект, что в activeRef (смена проекта обнуляет его синхронно)
|
// #116: ответ обрабатывается, только если отслеживаемый пакет — тот же объект, что в activeRef (эффект смены проекта объявлен выше и в том же коммите обнуляет activeRef)
|
||||||
if (!active || activeRef.current !== active) return;
|
if (!active || activeRef.current !== active) return;
|
||||||
const b = batch.data, e = batch.error;
|
const b = batch.data, e = batch.error;
|
||||||
if (b && b.id === active.id && !batch.isError) {
|
if (b && b.id === active.id && !batch.isError) {
|
||||||
|
|||||||
@ -339,11 +339,11 @@ describe("ActivityProvider", () => {
|
|||||||
|
|
||||||
it("#116: ответ опроса прежнего проекта, пришедший в коммите смены проекта, не возвращает событие", async () => {
|
it("#116: ответ опроса прежнего проекта, пришедший в коммите смены проекта, не возвращает событие", async () => {
|
||||||
const late = deferred<void>();
|
const late = deferred<void>();
|
||||||
let polls = 0;
|
let polls = 0, delivered = false;
|
||||||
hub({
|
hub({
|
||||||
...listing((mod, project) => (mod === "wiki" && project === "AWPCA" ? [item(9, "wiki")] : [])),
|
...listing((mod, project) => (mod === "wiki" && project === "AWPCA" ? [item(9, "wiki")] : [])),
|
||||||
"GET /batches/:id": async () => {
|
"GET /batches/:id": async () => {
|
||||||
if (++polls > 1) await late.promise; // первый ответ показан сразу, следующий держится до смены проекта
|
if (++polls > 1) { await late.promise; delivered = true; } // первый ответ показан сразу, следующий держится до смены проекта
|
||||||
return batch("running", { type: "wiki_sync" }, { id: 9, module: "wiki" });
|
return batch("running", { type: "wiki_sync" }, { id: 9, module: "wiki" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -352,6 +352,7 @@ describe("ActivityProvider", () => {
|
|||||||
await waitFor(() => expect(polls).toBeGreaterThanOrEqual(2)); // повторный опрос ушёл и висит
|
await waitFor(() => expect(polls).toBeGreaterThanOrEqual(2)); // повторный опрос ушёл и висит
|
||||||
// смена проекта и ответ опроса — одним коммитом: оба обновления копятся в act и рендерятся вместе на выходе из него
|
// смена проекта и ответ опроса — одним коммитом: оба обновления копятся в act и рендерятся вместе на выходе из него
|
||||||
await act(async () => { m.setProject("STOCKS_DRRK"); late.resolve(); await sleep(20); });
|
await act(async () => { m.setProject("STOCKS_DRRK"); late.resolve(); await sleep(20); });
|
||||||
|
expect(delivered).toBe(true); // отложенный ответ действительно ушёл в обработчик
|
||||||
await waitFor(() => expect(m.now().wiki.event).toBeNull());
|
await waitFor(() => expect(m.now().wiki.event).toBeNull());
|
||||||
await sleep(50);
|
await sleep(50);
|
||||||
expect(m.now().wiki.event).toBeNull();
|
expect(m.now().wiki.event).toBeNull();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user