Add Prettier and ESLint tooling (Refs #77)

This commit is contained in:
2026-10-09 15:56:13 -04:00
parent 8ed059b8d3
commit 16469e2d43
711 changed files with 99737 additions and 28286 deletions
+66 -16
View File
@@ -8,9 +8,21 @@ import { fleet } from '../../src/lib/ui/stores/fleet.js';
import type { AuthUser } from '../../src/lib/auth.js';
const currentPage = writable({ url: new URL('http://localhost/campaigns/42'), data: {} });
vi.mock('$app/stores', () => ({ page: { subscribe: (run: Parameters<typeof currentPage.subscribe>[0]) => currentPage.subscribe(run) } }));
vi.mock('$app/navigation', () => ({ goto: vi.fn(), beforeNavigate: vi.fn(), afterNavigate: vi.fn(), onNavigate: vi.fn() }));
afterEach(() => { fleet.set({ servers: [], operations: [], receivedAt: 0 }); currentPage.set({ url: new URL('http://localhost/campaigns/42'), data: {} }); });
vi.mock('$app/stores', () => ({
page: {
subscribe: (run: Parameters<typeof currentPage.subscribe>[0]) => currentPage.subscribe(run)
}
}));
vi.mock('$app/navigation', () => ({
goto: vi.fn(),
beforeNavigate: vi.fn(),
afterNavigate: vi.fn(),
onNavigate: vi.fn()
}));
afterEach(() => {
fleet.set({ servers: [], operations: [], receivedAt: 0 });
currentPage.set({ url: new URL('http://localhost/campaigns/42'), data: {} });
});
describe('sidebar navigation', () => {
it('exposes every allowed page in one navigation and marks the current page', () => {
@@ -26,27 +38,65 @@ describe('sidebar navigation', () => {
});
it('does not show invented attention counts before the fleet snapshot loads', () => {
expect(render(Navigation, { props: { role: 'admin' } }).body).not.toMatch(/needs? attention/);
fleet.set({ receivedAt: Date.now(), operations: [], servers: [{
name: 't5_zombie_theater_1', game: 't5', map: 'zombie_theater', last_players: null,
last_map: null, last_gametype: null, last_seen_at: null, last_error: null, roster: [],
health: 'offline', held: [], active_since: null, inactive_since: null, game_started_at: null, game_ended_at: null
}] });
expect(render(Navigation, { props: { role: 'admin' } }).body).toContain('aria-label="Servers, 1 needs attention"');
expect(render(Navigation, { props: { role: 'admin' } }).body).not.toMatch(
/needs? attention/
);
fleet.set({
receivedAt: Date.now(),
operations: [],
servers: [
{
name: 't5_zombie_theater_1',
game: 't5',
map: 'zombie_theater',
last_players: null,
last_map: null,
last_gametype: null,
last_seen_at: null,
last_error: null,
roster: [],
health: 'offline',
held: [],
active_since: null,
inactive_since: null,
game_started_at: null,
game_ended_at: null
}
]
});
expect(render(Navigation, { props: { role: 'admin' } }).body).toContain(
'aria-label="Servers, 1 needs attention"'
);
});
it('counts hosts without servers and clears the badge when the next host summary is healthy', () => {
fleet.set({ receivedAt: Date.now(), operations: [], servers: [], hostAttention: 2 });
expect(render(Navigation, { props: { role: 'admin' } }).body).toContain('aria-label="Hosts, 2 need attention"');
fleet.update(value => ({ ...value, hostAttention: 0 }));
expect(render(Navigation, { props: { role: 'admin' } }).body).not.toMatch(/aria-label="Hosts, \d/);
expect(render(Navigation, { props: { role: 'admin' } }).body).toContain(
'aria-label="Hosts, 2 need attention"'
);
fleet.update((value) => ({ ...value, hostAttention: 0 }));
expect(render(Navigation, { props: { role: 'admin' } }).body).not.toMatch(
/aria-label="Hosts, \d/
);
});
});
const user: AuthUser = { id: '1', username: 'operator', displayName: 'Operator', role: 'operator', disabled: false,
mustChangePassword: false, createdAt: '', updatedAt: '', lastLoginAt: null };
const user: AuthUser = {
id: '1',
username: 'operator',
displayName: 'Operator',
role: 'operator',
disabled: false,
mustChangePassword: false,
createdAt: '',
updatedAt: '',
lastLoginAt: null
};
const children = createRawSnippet(() => ({ render: () => '<h1>Page content</h1>' }));
const shell = (overrides: Partial<AuthUser> = {}) => render(Layout, { props: { children, data: { user: { ...user, ...overrides }, setupRequired: false } } }).body;
const shell = (overrides: Partial<AuthUser> = {}) =>
render(Layout, {
props: { children, data: { user: { ...user, ...overrides }, setupRequired: false } }
}).body;
describe('application shell', () => {
it('offers collapsible desktop navigation, a labelled mobile drawer, search and help', () => {