import { expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
import { writable } from 'svelte/store';
import { get } from 'svelte/store';
import type { ComponentProps } from 'svelte';
import type { GameTelemetry } from '../../src/lib/telemetry.js';
import type { FleetOperation } from '../../src/lib/fleet-overview.js';
import ServerPage from '../../src/routes/servers/[name]/+page.svelte';
import PlayerScoreboard from '../../src/lib/ui/components/PlayerScoreboard.svelte';
import ConfigInspector from '../../src/lib/ui/components/ConfigInspector.svelte';
import { uiNow } from '../../src/lib/ui/stores/servers.js';
import { instanceActivity } from '../../src/lib/ui/server-activity.js';
import { gameEvent } from '../helpers/telemetry.js';
import { page } from '$app/stores';
vi.mock('$app/state', () => ({ page: { url: new URL('http://localhost/servers/t5_zombie_theater_1') } }));
vi.mock('$app/stores', () => ({ page: writable({ params: { name: 't5_zombie_theater_1' }, url: new URL('http://localhost/servers/t5_zombie_theater_1') }) }));
vi.mock('$app/navigation', () => ({ beforeNavigate: vi.fn(), afterNavigate: vi.fn(), goto: vi.fn() }));
const report = (current = true): GameTelemetry => {
const receivedAt = new Date(get(uiNow) - (current ? 10_000 : 300_000)).toISOString();
const joined = new Date(Date.parse(receivedAt) - 60_000).toISOString();
return { ...gameEvent('heartbeat', 4, 1), receivedAt, timing: { matchId: 1, players: {
'12345678901234560': { serverJoinedAt: joined, matchJoinedAt: joined, roundStarted: 1 }
} } };
};
it('keeps scoreboard columns focused and collapses player identifiers and timings', () => {
const body = render(PlayerScoreboard, { props: { report: report(), matchElapsed: '4m 19s' } }).body;
expect(body).toContain('Live scoreboard');
expect(body).toContain('Round 4');
expect(body).toContain('Match 4m 19s');
expect(body).toContain('aria-expanded="false"');
expect(body).toMatch(/
]*hidden/);
expect(body).toContain('Time on instance: 1m 10s');
expect(body).toContain('aria-label="Copy GUID for Player 1"');
expect(body).not.toContain('>Time on server');
expect(body).not.toContain('>Round started');
expect(body).toContain('aria-sort="descending"');
expect(body).toContain('About these stats');
});
it('freezes historical timing and keeps unreported scores distinct from zero', () => {
const body = render(PlayerScoreboard, { props: { report: report(false) } }).body;
expect(body).toContain('Last reported scoreboard');
expect(body).toContain('in last report');
expect(body).toContain('Time on instance: 1m 00s');
expect(body).not.toContain('Time on instance: 6m');
const start = { ...gameEvent('game_start', 0, 1), receivedAt: report().receivedAt };
expect(render(PlayerScoreboard, { props: { report: start } }).body).toContain('aria-label="Not yet reported"');
});
it('omits the fixed instance selector while keeping promoted/live distinction', () => {
const body = render(ConfigInspector, { props: { fixedServer: 't5_zombie_theater_1' } }).body;
expect(body).not.toContain('