78 lines
5.1 KiB
TypeScript
78 lines
5.1 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import { MemoryRouter } from "react-router-dom";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("../auth/AuthContext", () => ({
|
|
useAuth: () => ({
|
|
user: { id: "admin-1", username: "admin", display_name: "管理员", role: "ADMIN" },
|
|
projects: [{ id: "project-1", name: "东门观光车", code: "EAST", status: "ENDED" }],
|
|
loading: false,
|
|
error: null,
|
|
login: vi.fn(),
|
|
logout: vi.fn(),
|
|
refresh: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock("../hooks/usePollingResource", () => ({
|
|
usePollingResource: (_loader: unknown, options: { enabled?: boolean; resourceKey?: string }) => {
|
|
const key = String(options.resourceKey ?? "");
|
|
if (!options.enabled) return { data: undefined, loading: false, refreshing: false, error: null, offline: false, lastClientSuccessAt: null, refresh: vi.fn() };
|
|
if (key.includes('"batches"')) return {
|
|
data: { items: [], page: 1, page_size: 20, total: 0, from: "2026-07-10", to: "2026-07-16" }, loading: false, refreshing: false, error: null, offline: false, lastClientSuccessAt: new Date().toISOString(), refresh: vi.fn(),
|
|
};
|
|
if (key.includes('"summary"')) return {
|
|
data: {
|
|
from: "2026-07-10", to: "2026-07-16",
|
|
summary: { total_tickets: 1, total_people: 3, called_tickets: 1, called_people: 3, completed_tickets: 1, completed_people: 3, missed_tickets: 0, canceled_tickets: 0, completion_rate: 1, missed_rate: 0, canceled_rate: 0, average_wait_seconds: 120, max_wait_seconds: 120 },
|
|
hourly: [{ hour: 10, issued_tickets: 1, issued_people: 3, called_tickets: 1, called_people: 3 }],
|
|
peak_hours: [{ rank: 1, hour: 10, issued_tickets: 1, issued_people: 3, called_tickets: 1, called_people: 3 }],
|
|
daily: [{ business_date: "2026-07-16", total_tickets: 1, total_people: 3, called_tickets: 1, completed_tickets: 1, missed_tickets: 0, canceled_tickets: 0, completion_rate: 1, missed_rate: 0, canceled_rate: 0, average_wait_seconds: 120, max_wait_seconds: 120 }],
|
|
projects: [{ project_id: "project-1", project_name: "东门观光车", total_tickets: 1, total_people: 3, called_tickets: 1, completed_tickets: 1, missed_tickets: 0, canceled_tickets: 0, completion_rate: 1, missed_rate: 0, canceled_rate: 0, average_wait_seconds: 120, max_wait_seconds: 120 }],
|
|
}, loading: false, refreshing: false, error: null, offline: false, lastClientSuccessAt: new Date().toISOString(), refresh: vi.fn(),
|
|
};
|
|
return {
|
|
data: { items: [{ id: "ticket-1", project_id: "project-1", project_name: "东门观光车", queue_session_id: "session-1", business_date: "2026-07-16", ticket_number: "00012", party_size: 3, status: "COMPLETED", joined_at: "2026-07-16T09:00:00Z", called_at: "2026-07-16T09:02:00Z", wait_seconds: 120, phone_masked: "****8000", personal_data_status: "AVAILABLE" }], page: 1, page_size: 20, total: 1, from: "2026-07-10", to: "2026-07-16" }, loading: false, refreshing: false, error: null, offline: false, lastClientSuccessAt: new Date().toISOString(), refresh: vi.fn(),
|
|
};
|
|
},
|
|
}));
|
|
|
|
vi.mock("../api", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("../api")>();
|
|
return { ...actual, api: { adminHistoryExport: vi.fn().mockResolvedValue(new Blob(["号码"])), adminHistoryTicket: vi.fn(), adminHistoryBatch: vi.fn() } };
|
|
});
|
|
|
|
import { HistoryPage } from "./HistoryPage";
|
|
|
|
afterEach(() => vi.restoreAllMocks());
|
|
|
|
describe("HistoryPage", () => {
|
|
it("默认展示排队历史并支持切换运营统计", () => {
|
|
render(<MemoryRouter initialEntries={["/admin/history"]}><HistoryPage /></MemoryRouter>);
|
|
|
|
expect(screen.getByRole("heading", { name: "历史数据" })).toBeVisible();
|
|
expect(screen.getByRole("tab", { name: "排队记录" })).toHaveAttribute("aria-selected", "true");
|
|
expect(screen.getByRole("row", { name: /东门观光车/ })).toBeVisible();
|
|
expect(screen.getByText("00012")).toBeVisible();
|
|
expect(screen.getByText("****8000")).toBeVisible();
|
|
|
|
fireEvent.click(screen.getByRole("tab", { name: "运营统计" }));
|
|
expect(screen.getByRole("tab", { name: "运营统计" })).toHaveAttribute("aria-selected", "true");
|
|
expect(screen.getByLabelText("历史数据筛选条件")).toHaveClass("history-filters--summary");
|
|
expect(screen.getByText("经营复盘")).toBeVisible();
|
|
expect(screen.getByText("总人数 3 人")).toBeVisible();
|
|
expect(screen.getByText("每日趋势")).toBeVisible();
|
|
expect(screen.getByText("完成量")).toBeVisible();
|
|
expect(screen.queryByRole("img", { name: "每日取号量与完成量趋势图" })).not.toBeInTheDocument();
|
|
expect(screen.getByText("项目对比")).toBeVisible();
|
|
expect(screen.getByText("高峰时段")).toBeVisible();
|
|
expect(screen.getByText("小时分布")).toBeVisible();
|
|
expect(screen.queryByText("需要关注")).not.toBeInTheDocument();
|
|
expect(screen.getAllByText("平均等待").length).toBeGreaterThan(0);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "下钻" }));
|
|
expect(screen.getByRole("tab", { name: "排队记录" })).toHaveAttribute("aria-selected", "true");
|
|
expect(screen.getByRole("combobox", { name: "项目" })).toHaveValue("project-1");
|
|
});
|
|
});
|