test(profile,documents): cover PasswordChangeForm and FileSectionNew branches

PasswordChangeForm: tests the null/success/error/mismatch banner branches
plus the form action wiring.

FileSectionNew: tests the no-file/file-selected toggle, onfileParsed
callback invocation with the parsed metadata, the early-return when no
file is in the change event, and the suggestedTitle fallback path.

Eleven tests across two files. Both follow the UploadZone template (props,
File API synthetic input, vi.fn() callback spies).

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-09 20:01:59 +02:00
parent d9270e84a3
commit 2578da50f9
2 changed files with 122 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import FileSectionNew from './FileSectionNew.svelte';
afterEach(cleanup);
describe('FileSectionNew', () => {
it('renders the upload prompt and section heading when no file is selected', async () => {
render(FileSectionNew, { props: {} });
await expect.element(page.getByRole('heading', { name: /datei/i })).toBeVisible();
await expect.element(page.getByText('Datei hochladen')).toBeVisible();
await expect.element(page.getByText('(optional)')).toBeVisible();
});
it('replaces the prompt with the selected filename after a file is chosen', async () => {
render(FileSectionNew, { props: {} });
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
const file = new File(['%PDF'], 'brief_1920.pdf', { type: 'application/pdf' });
Object.defineProperty(input, 'files', { value: [file], writable: false });
input.dispatchEvent(new Event('change', { bubbles: true }));
await expect.element(page.getByText('brief_1920.pdf')).toBeVisible();
await expect.element(page.getByText('Datei hochladen')).not.toBeInTheDocument();
});
it('invokes onfileParsed with the parsed filename result', async () => {
const onfileParsed = vi.fn();
render(FileSectionNew, { props: { onfileParsed } });
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
const file = new File(['%PDF'], 'Sender_Receiver_2024-05-01.pdf', { type: 'application/pdf' });
Object.defineProperty(input, 'files', { value: [file], writable: false });
input.dispatchEvent(new Event('change', { bubbles: true }));
expect(onfileParsed).toHaveBeenCalledOnce();
const result = onfileParsed.mock.calls[0][0];
expect(result).toHaveProperty('suggestedTitle');
});
it('does nothing when the change event fires with no file selected', async () => {
const onfileParsed = vi.fn();
render(FileSectionNew, { props: { onfileParsed } });
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
Object.defineProperty(input, 'files', { value: [], writable: false });
input.dispatchEvent(new Event('change', { bubbles: true }));
expect(onfileParsed).not.toHaveBeenCalled();
await expect.element(page.getByText('Datei hochladen')).toBeVisible();
});
it('falls back to the bare stripped filename when the parser provides no suggested title', async () => {
const onfileParsed = vi.fn();
render(FileSectionNew, { props: { onfileParsed } });
const input = document.querySelector('input[type="file"]') as HTMLInputElement;
const file = new File(['%PDF'], 'plain.pdf', { type: 'application/pdf' });
Object.defineProperty(input, 'files', { value: [file], writable: false });
input.dispatchEvent(new Event('change', { bubbles: true }));
const result = onfileParsed.mock.calls[0][0];
expect(typeof result.suggestedTitle).toBe('string');
expect(result.suggestedTitle.length).toBeGreaterThan(0);
});
});