D2: verify GET /api/jobs returns error field for failed jobs
Verification tests for outcome-contract clause failed-job-error-exposed-for-ui-banner. - db.test.ts: listJobs includes error for failed jobs, null for non-failed - jobs-list-endpoint.test.ts: route-level integration with real DB, exercises GET handler end-to-end D2 already merged (f03b757+); non-blocking verification only.
This commit is contained in:
@@ -174,6 +174,24 @@ describe('listJobs', () => {
|
||||
it('returns an array (possibly empty)', () => {
|
||||
expect(Array.isArray(listJobs())).toBe(true);
|
||||
});
|
||||
|
||||
it('includes error field for failed jobs — D2 error banner data contract', () => {
|
||||
const job = createJob('src', 'Failed Job', 'auto');
|
||||
updateJob({ id: job.id, status: 'failed', error: 'simulated transcription failure for outcome-contract probe' });
|
||||
const jobs = listJobs();
|
||||
const found = jobs.find((j) => j.id === job.id);
|
||||
expect(found).toBeDefined();
|
||||
expect(found!.error).toBe('simulated transcription failure for outcome-contract probe');
|
||||
});
|
||||
|
||||
it('returns null error for non-failed jobs', () => {
|
||||
const job = createJob('src', 'Done Job', 'auto');
|
||||
updateJob({ id: job.id, status: 'done', error: null });
|
||||
const jobs = listJobs();
|
||||
const found = jobs.find((j) => j.id === job.id);
|
||||
expect(found).toBeDefined();
|
||||
expect(found!.error).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ── Push subscriptions ────────────────────────────────────────────────────────
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { describe, it, expect, afterAll, vi } from 'vitest';
|
||||
import { join } from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { rm } from 'fs/promises';
|
||||
|
||||
/**
|
||||
* Integration test for GET /api/jobs — verifies the error field is
|
||||
* exposed for failed jobs and null for non-failed jobs, exercising
|
||||
* the full db→API path with a real SQLite database.
|
||||
*
|
||||
* Covers outcome-contract clause failed-job-error-exposed-for-ui-banner.
|
||||
* D2 already merged (f03b757+); this is non-blocking verification.
|
||||
*/
|
||||
|
||||
const TEST_DATA_DIR = join(tmpdir(), 'whisper-pwa-jobs-list-int-' + process.pid);
|
||||
vi.stubEnv('DATA_DIR', TEST_DATA_DIR);
|
||||
|
||||
const { createJob, getJob, updateJob, listJobs } = await import('$lib/server/db.js');
|
||||
const { GET } = await import('$lib/../routes/api/jobs/+server.js');
|
||||
|
||||
afterAll(async () => {
|
||||
await rm(TEST_DATA_DIR, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
describe('GET /api/jobs — error field exposure', () => {
|
||||
it('includes error field for a failed job', async () => {
|
||||
const job = createJob('probe-upload.webm', 'UI error probe', 'auto');
|
||||
updateJob({
|
||||
id: job.id,
|
||||
status: 'failed',
|
||||
error: 'simulated transcription failure for outcome-contract probe'
|
||||
});
|
||||
|
||||
const res = await GET();
|
||||
expect(res.status).toBe(200);
|
||||
const body = await res.json();
|
||||
expect(Array.isArray(body)).toBe(true);
|
||||
|
||||
const found = body.find((j: any) => j.id === job.id);
|
||||
expect(found).toBeDefined();
|
||||
expect(found.status).toBe('failed');
|
||||
expect(found.error).toBe('simulated transcription failure for outcome-contract probe');
|
||||
});
|
||||
|
||||
it('returns null error for a non-failed job', async () => {
|
||||
const job = createJob('probe-done.webm', 'Done probe', 'auto');
|
||||
updateJob({ id: job.id, status: 'done', error: null });
|
||||
|
||||
const res = await GET();
|
||||
expect(res.status).toBe(200);
|
||||
const body = await res.json();
|
||||
|
||||
const found = body.find((j: any) => j.id === job.id);
|
||||
expect(found).toBeDefined();
|
||||
expect(found.error).toBeNull();
|
||||
});
|
||||
|
||||
it('preserves other job fields when error is present', async () => {
|
||||
const job = createJob('my-recording.webm', 'My Recording', 'aggressive');
|
||||
updateJob({
|
||||
id: job.id,
|
||||
status: 'failed',
|
||||
error: 'transcription failed',
|
||||
progress: 50,
|
||||
whisperJobId: 'whisper-123'
|
||||
});
|
||||
|
||||
const res = await GET();
|
||||
const body = await res.json();
|
||||
const found = body.find((j: any) => j.id === job.id);
|
||||
|
||||
expect(found).toBeDefined();
|
||||
expect(found.status).toBe('failed');
|
||||
expect(found.error).toBe('transcription failed');
|
||||
expect(found.title).toBe('My Recording');
|
||||
expect(found.source).toBe('my-recording.webm');
|
||||
expect(found.audioMode).toBe('aggressive');
|
||||
expect(found.progress).toBe(50);
|
||||
expect(found.whisperJobId).toBe('whisper-123');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user