tftsr-devops_investigation/tests/unit/historyStore.test.ts
Shaun Arman 944b14e5c4
Some checks failed
Test / frontend-typecheck (push) Waiting to run
Test / frontend-tests (push) Waiting to run
Auto Tag / auto-tag (push) Successful in 4s
Test / rust-fmt-check (push) Successful in 1m7s
Release / build-macos-arm64 (push) Successful in 4m1s
Test / rust-clippy (push) Successful in 7m26s
Test / rust-tests (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
fix: dashboard shows — while loading, exposes errors, adds refresh button
Stat cards showed 0 immediately on mount because openCount was computed
from an empty issues array before the async loadIssues call resolved.
Now shows — during load, a red error banner if the backend call fails,
and a Refresh button. useEffect dependency changed to [] (fires once on
mount, not on every loadIssues reference check).
2026-03-31 08:55:05 -05:00

109 lines
3.4 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from "vitest";
import { invoke } from "@tauri-apps/api/core";
import { useHistoryStore } from "@/stores/historyStore";
import type { IssueSummary } from "@/lib/tauriCommands";
const mockInvoke = vi.mocked(invoke);
const makeIssue = (overrides: Partial<IssueSummary> = {}): IssueSummary => ({
id: "issue-001",
title: "Test issue",
severity: "P3",
status: "open",
category: "linux",
log_count: 0,
step_count: 0,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
...overrides,
});
describe("History Store", () => {
beforeEach(() => {
useHistoryStore.setState({ issues: [], isLoading: false, error: null, searchQuery: "" });
mockInvoke.mockReset();
});
it("loadIssues populates the issues array", async () => {
const issues = [makeIssue(), makeIssue({ id: "issue-002", title: "Another issue" })];
mockInvoke.mockResolvedValueOnce(issues);
await useHistoryStore.getState().loadIssues();
expect(useHistoryStore.getState().issues).toHaveLength(2);
expect(useHistoryStore.getState().isLoading).toBe(false);
});
it("loadIssues sets error on failure and clears isLoading", async () => {
mockInvoke.mockRejectedValueOnce(new Error("DB locked"));
await useHistoryStore.getState().loadIssues();
expect(useHistoryStore.getState().error).toContain("DB locked");
expect(useHistoryStore.getState().isLoading).toBe(false);
});
it("isLoading is true while fetching (stat cards must show — not 0)", async () => {
let resolve!: (v: unknown) => void;
mockInvoke.mockReturnValueOnce(new Promise((r) => (resolve = r)));
const p = useHistoryStore.getState().loadIssues();
expect(useHistoryStore.getState().isLoading).toBe(true);
resolve([makeIssue()]);
await p;
expect(useHistoryStore.getState().isLoading).toBe(false);
expect(useHistoryStore.getState().issues).toHaveLength(1);
});
it("open issue count includes status=open and status=triaging", () => {
useHistoryStore.setState({
issues: [
makeIssue({ status: "open" }),
makeIssue({ id: "002", status: "triaging" }),
makeIssue({ id: "003", status: "resolved" }),
makeIssue({ id: "004", status: "open" }),
],
});
const { issues } = useHistoryStore.getState();
const openCount = issues.filter(
(i) => i.status === "open" || i.status === "triaging"
).length;
expect(openCount).toBe(3);
});
it("newly created issue with status=open is counted as active", () => {
useHistoryStore.setState({ issues: [makeIssue({ status: "open" })] });
const { issues } = useHistoryStore.getState();
const openCount = issues.filter(
(i) => i.status === "open" || i.status === "triaging"
).length;
expect(openCount).toBe(1);
});
it("resolved issues are not counted as active", () => {
useHistoryStore.setState({
issues: [makeIssue({ status: "resolved" }), makeIssue({ id: "002", status: "resolved" })],
});
const { issues } = useHistoryStore.getState();
const openCount = issues.filter(
(i) => i.status === "open" || i.status === "triaging"
).length;
expect(openCount).toBe(0);
});
it("issue category field is present (not domain)", () => {
const issue = makeIssue({ category: "kubernetes" });
useHistoryStore.setState({ issues: [issue] });
const stored = useHistoryStore.getState().issues[0];
expect(stored.category).toBe("kubernetes");
});
});