// frontend/tests/tasks/RiskRadar.test.tsx import { fireEvent, render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { RiskRadar } from "@/components/tasks/RiskRadar"; import type { Risk } from "@/lib/types"; const RISKS: Risk[] = [ { kind: "지연 위험", icon: "clock", tone: "coral", text: "**분기 리포트 초안 마무리** — 오늘(6/8) 마감인데 아직 진행 중이에요", task_id: "k1", cta: "작업 열기", }, { kind: "업무 쏠림", icon: "scale", tone: "amber", text: "미완료 작업 **9건**이 내게 몰려 있어요", task_id: null, cta: null, }, { kind: "의존성", icon: "link", tone: "violet", text: "**예산 섹션 작성**이(가) 늦어지면 함께 밀려요", task_id: "k1b", cta: "후속 작업 보기", }, ]; describe("RiskRadar", () => { it("risks=[] → null 렌더", () => { const { container } = render( {}} />); expect(container.querySelector(".rradar")).toBeNull(); }); it("3종 카드 tone 클래스", () => { const { container } = render( {}} />); expect(container.querySelector(".rr-item.t-coral")).toBeTruthy(); expect(container.querySelector(".rr-item.t-amber")).toBeTruthy(); expect(container.querySelector(".rr-item.t-violet")).toBeTruthy(); }); it("**굵게** → 변환 (dangerouslySetInnerHTML 미사용)", () => { const { container } = render( {}} />); const bolds = container.querySelectorAll(".rr-text b"); expect(bolds.length).toBeGreaterThan(0); expect([...bolds].some((b) => b.textContent === "분기 리포트 초안 마무리")).toBe(true); }); it("task_id 있으면 CTA, 클릭 시 onOpen", () => { const onOpen = vi.fn(); render(); fireEvent.click(screen.getByRole("button", { name: /작업 열기/ })); expect(onOpen).toHaveBeenCalledWith("k1"); }); it("업무 쏠림(task_id null)은 CTA 없음", () => { render( {}} />); // 작업 열기 / 후속 작업 보기 두 개만 (쏠림은 CTA 없음) expect(screen.queryByRole("button", { name: /몰려/ })).toBeNull(); }); });