77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import type { JobRecord } from '@devrunbook/application'
|
|
import { createJobHandlers } from './handlers'
|
|
|
|
function job(payload: JobRecord['payload']): JobRecord {
|
|
const timestamp = new Date('2026-07-27T12:00:00.000Z')
|
|
return {
|
|
id: '00000000-0000-4000-8000-000000000911',
|
|
workspaceId: null,
|
|
type: 'system.health-probe',
|
|
state: 'running',
|
|
idempotencyKey: 'probe-1',
|
|
payload,
|
|
progress: {},
|
|
attemptCount: 1,
|
|
maxAttempts: 3,
|
|
leaseOwner: 'worker:lease',
|
|
leaseExpiresAt: timestamp,
|
|
availableAt: timestamp,
|
|
startedAt: timestamp,
|
|
finishedAt: null,
|
|
errorCode: null,
|
|
errorDetailRedacted: null,
|
|
createdAt: timestamp,
|
|
updatedAt: timestamp,
|
|
}
|
|
}
|
|
|
|
describe('worker job handlers', () => {
|
|
it('handles a durable health probe as data without executing payload text', async () => {
|
|
const handler = createJobHandlers(
|
|
() => new Date('2026-07-27T12:01:00.000Z'),
|
|
)['system.health-probe']
|
|
if (!handler) throw new Error('Health probe handler is not registered')
|
|
|
|
await expect(
|
|
handler(job({ requestedBy: '$(unsafe command)' }), {
|
|
signal: new AbortController().signal,
|
|
heartbeat: async () => true,
|
|
}),
|
|
).resolves.toEqual({
|
|
status: 'ok',
|
|
checkedAt: '2026-07-27T12:01:00.000Z',
|
|
workerProtocol: 1,
|
|
})
|
|
})
|
|
|
|
it('rejects unsupported payload fields permanently', async () => {
|
|
const handler = createJobHandlers()['system.health-probe']
|
|
if (!handler) throw new Error('Health probe handler is not registered')
|
|
|
|
await expect(
|
|
handler(job({ command: 'whoami' }), {
|
|
signal: new AbortController().signal,
|
|
heartbeat: async () => true,
|
|
}),
|
|
).rejects.toMatchObject({ code: 'health_probe_payload_invalid' })
|
|
})
|
|
|
|
it('registers repository collection only when explicit dependencies are supplied', () => {
|
|
expect(createJobHandlers()['gitea.repository-snapshot']).toBeUndefined()
|
|
expect(
|
|
createJobHandlers(undefined, {
|
|
createReader: async () => {
|
|
throw new Error('not used')
|
|
},
|
|
persistence: {
|
|
resolveCollectionTarget: async () => null,
|
|
completeCollection: async () => null,
|
|
failCollection: async () => false,
|
|
},
|
|
})['gitea.repository-snapshot'],
|
|
).toBeTypeOf('function')
|
|
})
|
|
})
|