Files
electric-cherry/tests/unit/ui-moderation.test.ts
T
2026-10-15 21:33:50 -04:00

75 lines
2.9 KiB
TypeScript

import { afterEach, expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
import { writable } from 'svelte/store';
import ChatPanel from '../../src/lib/ui/components/ChatPanel.svelte';
import PlayerScoreboard from '../../src/lib/ui/components/PlayerScoreboard.svelte';
import { moderationHref } from '../../src/lib/ui/moderation.js';
import type { UserRole } from '../../src/lib/auth.js';
const currentPage = writable({
url: new URL('http://localhost/servers/t6_zm_transit_1'),
data: { user: { role: 'moderator' as UserRole } }
});
vi.mock('$app/stores', () => ({
page: {
subscribe: (run: Parameters<typeof currentPage.subscribe>[0]) => currentPage.subscribe(run)
}
}));
afterEach(() =>
currentPage.update((value) => ({ ...value, data: { user: { role: 'moderator' } } }))
);
it('keeps ambiguous engine chat IDs in search and preserves selected evidence for verified lookup', () => {
const body = render(ChatPanel, {
props: {
game: 't6',
history: [
{
type: 'message',
matchId: 12,
message: {
guid: 'abcdef',
player: 'Tank',
message: 'Review & investigate',
slot: 2,
time: '0:30'
},
context: { realTime: null, round: null, matchElapsedMs: null }
}
]
}
}).body;
const target = new URL(
body.match(/href="([^"]*\/moderation[^"]*)"/)![1].replaceAll('&amp;', '&'),
'http://localhost'
);
expect(target.searchParams.get('q')).toBe('abcdef');
expect(target.searchParams.has('guid')).toBe(false);
expect(target.searchParams.get('game')).toBe('t6');
expect(target.searchParams.get('matchId')).toBe('12');
expect(target.searchParams.get('message')).toBe('Review & investigate');
});
it('links scoreboard actions to the exact telemetry GUID and hides moderation from ordinary viewers', () => {
const props = {
report: {
server: 't6_zm_transit_1',
map: 'zm_transit',
event: 'game_start' as const,
receivedAt: '2026-10-15T12:00:00Z',
players: [{ guid: '18446744073709551615', name: 'Tank' }]
}
};
const body = render(PlayerScoreboard, { props }).body;
expect(body).toContain('guid=18446744073709551615');
expect(body).toContain('server=t6_zm_transit_1');
currentPage.update((value) => ({ ...value, data: { user: { role: 'viewer' } } }));
expect(render(PlayerScoreboard, { props }).body).not.toContain('/moderation?');
});
it('does not invent a game namespace for an unscoped profile', () => {
const target = new URL(moderationHref({ guid: '42', game: 'unknown' }), 'http://localhost');
expect(target.searchParams.get('guid')).toBe('42');
expect(target.searchParams.has('game')).toBe(false);
});