Files
buzz-sheet/lib/analytics/model.test.ts
T
gunshiz 408ea8a219
CI / Verify (push) Successful in 2m0s
CI / Build immutable images and deploy (push) Successful in 3m47s
feat : update analis page
2026-10-11 20:35:00 +07:00

84 lines
4.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { rankAnalyticsItems, selectAnalytics, type AnalyticsItem, type PublicAnalytics } from "./model";
const item = (key: string, guideCount: number, stygianCount: number, name = key): AnalyticsItem => ({
key, name, imageUrl: null, rarity: null, guideCount, stygianCount,
contributions: [{ guideId: "g0", teamSignature: "guide-team", count: guideCount }, { guideId: "s0", teamSignature: "stygian-team", count: stygianCount }],
});
describe("analytics source selection", () => {
it("merges sources, changes order, and removes Stygian-only items when excluded", () => {
const items = [item("shared", 2, 5), item("guide", 4, 0), item("stygian", 0, 3)];
expect(rankAnalyticsItems(items, true).map(({ key, count }) => [key, count])).toEqual([
["shared", 7], ["guide", 4], ["stygian", 3],
]);
expect(rankAnalyticsItems(items, false).map(({ key, count }) => [key, count])).toEqual([
["guide", 4], ["shared", 2],
]);
expect(items[0].guideCount).toBe(2);
});
it("breaks ties by name and then key", () => {
expect(rankAnalyticsItems([item("z", 1, 0, "Alpha"), item("b", 1, 0, "Beta"), item("a", 1, 0, "Alpha")], true)
.map(({ key }) => key)).toEqual(["a", "z", "b"]);
});
it("updates every ranking and summary and handles empty sources", () => {
const entries = [item("shared", 2, 1), item("stygian", 0, 1)];
const data: PublicAnalytics = {
guides: [
...Array.from({ length: 5 }, (_, index) => ({ id: `g${index}`, source: "guide" as const, name: `Guide ${index}`, character: null })),
...Array.from({ length: 3 }, (_, index) => ({ id: `s${index}`, source: "stygian" as const, name: `Stygian ${index}`, character: null })),
],
teamGroups: [{ guideId: "g0", signature: "guide-team", count: 6 }, { guideId: "s0", signature: "stygian-team", count: 9 }],
guideCount: 5, stygianScheduleCount: 3, guideTeamCount: 6, stygianTeamCount: 9,
team: { character: entries, weapon: entries, artifact: entries },
recommendation: { weapon: entries, artifact: entries },
};
const included = selectAnalytics(data, true);
const excluded = selectAnalytics(data, false);
expect(included.teamCount).toBe(15);
expect(excluded.teamCount).toBe(6);
expect(excluded.stygianScheduleCount).toBe(0);
expect(excluded.guideCount).toBe(5);
for (const list of [...Object.values(excluded.team), ...Object.values(excluded.recommendation)]) {
expect(list.map(({ key, count }) => [key, count])).toEqual([["shared", 2]]);
}
expect(rankAnalyticsItems([], true)).toEqual([]);
expect(rankAnalyticsItems([item("unused", 0, 0)], false)).toEqual([]);
});
it("excludes guides before deduplicating and preserves per-member equipment counts", () => {
const entry: AnalyticsItem = {
...item("weapon", 7, 2),
contributions: [
{ guideId: "g1", teamSignature: "shared", count: 4 },
{ guideId: "g2", teamSignature: "shared", count: 2 },
{ guideId: "g2", teamSignature: "different-build", count: 1 },
{ guideId: "s1", teamSignature: "shared", count: 2 },
],
};
const recommendation = { ...entry, contributions: [{ guideId: "g1", teamSignature: null, count: 3 }, { guideId: "g2", teamSignature: null, count: 4 }] };
const data: PublicAnalytics = {
guides: [{ id: "g1", source: "guide", name: "One", character: null }, { id: "g2", source: "guide", name: "Two", character: null }, { id: "s1", source: "stygian", name: "Stygian", character: null }],
teamGroups: [{ guideId: "g1", signature: "shared", count: 2 }, { guideId: "g2", signature: "shared", count: 1 }, { guideId: "g2", signature: "different-build", count: 1 }, { guideId: "s1", signature: "shared", count: 1 }],
guideCount: 2, stygianScheduleCount: 1, guideTeamCount: 4, stygianTeamCount: 1,
team: { character: [], weapon: [entry], artifact: [] }, recommendation: { weapon: [recommendation], artifact: [] },
};
expect(selectAnalytics(data, true).team.weapon[0].count).toBe(9);
const unique = selectAnalytics(data, true, new Set(), true);
expect(unique.teamCount).toBe(2);
expect(unique.team.weapon[0].count).toBe(3);
expect(unique.recommendation.weapon[0].count).toBe(7);
const excluded = selectAnalytics(data, true, new Set(["g1"]), true);
expect(excluded.guideCount).toBe(1);
expect(excluded.team.weapon[0].count).toBe(3);
expect(excluded.recommendation.weapon[0].count).toBe(4);
expect(selectAnalytics(data, true, new Set(["g1", "g2"]), true).team.weapon[0].count).toBe(2);
const empty = selectAnalytics(data, false, new Set(["g1", "g2"]), true);
expect(empty.teamCount).toBe(0);
expect(empty.team.weapon).toEqual([]);
});
});