Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
@@ -1,34 +1,64 @@
|
||||
import { afterEach, beforeEach, 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();
|
||||
});
|
||||
|
||||
it('bounds beta pages, searches across retained history, and seeks activity without duplicates', async () => {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { betaListPage, betaActivityPage } = await import('../../src/lib/server/fleet/beta-pages.js');
|
||||
const { betaListPage, betaActivityPage } =
|
||||
await import('../../src/lib/server/fleet/beta-pages.js');
|
||||
db().exec(`INSERT INTO scripts(id,name,target_rel_path) VALUES(1,'Plugin','plugin.dll');
|
||||
INSERT INTO script_versions(id,script_id,version,sha256,size) VALUES(1,1,1,'hash',0)`);
|
||||
db().transaction(() => {
|
||||
for (let id = 1; id <= 125; id++) {
|
||||
db().prepare('INSERT INTO betas(id,script_id,script_version_id,trigger_kind,state,notes) VALUES(?,1,1,?,?,?)')
|
||||
db()
|
||||
.prepare(
|
||||
'INSERT INTO betas(id,script_id,script_version_id,trigger_kind,state,notes) VALUES(?,1,1,?,?,?)'
|
||||
)
|
||||
.run(id, 'ui', id <= 5 ? 'running' : 'promoted', `Test ${id}`);
|
||||
db().prepare('INSERT INTO beta_scripts(beta_id,script_id,script_version_id) VALUES(?,1,1)').run(id);
|
||||
db()
|
||||
.prepare(
|
||||
'INSERT INTO beta_scripts(beta_id,script_id,script_version_id) VALUES(?,1,1)'
|
||||
)
|
||||
.run(id);
|
||||
}
|
||||
for (let i = 0; i < 150; i++) db().prepare('INSERT INTO beta_events(beta_id,message) VALUES(1,?)').run(`Activity ${i}`);
|
||||
for (let i = 0; i < 150; i++)
|
||||
db()
|
||||
.prepare('INSERT INTO beta_events(beta_id,message) VALUES(1,?)')
|
||||
.run(`Activity ${i}`);
|
||||
})();
|
||||
const page = betaListPage(new URLSearchParams());
|
||||
expect(page.betas).toHaveLength(25);
|
||||
expect(page).toMatchObject({ total: 125, page: 1, totalPages: 5, counts: { active: 5, history: 120 } });
|
||||
expect(betaListPage(new URLSearchParams('view=active')).betas.map(beta => beta.id)).toEqual([5,4,3,2,1]);
|
||||
expect(betaListPage(new URLSearchParams('view=history&q=Test%20101')).betas.map(beta => beta.id)).toEqual([101]);
|
||||
expect(page).toMatchObject({
|
||||
total: 125,
|
||||
page: 1,
|
||||
totalPages: 5,
|
||||
counts: { active: 5, history: 120 }
|
||||
});
|
||||
expect(betaListPage(new URLSearchParams('view=active')).betas.map((beta) => beta.id)).toEqual([
|
||||
5, 4, 3, 2, 1
|
||||
]);
|
||||
expect(
|
||||
betaListPage(new URLSearchParams('view=history&q=Test%20101')).betas.map((beta) => beta.id)
|
||||
).toEqual([101]);
|
||||
expect(betaListPage(new URLSearchParams('q=Plugin&limit=100000')).betas).toHaveLength(100);
|
||||
const second = betaListPage(new URLSearchParams('page=2'));
|
||||
expect(second.betas.some(beta => page.betas.some(other => other.id === beta.id))).toBe(false);
|
||||
expect(second.betas.some((beta) => page.betas.some((other) => other.id === beta.id))).toBe(
|
||||
false
|
||||
);
|
||||
const latest = betaActivityPage(1);
|
||||
expect(latest.events).toHaveLength(50);
|
||||
db().prepare("INSERT INTO beta_events(beta_id,message) VALUES(1,'New event')").run();
|
||||
const previous = betaActivityPage(1, new URLSearchParams({ before: String(latest.nextBefore) }));
|
||||
const previous = betaActivityPage(
|
||||
1,
|
||||
new URLSearchParams({ before: String(latest.nextBefore) })
|
||||
);
|
||||
expect(previous.events).toHaveLength(50);
|
||||
expect(previous.events.at(-1)!.id).toBeLessThan(latest.events[0].id);
|
||||
const { GET } = await import('../../src/routes/api/betas/[id]/+server.js');
|
||||
@@ -38,13 +68,20 @@ it('bounds beta pages, searches across retained history, and seeks activity with
|
||||
it('coalesces beta progress notifications after synchronous database work', async () => {
|
||||
const { invalidateBeta, subscribe } = await import('../../src/lib/server/pipeline/bus.js');
|
||||
const events: unknown[] = [];
|
||||
const stop = subscribe(event => events.push(event));
|
||||
const stop = subscribe((event) => events.push(event));
|
||||
try {
|
||||
invalidateBeta(1); invalidateBeta(1); invalidateBeta(2);
|
||||
invalidateBeta(1);
|
||||
invalidateBeta(1);
|
||||
invalidateBeta(2);
|
||||
expect(events).toEqual([]);
|
||||
await Promise.resolve();
|
||||
expect(events).toEqual([{ type: 'beta-changed', betaId: 1 }, { type: 'beta-changed', betaId: 2 }]);
|
||||
} finally { stop(); }
|
||||
expect(events).toEqual([
|
||||
{ type: 'beta-changed', betaId: 1 },
|
||||
{ type: 'beta-changed', betaId: 2 }
|
||||
]);
|
||||
} finally {
|
||||
stop();
|
||||
}
|
||||
});
|
||||
|
||||
it('filters by displayed status and searches servers and file paths before pagination', async () => {
|
||||
@@ -57,30 +94,53 @@ it('filters by displayed status and searches servers and file paths before pagin
|
||||
INSERT INTO script_versions(id,script_id,version,sha256,size) VALUES(1,1,1,'hash',0);
|
||||
INSERT INTO servers(name) VALUES('t5_zombie_theater_3');`);
|
||||
const states = [
|
||||
['running','active','awaiting-empty'], ['ready-promote','passed','ready'], ['running','failed','failed'],
|
||||
['running','paused','observing'], ['promoted','passed','ready'], ['rolled-back','paused','ready'], ['running','inconclusive','observing']
|
||||
['running', 'active', 'awaiting-empty'],
|
||||
['ready-promote', 'passed', 'ready'],
|
||||
['running', 'failed', 'failed'],
|
||||
['running', 'paused', 'observing'],
|
||||
['promoted', 'passed', 'ready'],
|
||||
['rolled-back', 'paused', 'ready'],
|
||||
['running', 'inconclusive', 'observing']
|
||||
];
|
||||
for (let index = 0; index < 35; index++) {
|
||||
const [state, outcome, stage] = states[index % states.length];
|
||||
const id = index + 1;
|
||||
db().prepare('INSERT INTO betas(id,script_id,script_version_id,trigger_kind,state,notes) VALUES(?,1,1,?,?,?)').run(id, 'ui', state, `Beta test ${id}`);
|
||||
db().prepare('INSERT INTO beta_scripts(beta_id,script_id,script_version_id) VALUES(?,1,1)').run(id);
|
||||
db().prepare('INSERT INTO beta_servers(beta_id,server,stage,had_original) VALUES(?,?,?,0)').run(id, 't5_zombie_theater_3', stage);
|
||||
db().prepare('INSERT INTO beta_test_plans(beta_id,plan,outcome) VALUES(?,?,?)').run(id, JSON.stringify(defaultPlan()), outcome);
|
||||
db()
|
||||
.prepare(
|
||||
'INSERT INTO betas(id,script_id,script_version_id,trigger_kind,state,notes) VALUES(?,1,1,?,?,?)'
|
||||
)
|
||||
.run(id, 'ui', state, `Beta test ${id}`);
|
||||
db()
|
||||
.prepare('INSERT INTO beta_scripts(beta_id,script_id,script_version_id) VALUES(?,1,1)')
|
||||
.run(id);
|
||||
db()
|
||||
.prepare('INSERT INTO beta_servers(beta_id,server,stage,had_original) VALUES(?,?,?,0)')
|
||||
.run(id, 't5_zombie_theater_3', stage);
|
||||
db()
|
||||
.prepare('INSERT INTO beta_test_plans(beta_id,plan,outcome) VALUES(?,?,?)')
|
||||
.run(id, JSON.stringify(defaultPlan()), outcome);
|
||||
}
|
||||
const body = await (await GET({ url: new URL('http://localhost/api/betas?limit=100') })).json();
|
||||
for (const status of ['ready', 'testing', 'attention', 'paused', 'promoted', 'rolled-back']) {
|
||||
const expected = body.betas.filter((beta: Parameters<typeof betaStatus>[0]) => betaStatus(beta).key === status);
|
||||
const expected = body.betas.filter(
|
||||
(beta: Parameters<typeof betaStatus>[0]) => betaStatus(beta).key === status
|
||||
);
|
||||
const result = betaListPage(new URLSearchParams({ status, limit: '100' }));
|
||||
expect(result.total).toBe(expected.length);
|
||||
expect(result.betas.map(beta => beta.id)).toEqual(expected.map((beta: { id: number }) => beta.id));
|
||||
expect(result.betas.map((beta) => beta.id)).toEqual(
|
||||
expected.map((beta: { id: number }) => beta.id)
|
||||
);
|
||||
}
|
||||
expect(betaListPage(new URLSearchParams('q=Kino%20Der%20Toten')).total).toBe(35);
|
||||
expect(betaListPage(new URLSearchParams('q=special-file.dll')).total).toBe(35);
|
||||
expect(betaListPage(new URLSearchParams('q=%2335')).betas.map(beta => beta.id)).toEqual([35]);
|
||||
expect(betaListPage(new URLSearchParams('q=%2335')).betas.map((beta) => beta.id)).toEqual([35]);
|
||||
const first = betaListPage(new URLSearchParams('view=active&status=attention&q=Kino&limit=3'));
|
||||
const second = betaListPage(new URLSearchParams('view=active&status=attention&q=Kino&limit=3&page=2'));
|
||||
const second = betaListPage(
|
||||
new URLSearchParams('view=active&status=attention&q=Kino&limit=3&page=2')
|
||||
);
|
||||
expect(first.total).toBe(10);
|
||||
expect(first.betas).toHaveLength(3);
|
||||
expect(second.betas.some(beta => first.betas.some(other => other.id === beta.id))).toBe(false);
|
||||
expect(second.betas.some((beta) => first.betas.some((other) => other.id === beta.id))).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user