import { render, screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { beforeEach, expect, test, vi } from "vitest"; import { fetchPlatformGrantRecords, fetchPlatformGrantUsers } from "../api.js"; import { createDashboardModel } from "../data/createDashboardModel.js"; import { ReportOverview } from "./ReportOverview.jsx"; vi.mock("../api.js", () => ({ fetchPlatformGrantRecords: vi.fn(), fetchPlatformGrantUsers: vi.fn() })); beforeEach(() => { vi.mocked(fetchPlatformGrantRecords).mockReset(); vi.mocked(fetchPlatformGrantUsers).mockReset(); }); test("shows daily totals first and expands daily country details on demand", async () => { const user = userEvent.setup(); const model = createDashboardModel({ country_breakdown: [ { country: "巴西", country_id: 86, active_users: 30, recharge_usd_minor: 30000 }, { country: "沙特", country_id: 966, active_users: 12, recharge_usd_minor: 12000 } ], daily_country_breakdown: [ { active_users: 10, country: "巴西", country_id: 86, recharge_usd_minor: 10000, stat_day: "2026-06-05" }, { active_users: 5, country: "沙特", country_id: 966, recharge_usd_minor: 5000, stat_day: "2026-06-05" }, { active_users: 20, country: "巴西", country_id: 86, recharge_usd_minor: 20000, stat_day: "2026-06-06" } ], daily_series: [ { active_users: 15, recharge_usd_minor: 15000, stat_day: "2026-06-05" }, { active_users: 20, recharge_usd_minor: 20000, stat_day: "2026-06-06" } ], recharge_usd_minor: 35000 }, { appCode: "lalu", countryId: 0, range: { end: "2026-06-06", start: "2026-06-05" } }); const { container } = render(); expect(screen.queryByText("巴西")).not.toBeInTheDocument(); expect(screen.queryByText("沙特")).not.toBeInTheDocument(); const stickyDateHeader = container.querySelector(".report-table--wide th.is-sticky-left"); expect(stickyDateHeader).toHaveTextContent("日期"); expect(screen.getByRole("columnheader", { name: "用户金币数" })).toBeInTheDocument(); expect(screen.getByRole("columnheader", { name: "产出金币" })).toBeInTheDocument(); expect(screen.getByRole("columnheader", { name: "消耗产出比" })).toBeInTheDocument(); expect(screen.queryByRole("columnheader", { name: "金币数量(总和)" })).not.toBeInTheDocument(); expect(container.querySelector(".report-table--wide td.is-sticky-left .report-date-cell")).toBeTruthy(); const june5Row = screen.getByRole("button", { name: "展开 2026-06-05 国家明细" }); expect(june5Row).toHaveAttribute("aria-expanded", "false"); await user.click(june5Row); expect(june5Row).toHaveAttribute("aria-expanded", "true"); const detailRows = within(screen.getByRole("table", { name: "2026-06-05 国家明细" })).getAllByRole("row"); expect(detailRows).toHaveLength(3); expect(container.querySelector(".report-subtable .is-sticky-left")).toBeNull(); expect(screen.getByText("巴西")).toBeInTheDocument(); expect(screen.getByText("沙特")).toBeInTheDocument(); await user.click(june5Row); expect(june5Row).toHaveAttribute("aria-expanded", "false"); expect(screen.queryByText("巴西")).not.toBeInTheDocument(); }); test("drills platform grant coin from total to country users and user records", async () => { const user = userEvent.setup(); vi.mocked(fetchPlatformGrantUsers).mockResolvedValue({ items: [{ display_user_id: "163001", last_granted_at_ms: Date.UTC(2026, 5, 5, 10, 20, 30), record_count: 2, total_coin: 55, user_id: "7001", username: "Ana" }], page: 1, pageSize: 20, total: 1 }); const taskRecord = { amount: 33, event_id: "grant:task:7001", event_type: "WalletTaskRewardCredited", occurred_at_ms: Date.UTC(2026, 5, 5, 10, 20, 30), user_id: "7001" }; const resourceRecord = { amount: 22, event_id: "grant:resource:7001", event_type: "WalletBalanceChanged", occurred_at_ms: Date.UTC(2026, 5, 5, 9, 20, 30), user_id: "7001" }; vi.mocked(fetchPlatformGrantRecords).mockResolvedValue({ items: [ taskRecord, resourceRecord ], page: 1, pageSize: 20, total: 2 }); const model = createDashboardModel({ country_breakdown: [ { country: "巴西", country_id: 86, platform_grant_coin: 55, region_id: 10 }, { country: "沙特", country_id: 966, platform_grant_coin: 12, region_id: 20 } ], daily_country_breakdown: [ { country: "巴西", country_id: 86, platform_grant_coin: 33, region_id: 10, stat_day: "2026-06-05" }, { country: "巴西", country_id: 86, platform_grant_coin: 22, region_id: 10, stat_day: "2026-06-06" }, { country: "沙特", country_id: 966, platform_grant_coin: 12, region_id: 20, stat_day: "2026-06-06" } ], daily_series: [ { platform_grant_coin: 33, stat_day: "2026-06-05" }, { platform_grant_coin: 34, stat_day: "2026-06-06" } ], platform_grant_coin: 67 }, { appCode: "lalu", countryId: 0, range: { end: "2026-06-06", start: "2026-06-05" } }); render( ); await user.click(screen.getByRole("button", { name: "查看 全部 平台发放金币国家明细" })); expect(screen.getByRole("dialog", { name: "平台发放金币" })).toBeInTheDocument(); await user.click(screen.getByRole("button", { name: "查看 巴西 平台发放金币用户明细" })); await waitFor(() => expect(fetchPlatformGrantUsers).toHaveBeenCalledWith(expect.objectContaining({ appCode: "lalu", countryId: 86, page: 1, pageSize: 20, regionId: 10, statTz: "Asia/Shanghai" }))); expect(await screen.findByRole("button", { name: "查看 163001 平台发放金币来源明细" })).toBeInTheDocument(); await user.click(screen.getByRole("button", { name: "查看 163001 平台发放金币来源明细" })); await waitFor(() => expect(fetchPlatformGrantRecords).toHaveBeenCalledWith(expect.objectContaining({ countryId: 86, page: 1, pageSize: 20, regionId: 10, userId: "7001" }))); expect(await screen.findByRole("cell", { name: "任务奖励" })).toBeInTheDocument(); expect(screen.getByRole("cell", { name: "资源发放" })).toBeInTheDocument(); await user.selectOptions(screen.getByLabelText("来源筛选"), "WalletTaskRewardCredited"); await waitFor(() => expect(fetchPlatformGrantRecords).toHaveBeenLastCalledWith(expect.objectContaining({ page: 1, pageSize: 20, source: "WalletTaskRewardCredited", userId: "7001" }))); });