Files
electric-cherry/tests/unit/ui-read-only-releases.test.ts
T
2026-10-11 23:30:40 -04:00

85 lines
3.2 KiB
TypeScript

import { afterEach, expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
import { writable } from 'svelte/store';
import type { UserRole } from '../../src/lib/auth.js';
import Scripts from '../../src/routes/scripts/+page.svelte';
import Plugins from '../../src/routes/plugins/+page.svelte';
import ConfigLibrary from '../../src/lib/ui/components/ConfigLibrary.svelte';
import ConfigEditor from '../../src/lib/ui/components/ConfigEditor.svelte';
import ConfigTextEditor from '../../src/lib/ui/components/ConfigTextEditor.svelte';
const currentPage = writable({
url: new URL('http://localhost/scripts'),
data: { user: { role: 'super_viewer' as UserRole } }
});
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()
}));
afterEach(() =>
currentPage.update((value) => ({
...value,
data: { user: { role: 'super_viewer' } }
}))
);
it.each(['super_viewer', 'viewer'] as const)(
'keeps release libraries browsable without upload or creation controls for %s',
(role) => {
currentPage.update((value) => ({ ...value, data: { user: { role } } }));
const scripts = render(Scripts).body;
expect(scripts).toContain('Search scripts');
expect(scripts).not.toContain('Upload scripts');
const plugins = render(Plugins).body;
expect(plugins).toContain('Filter plugins by game');
expect(plugins).not.toContain('Add plugin');
const configs = render(ConfigLibrary).body;
expect(configs).toContain('Inspect a server');
expect(configs).toContain('Refresh');
expect(configs).not.toContain('New config');
}
);
it.each(['operator', 'admin'] as const)('preserves release creation controls for %s', (role) => {
currentPage.update((value) => ({ ...value, data: { user: { role } } }));
expect(render(Scripts).body).toContain('Upload scripts');
expect(render(Plugins).body).toContain('Add plugin');
expect(render(ConfigLibrary).body).toContain('New config');
});
it('shows a configuration viewer and version selection without importing or restoring edits', () => {
const body = render(ConfigEditor, {
props: {
id: 1,
kind: 'config',
versions: [{ id: 1, version: 1, notes: null }],
currentVersionId: 1,
runningBetaId: null,
scopeType: 'game',
scopeValue: 't5',
onsaved: vi.fn()
}
}).body;
expect(body).toContain('Configuration viewer');
expect(body).toContain('Starting version');
expect(body).not.toContain('Import .cfg');
expect(body).not.toContain('Save new version');
});
it('keeps readonly configuration text selectable and its view switch enabled', () => {
const body = render(ConfigTextEditor, {
props: { text: 'set g_inactivity "0"', readonly: true }
}).body;
expect(body).toMatch(/<textarea[^>]*readonly/);
expect(body).not.toMatch(/<textarea[^>]*disabled/);
expect(body).not.toMatch(/<button[^>]*disabled/);
expect(body).toContain('Raw .cfg');
expect(body).toContain('Settings');
});