You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.3 KiB
TypeScript

// frontend/tests/notify/TriageStream.test.tsx — 탭 전환 · 액션 노출 · 빈/더보기 상태
import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { TriageStream } from "@/components/notify/TriageStream";
import type { Notification, NotifyBucket, Triage } from "@/lib/types";
function notif(over: Partial<Notification> & { id: string }): Notification {
return {
bucket: "now",
src: "mail",
app: "메일 · 회사",
title: "제목",
sum: "요약",
time: "09:12",
why: "VIP 발신자",
tone: "coral",
act: "답장 초안 보기",
...over,
};
}
const triage: Triage = {
now: [notif({ id: "n1", bucket: "now", title: "수아님 — 분기 리포트 피드백" })],
later: [notif({ id: "l1", bucket: "later", why: "다이제스트", tone: "violet", act: "" })],
held: [
notif({
id: "h2",
bucket: "held",
title: "회의 초대 자동 수락",
why: "빈 시간 일치",
tone: "green",
act: "",
}),
],
counts: { now: 6, later: 12, held: 29 },
stats: { total: 47, seen: 6, filtered: "87%" },
};
function renderWith(tab: NotifyBucket, onLater = vi.fn(), onUndo = vi.fn()) {
const setTab = vi.fn();
render(
<TriageStream triage={triage} tab={tab} setTab={setTab} onLater={onLater} onUndo={onUndo} />,
);
return { setTab, onLater, onUndo };
}
describe("TriageStream", () => {
it("탭 카운트 표시 (지금 6 / 나중에 12 / 아리가 처리 29)", () => {
renderWith("now");
expect(screen.getByText("6")).toBeInTheDocument();
expect(screen.getByText("12")).toBeInTheDocument();
expect(screen.getByText("29")).toBeInTheDocument();
});
it("탭 클릭 시 setTab 호출", () => {
const { setTab } = renderWith("now");
fireEvent.click(screen.getByText("나중에", { selector: ".nt-tab" }));
expect(setTab).toHaveBeenCalledWith("later");
});
it("now 탭에서 '나중에' 버튼 클릭 → onLater", () => {
const { onLater } = renderWith("now");
fireEvent.click(screen.getByText("나중에", { selector: ".nt-act" }));
expect(onLater).toHaveBeenCalledWith(expect.objectContaining({ id: "n1" }));
});
it("held 탭에서 '되돌리기' 버튼 클릭 → onUndo", () => {
const { onUndo } = renderWith("held");
fireEvent.click(screen.getByText("되돌리기"));
expect(onUndo).toHaveBeenCalledWith(expect.objectContaining({ id: "h2" }));
});
it("later 탭에서는 액션 버튼 없음 (나중에/되돌리기 미노출)", () => {
renderWith("later");
expect(screen.queryByText("되돌리기")).not.toBeInTheDocument();
expect(screen.queryByText("나중에", { selector: ".nt-act" })).not.toBeInTheDocument();
});
it("more>0 이면 nt-more 표시 (later: 12-1=11)", () => {
renderWith("later");
expect(screen.getByText(/비슷한 알림 \+11건/)).toBeInTheDocument();
});
it("빈 버킷이면 nt-empty 표시", () => {
const empty: Triage = { ...triage, now: [] };
const setTab = vi.fn();
render(
<TriageStream
triage={empty}
tab="now"
setTab={setTab}
onLater={() => {}}
onUndo={() => {}}
/>,
);
expect(screen.getByText(/오늘은 조용한 날이네요/)).toBeInTheDocument();
});
});