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
+110 -39
View File
@@ -3,8 +3,13 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { newFixture, type Fixture } from '../helpers/fixture.js';
let fixture: Fixture;
beforeEach(async () => { vi.resetModules(); fixture = await newFixture([]); });
afterEach(async () => { await fixture.cleanup(); });
beforeEach(async () => {
vi.resetModules();
fixture = await newFixture([]);
});
afterEach(async () => {
await fixture.cleanup();
});
describe('server detail data', () => {
it('filters history before the global limit and includes the matching campaign members', async () => {
@@ -12,58 +17,124 @@ describe('server detail data', () => {
const handle = db();
handle.exec("INSERT INTO servers (name) VALUES ('target'), ('other')");
handle.transaction(() => {
const deployment = handle.prepare("INSERT INTO deployments (id, action, started_at) VALUES (?, 'promote', ?)");
const member = handle.prepare("INSERT INTO deployment_servers (deployment_id, server, files_changed, restart_state) VALUES (?, ?, 1, 'done')");
const deployment = handle.prepare(
"INSERT INTO deployments (id, action, started_at) VALUES (?, 'promote', ?)"
);
const member = handle.prepare(
"INSERT INTO deployment_servers (deployment_id, server, files_changed, restart_state) VALUES (?, ?, 1, 'done')"
);
deployment.run('older-target', '2026-01-01');
member.run('older-target', 'target'); member.run('older-target', 'other');
for (let n = 0; n < 501; n++) { deployment.run('other-' + n, '2026-09-18'); member.run('other-' + n, 'other'); }
member.run('older-target', 'target');
member.run('older-target', 'other');
for (let n = 0; n < 501; n++) {
deployment.run('other-' + n, '2026-09-18');
member.run('other-' + n, 'other');
}
})();
const { GET } = await import('../../src/routes/api/campaigns/+server.js');
const all = await (await GET({ url: new URL('http://localhost/api/campaigns?limit=500') })).json();
const all = await (
await GET({ url: new URL('http://localhost/api/campaigns?limit=500') })
).json();
expect(all.deployments).toHaveLength(500);
const first = await (await GET({ url: new URL('http://localhost/api/campaigns?limit=25') })).json();
const second = await (await GET({ url: new URL('http://localhost/api/campaigns?limit=25&offset=25') })).json();
const first = await (
await GET({ url: new URL('http://localhost/api/campaigns?limit=25') })
).json();
const second = await (
await GET({ url: new URL('http://localhost/api/campaigns?limit=25&offset=25') })
).json();
expect(first.total).toBe(502);
expect(first.deployments).toHaveLength(25);
expect(new Set([...first.deployments, ...second.deployments].map(row => row.id)).size).toBe(50);
const filtered = await (await GET({ url: new URL('http://localhost/api/campaigns?server=target') })).json();
expect(
new Set([...first.deployments, ...second.deployments].map((row) => row.id)).size
).toBe(50);
const filtered = await (
await GET({ url: new URL('http://localhost/api/campaigns?server=target') })
).json();
expect(filtered.deployments.map((row: { id: string }) => row.id)).toEqual(['older-target']);
expect(filtered.deployments[0].servers).toHaveLength(2);
expect((await (await GET({ url: new URL('http://localhost/api/campaigns?server=unknown') })).json()).deployments).toEqual([]);
expect(
(
await (
await GET({ url: new URL('http://localhost/api/campaigns?server=unknown') })
).json()
).deployments
).toEqual([]);
});
it('identifies plugins, scripts, composed configs and unknown inventory files', async () => {
const { db } = await import('../../src/lib/server/db/index.js');
db().exec("INSERT INTO servers (name) VALUES ('target')");
const { createScript } = await import('../../src/lib/server/fleet/scripts.js');
const { recordScript } = await import('../../src/lib/server/fleet/inventory.js');
const { script, version } = createScript({ name:'Plugin', kind:'plugin', releaseVersion:'v1.0.0', targetRelPath:'native.bin', content:Buffer.from('plugin') });
recordScript('target','native.bin',version.id,version.sha256,6,'beta');
recordScript('target','dedicated_zm.cfg',null,'hash',10,'compose');
recordScript('target','main.gsc',null,'hash',10,'beta');
recordScript('target','unknown.dat',null,'hash',10,'manual');
const { GET } = await import('../../src/routes/api/servers/[name]/scripts/+server.js');
const body = await (await GET({ params: {name:'target'} })).json();
expect(Object.fromEntries(body.scripts.map((file: {relPath:string;kind:string}) => [file.relPath,file.kind]))).toEqual({
'dedicated_zm.cfg':'config','main.gsc':'script','native.bin':'plugin','unknown.dat':'file'
const { script, version } = createScript({
name: 'Plugin',
kind: 'plugin',
releaseVersion: 'v1.0.0',
targetRelPath: 'native.bin',
content: Buffer.from('plugin')
});
expect(body.scripts.find((file: { relPath: string }) => file.relPath === 'native.bin')).toMatchObject({
artifactId: script.id, version: version.version, releaseVersion: 'v1.0.0', sha256: version.sha256
recordScript('target', 'native.bin', version.id, version.sha256, 6, 'beta');
recordScript('target', 'dedicated_zm.cfg', null, 'hash', 10, 'compose');
recordScript('target', 'main.gsc', null, 'hash', 10, 'beta');
recordScript('target', 'unknown.dat', null, 'hash', 10, 'manual');
const { GET } = await import('../../src/routes/api/servers/[name]/scripts/+server.js');
const body = await (await GET({ params: { name: 'target' } })).json();
expect(
Object.fromEntries(
body.scripts.map((file: { relPath: string; kind: string }) => [
file.relPath,
file.kind
])
)
).toEqual({
'dedicated_zm.cfg': 'config',
'main.gsc': 'script',
'native.bin': 'plugin',
'unknown.dat': 'file'
});
expect(
body.scripts.find((file: { relPath: string }) => file.relPath === 'native.bin')
).toMatchObject({
artifactId: script.id,
version: version.version,
releaseVersion: 'v1.0.0',
sha256: version.sha256
});
});
it.each([['native.bin', 'file'], ['native.dll', 'plugin']])('omits saved artifact metadata for modified %s and falls back to its extension', async (path, kind) => {
const { db } = await import('../../src/lib/server/db/index.js');
db().exec("INSERT INTO servers (name) VALUES ('target')");
const { createScript } = await import('../../src/lib/server/fleet/scripts.js');
const { recordScript } = await import('../../src/lib/server/fleet/inventory.js');
const { version } = createScript({ name:'Plugin', kind:'plugin', releaseVersion:'v1.0.0', targetRelPath:path, content:Buffer.from('plugin') });
const content = Buffer.from('modified plugin');
const sha256 = createHash('sha256').update(content).digest('hex');
recordScript('target',path,version.id,sha256,content.length,'manual');
const { GET } = await import('../../src/routes/api/servers/[name]/scripts/+server.js');
const body = await (await GET({ params: {name:'target'} })).json();
expect(body.scripts).toEqual([expect.objectContaining({
relPath: path, kind, artifactId: null, version: null, releaseVersion: null,
scriptVersionId: version.id, sha256, size: content.length, source: 'manual'
})]);
});
it.each([
['native.bin', 'file'],
['native.dll', 'plugin']
])(
'omits saved artifact metadata for modified %s and falls back to its extension',
async (path, kind) => {
const { db } = await import('../../src/lib/server/db/index.js');
db().exec("INSERT INTO servers (name) VALUES ('target')");
const { createScript } = await import('../../src/lib/server/fleet/scripts.js');
const { recordScript } = await import('../../src/lib/server/fleet/inventory.js');
const { version } = createScript({
name: 'Plugin',
kind: 'plugin',
releaseVersion: 'v1.0.0',
targetRelPath: path,
content: Buffer.from('plugin')
});
const content = Buffer.from('modified plugin');
const sha256 = createHash('sha256').update(content).digest('hex');
recordScript('target', path, version.id, sha256, content.length, 'manual');
const { GET } = await import('../../src/routes/api/servers/[name]/scripts/+server.js');
const body = await (await GET({ params: { name: 'target' } })).json();
expect(body.scripts).toEqual([
expect.objectContaining({
relPath: path,
kind,
artifactId: null,
version: null,
releaseVersion: null,
scriptVersionId: version.id,
sha256,
size: content.length,
source: 'manual'
})
]);
}
);
});