// @vitest-environment jsdom import { afterEach, describe, expect, it, vi } from "vitest"; import { flushView, renderView } from "./view-test-utils"; import type { AdvancedHealthReport, VaultEntry } from "../../shared/types"; const sendMessageMock = vi.fn<(msg: unknown) => Promise>(); vi.mock("../App", () => ({ sendMessage: (msg: unknown) => sendMessageMock(msg), })); function entry(overrides: Partial = {}): VaultEntry { return { id: "entry-1", type: "login", title: "Example", username: "person@example.com", password: "correct-horse-battery-staple", url: "https://example.com/login", createdAt: Date.now() - 10_000, modifiedAt: Date.now() - 10_000, ...overrides, }; } describe("HealthView", () => { let dispose: (() => void) | undefined; afterEach(() => { dispose?.(); dispose = undefined; sendMessageMock.mockReset(); document.body.innerHTML = ""; }); it("opens the local entry editor from the Pro remediation queue", async () => { const report: AdvancedHealthReport = { vaultScore: 65, generatedAt: Date.now(), entryCount: 1, reusedGroups: 0, agedCount: 1, remediation: [ { id: "entry-1", title: "Example", domain: "example.com", url: "https://example.com/login", score: 65, ageDays: 200, reasons: ["200 days old"], factors: { breached: false, breachCount: 0, reused: false, aged: true, weak: false, missingTotpOnSensitive: false, }, }, ], }; sendMessageMock.mockResolvedValue({ ok: true, data: report }); const onFixEntry = vi.fn(); const { HealthView } = await import("./Health"); const mounted = renderView( , ); dispose = mounted.dispose; await flushView(); await flushView(); expect(mounted.container.textContent).toContain("Remediation queue"); expect(mounted.container.textContent).toContain("Example"); expect(mounted.container.textContent).not.toContain("Change password"); const button = mounted.container.querySelector(".peach-health-pro-row button"); expect(button?.textContent).toContain("Update"); button?.click(); expect(onFixEntry).toHaveBeenCalledWith(expect.objectContaining({ id: "entry-1" })); }); });