Rewrites BulkDocumentEditLayout to match the spec exactly: - Fixed viewport layout (same as DocumentEditLayout) filling viewport below nav - Split panel visible in all states (N=0/1/≥2) — was fullscreen dark drop zone - N=0: centered drop-zone-box in left panel; shared form visible but greyed out - N≥1: real PDF preview via URL.createObjectURL (no server upload required) - N≥2: FileSwitcherStrip at bottom of left panel; count pill + discard in topbar - FileEntry gains previewUrl; blob URLs created on add, revoked on remove/destroy - save() checks response.ok and marks failed files with status: 'error' - BulkDropZone redesigned: spec-accurate box with circular mint icon, serif title - FileSwitcherStrip: number badges, arrows, keyboard nav via data-chip-id selector - ScopeCard, UploadSaveBar: hardcoded German replaced with Paraglide i18n keys - +page.svelte simplified to bare component render (layout is self-contained) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { afterEach, describe, expect, it } from 'vitest';
|
||
import { cleanup, render } from 'vitest-browser-svelte';
|
||
import { page } from 'vitest/browser';
|
||
import Page from './+page.svelte';
|
||
|
||
afterEach(cleanup);
|
||
|
||
// ─── Test data ────────────────────────────────────────────────────────────────
|
||
|
||
const baseData = {
|
||
user: undefined,
|
||
canWrite: true,
|
||
canAnnotate: false,
|
||
persons: [],
|
||
initialSenderId: '',
|
||
initialSenderName: '',
|
||
initialReceivers: []
|
||
};
|
||
|
||
// ─── Prefill – sender ─────────────────────────────────────────────────────────
|
||
|
||
describe('New document page – sender prefill', () => {
|
||
it('shows an empty sender input when no senderId is in the URL', async () => {
|
||
render(Page, { data: baseData });
|
||
const input = document.querySelector<HTMLInputElement>('#senderId-search');
|
||
expect(input?.value).toBe('');
|
||
});
|
||
|
||
it('shows the sender name in the typeahead input when initialSenderName is set', async () => {
|
||
render(Page, {
|
||
data: { ...baseData, initialSenderId: 'p1', initialSenderName: 'Hans Müller' }
|
||
});
|
||
const input = document.querySelector<HTMLInputElement>('#senderId-search');
|
||
expect(input?.value).toBe('Hans Müller');
|
||
});
|
||
|
||
it('sets the hidden senderId input to the prefilled ID', async () => {
|
||
render(Page, {
|
||
data: { ...baseData, initialSenderId: 'p1', initialSenderName: 'Hans Müller' }
|
||
});
|
||
const hidden = document.querySelector<HTMLInputElement>(
|
||
'input[type="hidden"][name="senderId"]'
|
||
);
|
||
expect(hidden?.value).toBe('p1');
|
||
});
|
||
});
|
||
|
||
// ─── Prefill – receiver ───────────────────────────────────────────────────────
|
||
|
||
describe('New document page – receiver prefill', () => {
|
||
it('shows no receiver chips when initialReceivers is empty', async () => {
|
||
render(Page, { data: baseData });
|
||
await expect.element(page.getByText('Anna Schmidt')).not.toBeInTheDocument();
|
||
});
|
||
|
||
it('shows a receiver chip when initialReceivers has a person', async () => {
|
||
const data = {
|
||
...baseData,
|
||
initialReceivers: [
|
||
{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' }
|
||
]
|
||
};
|
||
render(Page, { data });
|
||
await expect.element(page.getByText('Anna Schmidt')).toBeInTheDocument();
|
||
});
|
||
|
||
it('renders a hidden receiverIds input for the prefilled receiver', async () => {
|
||
const data = {
|
||
...baseData,
|
||
initialReceivers: [
|
||
{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' }
|
||
]
|
||
};
|
||
render(Page, { data });
|
||
const hidden = document.querySelector<HTMLInputElement>('input[name="receiverIds"]');
|
||
expect(hidden?.value).toBe('p2');
|
||
});
|
||
});
|