import { describe, it, expect, afterEach, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import SegmentationTrainingCard from './SegmentationTrainingCard.svelte'; afterEach(cleanup); const baseInfo = (overrides: Record = {}) => ({ availableSegBlocks: 10, ocrServiceAvailable: true, runs: [], ...overrides }); describe('SegmentationTrainingCard', () => { it('renders the heading and description', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } }); await expect .element(page.getByRole('heading', { name: /segmentierung trainieren/i })) .toBeVisible(); await expect.element(page.getByText(/Starte ein neues Training/i)).toBeVisible(); }); it('shows the count of available segmentation blocks', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo({ availableSegBlocks: 42 }) } }); await expect.element(page.getByText('42 Segmentierungsblöcke bereit')).toBeVisible(); }); it('shows zero blocks when trainingInfo is null', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: null } }); await expect.element(page.getByText('0 Segmentierungsblöcke bereit')).toBeVisible(); }); it('disables the start button when fewer than 5 blocks are available', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo({ availableSegBlocks: 3 }) } }); const btn = (await page .getByRole('button', { name: /training starten/i }) .element()) as HTMLButtonElement; expect(btn.disabled).toBe(true); }); it('shows the too-few-blocks hint when fewer than 5 blocks are available', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo({ availableSegBlocks: 3 }) } }); await expect .element(page.getByText(/Mindestens 5 Segmentierungsblöcke erforderlich/i)) .toBeVisible(); }); it('disables the start button when the OCR service is reported down', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo({ ocrServiceAvailable: false }) } }); const btn = (await page .getByRole('button', { name: /training starten/i }) .element()) as HTMLButtonElement; expect(btn.disabled).toBe(true); }); it('shows the service-down hint when ocrServiceAvailable is false', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo({ ocrServiceAvailable: false }) } }); await expect.element(page.getByText('OCR-Dienst ist nicht erreichbar.')).toBeVisible(); }); it('enables the start button when blocks are sufficient and the service is up', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } }); const btn = (await page .getByRole('button', { name: /training starten/i }) .element()) as HTMLButtonElement; expect(btn.disabled).toBe(false); }); it('shows the success message after a successful training POST', async () => { const fetchSpy = vi .spyOn(globalThis, 'fetch') .mockResolvedValue(new Response('{}', { status: 200 })); try { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } }); await page.getByRole('button', { name: /training starten/i }).click(); await expect .element(page.getByText('Training wurde gestartet und abgeschlossen.')) .toBeVisible(); } finally { fetchSpy.mockRestore(); } }); it('renders the training history heading', async () => { render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } }); await expect.element(page.getByRole('heading', { name: /verlauf/i })).toBeVisible(); }); });