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.

141 lines
4.6 KiB
TypeScript

// frontend/tests/calendar/MeetDrawer.test.tsx — 회의 도우미 4상태 렌더 + 액션 왕복
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { expect, test, vi } from "vitest";
import { MeetDrawer } from "@/components/calendar/MeetDrawer";
import { calendarApi } from "@/lib/calendar/api";
vi.mock("@/lib/calendar/api");
const ev = {
id: "e3",
title: "팀 데일리 스탠드업",
start: "09:30",
end: "09:45",
loc: "Zoom",
} as never;
const cal = { id: "team", name: "팀", tone: "green", on: true, count: 4 } as never;
test("done 회의: 요약·결정·액션 + 작업으로", async () => {
(calendarApi.meeting as never as ReturnType<typeof vi.fn>).mockResolvedValue({
id: "e3",
phase: "done",
one_on_one: false,
meta: "...",
summary: ["s1"],
decisions: ["d1"],
actions: [
{
idx: 2,
text: "매출 데이터 전달",
who: "현우",
when: "오늘",
added: false,
materialized_task_id: null,
},
],
agenda: [],
last_meeting: {},
last_actions: [],
insights: [],
docs: [],
person: {},
promises: [],
signals: [],
talking_points: [],
starts_in: "",
});
(calendarApi.materialize as never as ReturnType<typeof vi.fn>).mockResolvedValue({
action: {},
task: {},
all_added: true,
});
render(<MeetDrawer ev={ev} cal={cal} onClose={() => {}} />);
expect(await screen.findByText("회의 노트 정리됨")).toBeInTheDocument();
expect(screen.getByText("매출 데이터 전달")).toBeInTheDocument();
// "작업으로" 행 버튼 (전체 보내기 버튼 "…모두 작업으로 보내기" 와 구분)
fireEvent.click(screen.getByRole("button", { name: "작업으로" }));
await waitFor(() => expect(calendarApi.materialize).toHaveBeenCalledWith("e3", 2));
});
test("upcoming: 안건·지난액션·인사이트·docs", async () => {
(calendarApi.meeting as never as ReturnType<typeof vi.fn>).mockResolvedValue({
id: "e6",
phase: "upcoming",
one_on_one: false,
starts_in: "2시간 50분 후 시작",
agenda: ["Q2 핵심 지표 리뷰 — 리텐션 · 매출"],
docs: ["분기 리포트 초안 · 75%"],
insights: ["리텐션 KPI가 전분기 대비 <b>+6%p</b>"],
last_actions: [{ text: "x", who: "나", done: false }],
last_meeting: { when: "지난주 월", note: "n" },
summary: [],
decisions: [],
actions: [],
person: {},
promises: [],
signals: [],
talking_points: [],
meta: "",
});
render(
<MeetDrawer ev={{ ...ev, id: "e6", title: "분기 전략 미팅" }} cal={cal} onClose={() => {}} />,
);
expect(await screen.findByText("2시간 50분 후 시작")).toBeInTheDocument();
expect(screen.getByText(/Q2 핵심 지표 리뷰/)).toBeInTheDocument();
expect(screen.getByText(/분기 리포트 초안 · 75%/)).toBeInTheDocument();
});
test("live: 기록 중 배지", async () => {
(calendarApi.meeting as never as ReturnType<typeof vi.fn>).mockResolvedValue({
id: "e4",
phase: "live",
one_on_one: false,
summary: ["논의1"],
decisions: [],
actions: [
{ idx: 0, text: "a", who: "나", when: "내일", added: false, materialized_task_id: null },
],
agenda: [],
last_meeting: {},
last_actions: [],
insights: [],
docs: [],
person: {},
promises: [],
signals: [],
talking_points: [],
meta: "",
starts_in: "",
});
render(<MeetDrawer ev={{ ...ev, id: "e4" }} cal={cal} onClose={() => {}} />);
expect(await screen.findByText("기록 중")).toBeInTheDocument();
});
test("1:1: 약속·시그널·대화 주제", async () => {
(calendarApi.meeting as never as ReturnType<typeof vi.fn>).mockResolvedValue({
id: "e7",
phase: "upcoming",
one_on_one: true,
starts_in: "오늘 16:30",
person: { name: "민서", initial: "민", tone: "green" },
promises: [{ text: "강의 지원 품의", done: false }],
signals: [{ k: "업무량", v: "진행 4건", tone: "amber" }],
talking_points: ["전처리 과제에서 막히는 부분이 있는지"],
last_meeting: { when: "5월 25일", note: "n" },
summary: [],
decisions: [],
agenda: [],
last_actions: [],
insights: [],
docs: [],
actions: [],
meta: "",
});
render(
<MeetDrawer ev={{ ...ev, id: "e7", title: "1:1 — 민서님" }} cal={cal} onClose={() => {}} />,
);
expect(await screen.findByText("1:1 어시스턴트")).toBeInTheDocument();
expect(screen.getByText("민서님 시그널")).toBeInTheDocument();
expect(screen.getByText("전처리 과제에서 막히는 부분이 있는지")).toBeInTheDocument();
});