Show map rankings for player personal records

This commit is contained in:
2026-10-08 00:32:32 -04:00
parent 3b270f79a7
commit 8de9247ff2
7 changed files with 108 additions and 6 deletions
+45
View File
@@ -0,0 +1,45 @@
import { expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
import { writable } from 'svelte/store';
import PlayerProfilePage from '../../src/routes/leaderboard/players/[guid]/+page.svelte';
import PlayerMapCards from '../../src/lib/ui/components/PlayerMapCards.svelte';
import type { PlayerMapRecord, PlayerProfile, RecordEvidence } from '../../src/lib/leaderboard.js';
vi.mock('$app/stores', () => ({ page: writable({
url: new URL('http://localhost/leaderboard/players/101?players=2'), data: { user: null }
}) }));
vi.mock('$app/navigation', () => ({ goto: vi.fn(), invalidateAll: vi.fn() }));
const evidence: RecordEvidence = { matchId: 71, game: 't5', mapKey: 't5:theater', mapName: 'Kino Der Toten',
server: 't5_zombie_theater_1', startedAt: '2026-10-06T12:00:00Z', endedAt: '2026-10-06T13:00:00Z',
startObserved: true, presentAtStart: true, firstObservedRound: 0, value: 22 };
const stats = { highestRound: 22, bestKills: 507, bestScore: 5290, kills: 722, roundsSurvived: 41,
headshots: 10, revives: 2, downs: 3, gamesPlayed: 9, gamesCompleted: 8 };
const map: PlayerMapRecord = { ...stats, game: 't5', key: 't5:theater', name: 'Kino Der Toten',
lastSeen: evidence.endedAt!, ranks: { highestRound: 7, bestKills: 12, bestScore: 3 },
records: { highestRound: evidence, bestKills: { ...evidence, matchId: 72, value: 507 },
bestScore: { ...evidence, matchId: 73, value: 5290 } } };
function expectRankedRecords(body: string) {
for (const [label, rank] of [['Best round', 7], ['Best kills', 12], ['Best score', 3]]) {
expect(body).toContain(`aria-label="Kino Der Toten ${label} rank ${rank}"`);
expect(body).toContain(`Rank #${rank}`);
}
for (const id of [71, 72, 73]) expect(body).toContain(`/matches/${id}?returnTo=`);
for (const value of ['22', '507', '5,290']) expect(body).toContain(`>${value}</a>`);
}
it('shows each record rank and preserves match links in mobile map cards', () => {
expectRankedRecords(render(PlayerMapCards, { props: { maps: [map], returnTo: '/leaderboard/players/101?players=2' } }).body);
});
it('shows the same ranks in the desktop profile with lifetime map scope explained', () => {
const profile: PlayerProfile = { guid: '101', name: 'Cherry', firstSeen: evidence.startedAt, lastSeen: evidence.endedAt!,
stats, records: map.records, maps: [map], matches: [], matchesTotal: 0, limit: 25, offset: 0 };
const body = render(PlayerProfilePage, { props: { data: { profile, returnTo: '/leaderboard',
scope: { game: '', map: '', players: '2', metric: 'kills', entry: null } } } }).body;
const table = body.slice(body.indexOf('<table'), body.indexOf('</table>'));
expectRankedRecords(table);
expect(body).toContain('Lifetime personal bests across all squad sizes, ranked against other players on each map.');
expect(body).toContain('Tied records share a rank.');
});