Add unique and new player metrics (Refs #142)
CI / checks (push) Successful in 4m53s

This commit is contained in:
2026-10-10 18:47:56 -04:00
parent 7fcf1cded2
commit e3e740cea3
16 changed files with 1212 additions and 3 deletions
+26
View File
@@ -99,6 +99,32 @@ it('refreshes cached match metrics after active matches and recorded participant
expect((await report()).scopeOptions).toEqual({ games: [], maps: [] });
});
it('refreshes player trends when participation crosses a period and first-seen identity changes', async () => {
const { db } = await import('../../src/lib/server/db/index.js');
const { metricsReport } = await import('../../src/lib/server/reports/index.js');
const now = Date.UTC(2026, 9, 10, 12, 30);
vi.spyOn(Date, 'now').mockReturnValue(now);
const query = parseMetricsQuery(new URLSearchParams('days=1'));
db().exec(`INSERT INTO leaderboard_matches
(id,server,game,map,map_key,map_name,started_at,last_received_at,last_event,last_fingerprint)
VALUES(1,'removed','t5','moon','moon','Moon','2026-10-10T11:30:00.000Z','2026-10-10T12:30:00.000Z','heartbeat','test');
INSERT INTO leaderboard_match_players(match_id,guid,first_seen_at,last_seen_at)
VALUES(1,'player','2026-10-10T11:30:00.000Z','2026-10-10T11:59:00.000Z');
INSERT INTO leaderboard_players(game,guid,name,first_seen_at,last_seen_at)
VALUES('t5','player','Player','2026-10-10T11:30:00.000Z','2026-10-10T11:59:00.000Z');`);
const first = await metricsReport(query);
expect(first.players).toMatchObject({ uniquePlayers: 1, newPlayers: 1 });
expect(first.points.at(-1)).toMatchObject({ uniquePlayers: 0, newPlayers: 0 });
db().exec("UPDATE leaderboard_match_players SET last_seen_at='2026-10-10T12:15:00.000Z'");
expect((await metricsReport(query)).points.at(-1)).toMatchObject({
uniquePlayers: 1,
newPlayers: 0
});
db().exec(`INSERT INTO leaderboard_players(game,guid,name,first_seen_at,last_seen_at)
VALUES('t6','player','Player','2026-10-01T11:30:00.000Z','2026-10-01T11:30:00.000Z')`);
expect((await metricsReport(query)).players).toMatchObject({ uniquePlayers: 1, newPlayers: 0 });
});
it('refreshes policy signals after policy edits and global pauses without new samples', async () => {
const { db } = await import('../../src/lib/server/db/index.js');
const { recordMetrics } = await import('../../src/lib/server/fleet/metrics.js');