// @vitest-environment jsdom import { afterEach, describe, expect, it, vi } from "vitest"; import { AdoptionConsentModal } from "./AdoptionConsentModal"; import { flushView, inputText, renderView } from "../views/view-test-utils"; function button(container: HTMLElement, text: string): HTMLButtonElement { const found = Array.from(container.querySelectorAll("button")).find((b) => (b.textContent ?? "").includes(text), ); if (!found) throw new Error(`button not found: ${text}`); return found as HTMLButtonElement; } function mount(overrides: Partial[0]> = {}) { const props = { receiverDeviceName: "June's iPhone", sas: "89524517", verifyMasterPassword: vi.fn(async () => true), onCancel: vi.fn(), onApprove: vi.fn(async () => {}), ...overrides, }; const rendered = renderView(); return { ...rendered, props }; } describe("AdoptionConsentModal", () => { const cleanups: Array<() => void> = []; afterEach(() => { while (cleanups.length) cleanups.pop()!(); }); function mounted(overrides: Partial[0]> = {}) { const rendered = mount(overrides); cleanups.push(rendered.dispose); return rendered; } it("T-A16: renders receiver device name, consequence copy, and SAS code", () => { const { container } = mounted(); expect(container.textContent).toContain("June's iPhone"); expect(container.textContent).toContain("copies your entire vault including all passwords and Pro"); expect(container.textContent).toContain("89524517"); }); it("T-A17: Share vault button is disabled until a password is entered", () => { const { container } = mounted(); const share = button(container, "Share vault"); expect(share.disabled).toBe(true); inputText(container.querySelector("#adoption-consent-password") as HTMLInputElement, "pw"); expect(share.disabled).toBe(false); }); it("T-A18: wrong password shows inline error, clears the field, and does not approve", async () => { const { container, props } = mounted({ verifyMasterPassword: vi.fn(async () => false) }); const input = container.querySelector("#adoption-consent-password") as HTMLInputElement; inputText(input, "wrong"); button(container, "Share vault").click(); await flushView(); expect(container.textContent).toContain("Incorrect password"); expect(input.value).toBe(""); expect(document.activeElement).toBe(input); expect(props.onApprove).not.toHaveBeenCalled(); }); it("T-A19: correct password calls onApprove", async () => { const { container, props } = mounted({ verifyMasterPassword: vi.fn(async () => true) }); inputText(container.querySelector("#adoption-consent-password") as HTMLInputElement, "correct"); button(container, "Share vault").click(); await flushView(); expect(props.verifyMasterPassword).toHaveBeenCalledWith("correct"); expect(props.onApprove).toHaveBeenCalledTimes(1); }); it("T-A20: cancel closes without approval", () => { const { container, props } = mounted(); button(container, "Cancel").click(); expect(props.onCancel).toHaveBeenCalledTimes(1); expect(props.onApprove).not.toHaveBeenCalled(); }); });