Files
familienarchiv/frontend/src/lib/document/DocumentTopBarActions.svelte.test.ts
Marcel 7d5a34edb7 refactor(document): extract DocumentTopBarActions from DocumentTopBar
Third Phase 5 split. The desktop action buttons — transcribe,
transcribe-stop, edit link, download link — become their own component
with a focused props interface (documentId, canWrite, isPdf,
transcribeMode bindable, filePath, originalFilename, fileUrl).

TDD: 8 tests covering empty render, transcribe button gating
(canWrite × isPdf × transcribeMode), stop-transcribe rendering, edit
link with documentId href, download link with filePath gating, all
hidden when in transcribe mode. After the test was red the component
was created.

DocumentTopBar dropped from 303 lines to 166. The orchestrator now
just composes BackButton, DocumentTopBarTitle, PersonChipRow,
OverflowPillButton, the details toggle, DocumentTopBarActions,
DocumentMobileMenu, and DocumentMetadataDrawer — each visual region
named in one or two words.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00

95 lines
3.0 KiB
TypeScript

import { describe, it, expect, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import DocumentTopBarActions from './DocumentTopBarActions.svelte';
afterEach(cleanup);
const baseProps = {
documentId: 'd1',
canWrite: false,
isPdf: false,
transcribeMode: false,
filePath: null as string | null,
originalFilename: 'brief.pdf' as string | null,
fileUrl: ''
};
describe('DocumentTopBarActions', () => {
it('renders nothing visible when canWrite is false and no file is present', async () => {
render(DocumentTopBarActions, { props: baseProps });
await expect
.element(page.getByRole('button', { name: /transkribieren/i }))
.not.toBeInTheDocument();
await expect.element(page.getByRole('link', { name: /bearbeiten/i })).not.toBeInTheDocument();
await expect.element(page.getByTitle('Herunterladen')).not.toBeInTheDocument();
});
it('renders the transcribe button when canWrite, isPdf, and not transcribing', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, canWrite: true, isPdf: true, filePath: 'docs/x.pdf' }
});
await expect.element(page.getByRole('button', { name: /transkribieren/i })).toBeVisible();
});
it('omits the transcribe button when not a PDF', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, canWrite: true, isPdf: false, filePath: 'docs/x.jpg' }
});
await expect
.element(page.getByRole('button', { name: /transkribieren/i }))
.not.toBeInTheDocument();
});
it('renders the stop-transcribe button when transcribeMode is true', async () => {
render(DocumentTopBarActions, {
props: {
...baseProps,
canWrite: true,
isPdf: true,
transcribeMode: true,
filePath: 'docs/x.pdf'
}
});
await expect.element(page.getByRole('button', { name: /fertig/i })).toBeVisible();
});
it('renders the edit link to the document edit route when canWrite and not transcribing', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, canWrite: true, documentId: 'doc-42' }
});
await expect
.element(page.getByRole('link', { name: /bearbeiten/i }))
.toHaveAttribute('href', '/documents/doc-42/edit');
});
it('hides the edit link when transcribeMode is true', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, canWrite: true, transcribeMode: true }
});
await expect.element(page.getByRole('link', { name: /bearbeiten/i })).not.toBeInTheDocument();
});
it('renders the download link when filePath is set and not in transcribe mode', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, filePath: 'docs/x.pdf', fileUrl: '/api/docs/x' }
});
await expect.element(page.getByTitle('Herunterladen')).toBeVisible();
});
it('hides the download link when transcribeMode is true', async () => {
render(DocumentTopBarActions, {
props: { ...baseProps, filePath: 'docs/x.pdf', fileUrl: '/api/docs/x', transcribeMode: true }
});
await expect.element(page.getByTitle('Herunterladen')).not.toBeInTheDocument();
});
});