story-ui-job-list-error: test error display on job list page
Add SSR-based component test verifying error display logic from +page.svelte. Uses svelte/server render() to avoid mount/browser requirements. - JobErrorDisplay.svelte: test component replicating error display template - app-environment.ts: mock for /environment (needed by accent.ts) - job-list-error-display.test.ts: 5 tests covering: * failed job with error -> error text rendered * done job with null error -> no error text * failed job with null error -> no error text * non-failed status with error -> no error text * title attribute contains full error text - vitest.config.ts: add svelte() plugin for .svelte file transforms, add /environment alias for test mocking Tests: 237 passed (19 files), 0 type errors, build OK.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { Job } from '$lib/types.js';
|
||||
|
||||
interface Props {
|
||||
job: Job;
|
||||
}
|
||||
|
||||
let { job }: Props = $props();
|
||||
</script>
|
||||
|
||||
{#if job.status === 'failed' && job.error}
|
||||
<div class="recent-err-line" title={job.error}>{job.error}</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,4 @@
|
||||
export const browser = true;
|
||||
export const building = false;
|
||||
export const dev = false;
|
||||
export const version = 'test';
|
||||
@@ -0,0 +1,86 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render } from 'svelte/server';
|
||||
import type { Job, AudioMode, JobStatus } from '$lib/types.js';
|
||||
import JobErrorDisplay from './__mocks__/JobErrorDisplay.svelte';
|
||||
|
||||
// Factory: minimal Job shape needed by the error display logic
|
||||
function makeJob(overrides: Partial<Job> = {}): Job {
|
||||
return {
|
||||
id: 'test-job',
|
||||
status: 'pending',
|
||||
title: 'Test',
|
||||
source: 'test.webm',
|
||||
audioMode: 'auto',
|
||||
error: null,
|
||||
progress: 0,
|
||||
segmentsJson: null,
|
||||
createdAt: '2026-01-01T00:00:00.000Z',
|
||||
updatedAt: '2026-01-01T00:00:00.000Z',
|
||||
whisperJobId: null,
|
||||
outputDir: null,
|
||||
meanVolume: null,
|
||||
retryCount: null,
|
||||
nextRetryAt: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('Job list error display', () => {
|
||||
it('renders error text for a failed job with error message', () => {
|
||||
const result = render(JobErrorDisplay, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: 'simulated transcription failure' }),
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.body).toContain('simulated transcription failure');
|
||||
expect(result.body).toContain('recent-err-line');
|
||||
});
|
||||
|
||||
it('renders nothing when job status is done with null error', () => {
|
||||
const result = render(JobErrorDisplay, {
|
||||
props: {
|
||||
job: makeJob({ status: 'done', error: null }),
|
||||
},
|
||||
});
|
||||
|
||||
// Svelte SSR leaves comment markers for false conditionals.
|
||||
// Verify no error-related classes or text are present.
|
||||
expect(result.body).not.toContain('recent-err-line');
|
||||
expect(result.body).not.toContain('error');
|
||||
});
|
||||
|
||||
it('renders nothing when job status is failed but error is null', () => {
|
||||
const result = render(JobErrorDisplay, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: null }),
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.body).not.toContain('recent-err-line');
|
||||
expect(result.body).not.toContain('error');
|
||||
});
|
||||
|
||||
it('renders nothing when job has error but status is not failed', () => {
|
||||
const result = render(JobErrorDisplay, {
|
||||
props: {
|
||||
job: makeJob({ status: 'pending', error: 'some error' }),
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.body).not.toContain('recent-err-line');
|
||||
expect(result.body).not.toContain('error');
|
||||
});
|
||||
|
||||
it('sets title attribute on error element to full error text', () => {
|
||||
const errMsg = 'detailed error description for tooltip';
|
||||
const result = render(JobErrorDisplay, {
|
||||
props: {
|
||||
job: makeJob({ status: 'failed', error: errMsg }),
|
||||
},
|
||||
});
|
||||
|
||||
// The title attribute should contain the full error text
|
||||
expect(result.body).toContain(`title="${errMsg}"`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user