Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
@@ -1,17 +1,44 @@
|
||||
import { beforeEach, afterEach, describe, it, expect, vi } from 'vitest';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
vi.mock('../../src/lib/server/pipeline/worker.js', () => ({ kick: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock('../../src/lib/server/pipeline/worker.js', () => ({
|
||||
kick: vi.fn().mockResolvedValue(undefined)
|
||||
}));
|
||||
let fixture: Fixture;
|
||||
beforeEach(async () => { vi.resetModules(); fixture = await newFixture(); });
|
||||
afterEach(async () => { await fixture.cleanup(); });
|
||||
const request = (body: unknown) => new Request('http://localhost/api/maintenance', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
fixture = await newFixture();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await fixture.cleanup();
|
||||
});
|
||||
const request = (body: unknown) =>
|
||||
new Request('http://localhost/api/maintenance', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
|
||||
describe('Maintenance API', () => {
|
||||
it('saves independent policies and the global pause without changing the restart schedule', async () => {
|
||||
const { POST, GET } = await import('../../src/routes/api/maintenance/+server.js');
|
||||
expect((await POST({ request: request({ action: 'schedule', enabled: true, time: '06:00', timeZone: 'America/Indiana/Indianapolis' }) })).status).toBe(200);
|
||||
const before = (await (GET()).json()).runtime.schedule;
|
||||
for (const body of [{ action: 'policy', policy: 'health', enabled: false }, { action: 'policy', policy: 'updates', enabled: true }, { action: 'pause', paused: true }]) {
|
||||
expect(
|
||||
(
|
||||
await POST({
|
||||
request: request({
|
||||
action: 'schedule',
|
||||
enabled: true,
|
||||
time: '06:00',
|
||||
timeZone: 'America/Indiana/Indianapolis'
|
||||
})
|
||||
})
|
||||
).status
|
||||
).toBe(200);
|
||||
const before = (await GET().json()).runtime.schedule;
|
||||
for (const body of [
|
||||
{ action: 'policy', policy: 'health', enabled: false },
|
||||
{ action: 'policy', policy: 'updates', enabled: true },
|
||||
{ action: 'pause', paused: true }
|
||||
]) {
|
||||
expect((await POST({ request: request(body) })).status).toBe(200);
|
||||
}
|
||||
const data = await GET().json();
|
||||
@@ -22,32 +49,69 @@ describe('Maintenance API', () => {
|
||||
it('rejects malformed actions without changing policies or queuing work', async () => {
|
||||
const { POST, GET } = await import('../../src/routes/api/maintenance/+server.js');
|
||||
const before = await GET().json();
|
||||
for (const body of [null, [], {}, { action: 'pause', paused: 'yes' }, { action: 'policy', policy: 'unknown', enabled: true },
|
||||
{ action: 'policy', policy: 'updates', enabled: 1 }, { action: 'schedule', enabled: true, time: '25:00', timeZone: 'UTC' },
|
||||
{ action: 'schedule', enabled: true, time: '06:00', timeZone: 'invalid' }, { action: 'update', servers: [] },
|
||||
{ action: 'update', servers: [1] }, { action: 'retry', id: '1' }]) {
|
||||
for (const body of [
|
||||
null,
|
||||
[],
|
||||
{},
|
||||
{ action: 'pause', paused: 'yes' },
|
||||
{ action: 'policy', policy: 'unknown', enabled: true },
|
||||
{ action: 'policy', policy: 'updates', enabled: 1 },
|
||||
{ action: 'schedule', enabled: true, time: '25:00', timeZone: 'UTC' },
|
||||
{ action: 'schedule', enabled: true, time: '06:00', timeZone: 'invalid' },
|
||||
{ action: 'update', servers: [] },
|
||||
{ action: 'update', servers: [1] },
|
||||
{ action: 'retry', id: '1' }
|
||||
]) {
|
||||
expect((await POST({ request: request(body) })).status).toBe(400);
|
||||
}
|
||||
expect(await GET().json()).toEqual(before);
|
||||
});
|
||||
it('opens one retained request outside the recent history window without changing normal history', async () => {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const insert = db().prepare("INSERT INTO maintenance_jobs(server,state,requested_at,kind,origin) VALUES(?,'done',?,'schedule','schedule')");
|
||||
db().transaction(() => { for (let i = 0; i < 105; i++) insert.run('t5_zombie_theater_1', new Date(Date.UTC(2026, 0, 1, 0, i)).toISOString()); })();
|
||||
const insert = db().prepare(
|
||||
"INSERT INTO maintenance_jobs(server,state,requested_at,kind,origin) VALUES(?,'done',?,'schedule','schedule')"
|
||||
);
|
||||
db().transaction(() => {
|
||||
for (let i = 0; i < 105; i++)
|
||||
insert.run(
|
||||
't5_zombie_theater_1',
|
||||
new Date(Date.UTC(2026, 0, 1, 0, i)).toISOString()
|
||||
);
|
||||
})();
|
||||
const { GET } = await import('../../src/routes/api/maintenance/+server.js');
|
||||
const ordinary = await GET().json();
|
||||
expect(ordinary.runtime.jobs).toHaveLength(100);
|
||||
expect(ordinary.runtime.jobs.some((job: { id: number }) => job.id === 1)).toBe(false);
|
||||
const selected = await GET({ url: new URL('http://localhost/api/maintenance?job=1') }).json();
|
||||
const selected = await GET({
|
||||
url: new URL('http://localhost/api/maintenance?job=1')
|
||||
}).json();
|
||||
expect(selected.runtime.jobs).toHaveLength(101);
|
||||
expect(selected.runtime.jobs.find((job: { id: number }) => job.id === 1)).toMatchObject({ state: 'done', kind: 'schedule' });
|
||||
for (const job of ['0', '-1', '', '1.5', 'bad', '99999999999999999999']) expect(GET({ url: new URL(`http://localhost/api/maintenance?job=${job}`) }).status).toBe(400);
|
||||
expect(selected.runtime.jobs.find((job: { id: number }) => job.id === 1)).toMatchObject({
|
||||
state: 'done',
|
||||
kind: 'schedule'
|
||||
});
|
||||
for (const job of ['0', '-1', '', '1.5', 'bad', '99999999999999999999'])
|
||||
expect(
|
||||
GET({ url: new URL(`http://localhost/api/maintenance?job=${job}`) }).status
|
||||
).toBe(400);
|
||||
expect(await GET().json()).toEqual(ordinary);
|
||||
});
|
||||
it('keeps old Watchdog URLs working through query-preserving redirects', async () => {
|
||||
const index = await import('../../src/routes/watchdog/+page.server.js');
|
||||
const detail = await import('../../src/routes/watchdog/[id]/+page.server.js');
|
||||
expect(() => index.load({ url: new URL('http://localhost/watchdog?kind=drift&server=test') })).toThrow(expect.objectContaining({ status: 308, location: '/maintenance?kind=drift&server=test' }));
|
||||
expect(() => detail.load({ params: { id: 'abc' }, url: new URL('http://localhost/watchdog/abc?test=1') })).toThrow(expect.objectContaining({ status: 308, location: '/maintenance/abc?test=1' }));
|
||||
expect(() =>
|
||||
index.load({ url: new URL('http://localhost/watchdog?kind=drift&server=test') })
|
||||
).toThrow(
|
||||
expect.objectContaining({
|
||||
status: 308,
|
||||
location: '/maintenance?kind=drift&server=test'
|
||||
})
|
||||
);
|
||||
expect(() =>
|
||||
detail.load({
|
||||
params: { id: 'abc' },
|
||||
url: new URL('http://localhost/watchdog/abc?test=1')
|
||||
})
|
||||
).toThrow(expect.objectContaining({ status: 308, location: '/maintenance/abc?test=1' }));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user