// frontend/tests/proactive/ProactiveBanner.test.tsx import { fireEvent, render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { ProactiveBanner } from "@/components/proactive/ProactiveBanner"; import type { ProactiveCard } from "@/lib/types"; const PC_MEETING: ProactiveCard = { id: "pc1", kind: "schedule", icon: "cal", tone: "violet", title: "내일 미팅 3연속 — 점심 비워뒀어요", why: "10:00·11:00·13:00 연속, 12시 공백을 보호 블록으로 잡았어요", cta: "그대로 둘게요", action_kind: "focus_block", detected_at: "방금", status: "active", }; describe("ProactiveBanner", () => { it("카드: title/why/cta 렌더", () => { render(); expect(screen.getByText("내일 미팅 3연속 — 점심 비워뒀어요")).toBeInTheDocument(); expect(screen.getByText(/12시 공백/)).toBeInTheDocument(); expect(screen.getByRole("button", { name: "그대로 둘게요" })).toBeInTheDocument(); }); it("cta 클릭 → onAccept(id) 호출", () => { const onAccept = vi.fn(); render(); fireEvent.click(screen.getByRole("button", { name: "그대로 둘게요" })); expect(onAccept).toHaveBeenCalledWith("pc1"); }); it("닫기 버튼 → onDismiss(id) 호출", () => { const onDismiss = vi.fn(); render(); fireEvent.click(screen.getByRole("button", { name: "이 제안 닫기" })); expect(onDismiss).toHaveBeenCalledWith("pc1"); }); it("카드 없으면 배너 미표시", () => { const { container } = render( , ); expect(container.querySelector(".proactive")).toBeNull(); }); });