hyapp-admin-platform/databi/src/data/createDashboardModel.test.js
2026-06-28 15:11:48 +08:00

183 lines
7.0 KiB
JavaScript

import { expect, test } from "vitest";
import { createDashboardModel } from "./createDashboardModel.js";
test("uses lucky gift pool breakdown to aggregate business metrics", () => {
const model = createDashboardModel({
lucky_gift_pools: [
{ payout_coin: 300, pool_id: "lucky_100", turnover_coin: 1_000 },
{ payout_coin: 50, pool_id: "super_lucky", turnover_coin: 500 }
],
lucky_gift_payout: 1,
lucky_gift_profit: 1,
lucky_gift_turnover: 1
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(model.luckyGiftPools).toEqual([
expect.objectContaining({ payout: 300, pool_id: "lucky_100", profit: 700, turnover: 1_000 }),
expect.objectContaining({ payout: 50, pool_id: "super_lucky", profit: 450, turnover: 500 })
]);
expect(metricValue(model, "幸运礼物流水")).toBe("1,500");
expect(metricValue(model, "幸运礼物返奖")).toBe("350");
expect(metricValue(model, "幸运礼物利润")).toBe("1,150");
expect(model.businessKpis.filter((item) => item.detailKey === "luckyGiftPools")).toHaveLength(3);
});
test("includes coin seller stock recharge in USD total and keeps seller transfer as coin metric", () => {
const model = createDashboardModel({
coin_seller_recharge_usd_minor: 200,
coin_seller_stock_coin: 400_000,
coin_seller_transfer_coin: 160_000,
salary_transfer_coin: 88_000,
country_breakdown: [
{
coin_seller_recharge_usd_minor: 200,
coin_seller_stock_coin: 400_000,
coin_seller_transfer_coin: 160_000,
country: "阿富汗",
google_recharge_usd_minor: 150,
recharge_usd_minor: 150,
salary_transfer_coin: 88_000
}
],
daily_series: [
{
coin_seller: 200,
google: 150,
label: "当前",
recharge_usd_minor: 150
}
],
google_recharge_usd_minor: 150,
recharge_usd_minor: 150
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(metricValue(model, "总充值")).toBe("$4");
expect(metricValue(model, "币商出货金币")).toBe("160,000");
expect(model.revenueSeries[0]).toEqual(expect.objectContaining({ coin_seller: 200, google: 150, lineTotal: 350, total: 350 }));
expect(model.countryBreakdown[0]).toEqual(expect.objectContaining({ coin_seller_stock_coin: 400_000, coin_seller_transfer_coin: 160_000, recharge_usd_minor: 350, salary_transfer_coin: 88_000 }));
});
test("exposes new user KPI and removes visitor stage from funnel", () => {
const model = createDashboardModel({
active_users: 80,
new_users: 12,
new_users_delta_rate: 0.24,
paid_users: 8,
recharge_users: 7
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(metricValue(model, "新增用户数")).toBe("12");
expect(model.kpis.map((item) => item.label)).toContain("新增用户数");
expect(model.funnel.map((item) => item.name)).toEqual(["活跃用户", "付费用户", "充值用户"]);
});
test("adds real-room robot gift metrics to a separate card row", () => {
const model = createDashboardModel({
real_room_robot_gift_room_count: 2,
real_room_robot_lucky_gift_coin: 200,
real_room_robot_normal_gift_coin: 100,
real_room_robot_super_gift_coin: 300
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(metricValue(model, "真人房机器人普通礼物")).toBe("100");
expect(metricValue(model, "真人房机器人幸运礼物")).toBe("200");
expect(metricValue(model, "真人房机器人超级幸运礼物")).toBe("300");
expect(metricValue(model, "真人房机器人房均礼物")).toBe("300");
expect(model.businessKpis.map((item) => item.label)).not.toContain("真人房机器人房均礼物");
expect(model.robotGiftKpis.find((item) => item.label === "真人房机器人房均礼物")?.caption).toBe("2 个房间");
});
test("uses active users as payer and recharge conversion denominator", () => {
const model = createDashboardModel({
active_users: 80,
country_breakdown: [
{
active_users: 20,
country: "巴西",
paid_users: 8,
recharge_users: 6,
recharge_usd_minor: 500
}
],
new_users: 4,
paid_users: 8,
recharge_users: 6
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(model.sideMetrics.find((item) => item.label === "付费转化率")?.value).toBe("10.00%");
expect(model.countryBreakdown[0]).toEqual(expect.objectContaining({
payer_rate: 0.4,
recharge_conversion_rate: 0.3
}));
});
test("uses registration count instead of legacy visitors in country breakdown", () => {
const model = createDashboardModel({
country_breakdown: [
{
country: "菲律宾",
new_users: 12,
visitors: 99
}
]
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-04", start: "2026-06-04" } });
expect(model.countryBreakdown[0]).toEqual(expect.objectContaining({
registrations: 12
}));
expect(model.countryBreakdown[0]).not.toHaveProperty("visitors");
});
test("builds report rows with range total, daily totals, and daily country rows", () => {
const model = createDashboardModel({
country_breakdown: [
{ country: "巴西", country_id: 86, active_users: 30, recharge_usd_minor: 300 }
],
daily_country_breakdown: [
{
active_users: 10,
coin_seller_stock_coin: 800,
coin_seller_transfer_coin: 500,
country: "巴西",
country_id: 86,
game_turnover: 300,
lucky_gift_turnover: 200,
recharge_usd_minor: 100,
salary_transfer_coin: 700,
stat_day: "2026-06-05",
super_lucky_gift_turnover: 80,
super_lucky_gift_payout: 20
},
{
active_users: 20,
country: "巴西",
country_id: 86,
recharge_usd_minor: 200,
stat_day: "2026-06-06"
}
],
daily_series: [
{ active_users: 10, label: "2026-06-05", recharge_usd_minor: 100, stat_day: "2026-06-05" },
{ active_users: 20, label: "2026-06-06", recharge_usd_minor: 200, stat_day: "2026-06-06" }
],
recharge_usd_minor: 300
}, { appCode: "lalu", countryId: 0, range: { end: "2026-06-06", start: "2026-06-05" } });
expect(model.reportCountryRows.map((row) => row.row_type)).toEqual(["total", "date_total", "country", "date_total", "country"]);
expect(model.reportCountryRows[0]).toEqual(expect.objectContaining({ country: "总计", date_label: "全部" }));
expect(model.reportCountryRows[1]).toEqual(expect.objectContaining({ country: "总计", date_label: "2026-06-05" }));
expect(model.reportCountryRows[2]).toEqual(expect.objectContaining({
coin_seller_stock_coin: 800,
coin_seller_transfer_coin: 500,
country: "巴西",
game_turnover: 300,
lucky_gift_turnover: 200,
salary_transfer_coin: 700,
super_lucky_gift_profit: 60
}));
});
function metricValue(model, label) {
return [...model.kpis, ...model.businessKpis, ...model.robotGiftKpis].find((item) => item.label === label)?.value;
}