refactor: move document domain core to lib/document/
Moves ~25 components, utils (search, filename, groupDocuments, documentStatusLabel, validateFile), bulkSelection store, and TranscriptionSection sub-component. Fixes broken relative imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
115
frontend/src/lib/document/UploadZone.svelte.test.ts
Normal file
115
frontend/src/lib/document/UploadZone.svelte.test.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { render } from 'vitest-browser-svelte';
|
||||
import { page } from 'vitest/browser';
|
||||
import UploadZone from './UploadZone.svelte';
|
||||
|
||||
describe('UploadZone', () => {
|
||||
describe('idle state', () => {
|
||||
it('shows the filename in the upload zone', async () => {
|
||||
render(UploadZone, {
|
||||
props: { filename: 'brief_1920.pdf', isUploading: false, isDragging: false, error: null }
|
||||
});
|
||||
await expect.element(page.getByText('brief_1920.pdf')).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows "Datei auswählen" button', async () => {
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: false, isDragging: false, error: null }
|
||||
});
|
||||
await expect.element(page.getByText('Datei auswählen')).toBeVisible();
|
||||
});
|
||||
|
||||
it('does not show the uploading animation', async () => {
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: false, isDragging: false, error: null }
|
||||
});
|
||||
expect(document.querySelector('[role="status"]')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('uploading state', () => {
|
||||
it('shows the uploading progress region', async () => {
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: true, isDragging: false, error: null }
|
||||
});
|
||||
await expect.element(page.getByRole('status')).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows Abbrechen button during upload', async () => {
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: true, isDragging: false, error: null }
|
||||
});
|
||||
await expect.element(page.getByText('Abbrechen')).toBeVisible();
|
||||
});
|
||||
|
||||
it('calls onCancel when Abbrechen is clicked', async () => {
|
||||
const onCancel = vi.fn();
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: true, isDragging: false, error: null, onCancel }
|
||||
});
|
||||
// Click the button inside [role="status"] — more specific than querySelector('button')
|
||||
const btn = document.querySelector('[role="status"] button') as HTMLButtonElement;
|
||||
btn.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
expect(onCancel).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
describe('error state', () => {
|
||||
it('shows the error message', async () => {
|
||||
render(UploadZone, {
|
||||
props: {
|
||||
filename: 'scan.pdf',
|
||||
isUploading: false,
|
||||
isDragging: false,
|
||||
error: 'Dateityp nicht unterstützt'
|
||||
}
|
||||
});
|
||||
await expect.element(page.getByText('Dateityp nicht unterstützt')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('file selection', () => {
|
||||
it('calls onFile for a valid PDF', () => {
|
||||
const onFile = vi.fn();
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: false, isDragging: false, error: null, onFile }
|
||||
});
|
||||
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
|
||||
const pdf = new File(['%PDF-1.4'], 'brief.pdf', { type: 'application/pdf' });
|
||||
Object.defineProperty(input, 'files', { value: [pdf], writable: false });
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
expect(onFile).toHaveBeenCalledWith(pdf);
|
||||
});
|
||||
|
||||
it('does not call onFile for an unsupported MIME type', async () => {
|
||||
const onFile = vi.fn();
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: false, isDragging: false, error: null, onFile }
|
||||
});
|
||||
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
|
||||
const docxFile = new File(['x'], 'test.docx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
||||
});
|
||||
Object.defineProperty(input, 'files', { value: [docxFile], writable: false });
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
expect(onFile).not.toHaveBeenCalled();
|
||||
await expect
|
||||
.element(page.getByText('Dieser Dateityp wird nicht unterstützt (PDF, JPG, PNG, TIFF).'))
|
||||
.toBeVisible();
|
||||
});
|
||||
|
||||
it('does not call onFile when file exceeds 50 MB', async () => {
|
||||
const onFile = vi.fn();
|
||||
render(UploadZone, {
|
||||
props: { filename: 'scan.pdf', isUploading: false, isDragging: false, error: null, onFile }
|
||||
});
|
||||
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
|
||||
const bigFile = new File(['x'.repeat(1)], 'huge.pdf', { type: 'application/pdf' });
|
||||
Object.defineProperty(bigFile, 'size', { value: 51 * 1024 * 1024 });
|
||||
Object.defineProperty(input, 'files', { value: [bigFile], writable: false });
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
expect(onFile).not.toHaveBeenCalled();
|
||||
await expect.element(page.getByText('Die Datei ist zu groß (max. 50 MB).')).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user