import { afterEach, expect, test, vi } from "vitest"; import { fetchFilterOptions, fetchSocialBiFilterOptions, fetchSocialBiRequirements, fetchStatisticsOverview, getCurrentAppCode, getDefaultAppOptions, setCurrentAppCode } from "./api.js"; afterEach(() => { window.localStorage.clear(); vi.unstubAllGlobals(); }); test("stores the last selected databi app including all apps", () => { expect(getCurrentAppCode()).toBe("lalu"); expect(setCurrentAppCode("YUMI")).toBe("yumi"); expect(window.localStorage.getItem("hyapp-admin.app-code")).toBe("yumi"); expect(getCurrentAppCode()).toBe("yumi"); expect(setCurrentAppCode("")).toBe(""); expect(window.localStorage.getItem("hyapp-admin.app-code")).toBe(""); expect(getCurrentAppCode()).toBe(""); }); test("adds fixed databi app options without losing API apps", async () => { vi.stubGlobal( "fetch", vi.fn(async (input) => { const url = String(input); if (url.includes("/v1/admin/apps")) { return jsonResponse({ items: [{ appCode: "huwaa", appName: "Huwaa" }, { app_code: "lalu", name: "Lalu" }] }); } if (url.includes("/v1/admin/regions")) { return jsonResponse({ items: [] }); } if (url.includes("/v1/admin/countries")) { return jsonResponse({ items: [] }); } return jsonResponse(null, 404); }) ); const options = await fetchFilterOptions({ appCode: "lalu" }); expect(options.appOptions).toEqual([ { code: "", label: "全部", value: "" }, { code: "huwaa", label: "Huwaa", value: "huwaa" }, { code: "lalu", label: "Lalu", value: "lalu" }, { code: "aslan", label: "Aslan", value: "aslan" }, { code: "yumi", label: "Yumi", value: "yumi" } ]); }); test("provides static databi app options before filter API loads", () => { expect(getDefaultAppOptions()).toEqual([ { code: "", label: "全部", value: "" }, { code: "lalu", label: "Lalu", value: "lalu" }, { code: "aslan", label: "Aslan", value: "aslan" }, { code: "yumi", label: "Yumi", value: "yumi" } ]); }); test("loads social BI apps and operation users from admin APIs", async () => { vi.stubGlobal( "fetch", vi.fn(async (input) => { const url = String(input); if (url.includes("/v1/admin/apps")) { return jsonResponse({ items: [{ appCode: "huwaa", appName: "Huwaa" }] }); } if (url.includes("/v1/teams/2/users")) { return jsonResponse({ items: [{ account: "ava", id: 7, name: "Ava Chen", teamName: "运营一部" }] }); } return jsonResponse(null, 404); }) ); const options = await fetchSocialBiFilterOptions({ appCode: "lalu" }); expect(options.appOptions).toEqual([ { label: "全部 App", value: "all" }, { label: "Huwaa", value: "huwaa" }, { label: "Aslan", value: "aslan" }, { label: "Yumi", value: "yumi" } ]); expect(options.operatorOptions).toEqual([ { label: "全部人员", searchText: "all 全部人员", value: "all" }, { label: "Ava Chen", searchText: "ava chen ava 运营一部", value: "7" } ]); expect(String(fetch.mock.calls[1][0])).toContain("/api/v1/teams/2/users?"); expect(String(fetch.mock.calls[1][0])).toContain("status=active"); }); test("loads social BI requirements with section role and payer filters", async () => { vi.stubGlobal("fetch", vi.fn(async () => jsonResponse({ section: "revenue", total: { recharge_users: 2 } }))); const data = await fetchSocialBiRequirements({ appCodes: ["lalu", "huwaa"], endMs: 20, payerType: "paid", regionIds: [9, 11], section: "revenue", startMs: 10, statTz: "Asia/Shanghai", userRole: "host" }); const requestURL = new URL(String(fetch.mock.calls[0][0])); expect(requestURL.pathname).toBe("/api/v1/admin/databi/social/requirements"); expect(requestURL.searchParams.get("app_codes")).toBe("lalu,huwaa"); expect(requestURL.searchParams.get("section")).toBe("revenue"); expect(requestURL.searchParams.get("user_role")).toBe("host"); expect(requestURL.searchParams.get("payer_type")).toBe("paid"); expect(requestURL.searchParams.get("region_ids")).toBe("9,11"); expect(requestURL.searchParams.get("stat_tz")).toBe("Asia/Shanghai"); expect(data.total.recharge_users).toBe(2); }); test("omits app scope headers and query params for all databi apps", async () => { vi.stubGlobal("fetch", vi.fn(async () => jsonResponse({ updated_at_ms: 1 }))); await fetchStatisticsOverview({ appCode: "", countryId: 0, endMs: 2, regionId: "all", seriesEndMs: 2, seriesStartMs: 1, startMs: 1, statTz: "Asia/Shanghai" }); const [url, init] = fetch.mock.calls[0]; const requestURL = new URL(String(url)); expect(requestURL.searchParams.has("app_code")).toBe(false); expect(init.headers["X-App-Code"]).toBeUndefined(); }); function jsonResponse(data, status = 200) { return new Response(JSON.stringify({ code: status === 200 ? 0 : status, data, message: status === 200 ? "" : "error" }), { headers: { "content-type": "application/json" }, status }); }