refactor(transcription): replace window.confirm with ConfirmService in TranscriptionBlock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-12 13:47:37 +02:00
parent 08bd27b5cd
commit d4ead08c17
3 changed files with 109 additions and 33 deletions

View File

@@ -1,25 +1,32 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import TranscriptionBlock from './TranscriptionBlock.svelte';
import TranscriptionBlockHost from './TranscriptionBlock.test-host.svelte';
import type { ConfirmService } from '$lib/services/confirm.svelte.js';
afterEach(cleanup);
const BASE_PROPS = {
blockId: 'block-1',
documentId: 'doc-1',
blockNumber: 3,
text: 'Liebe Mutter,',
label: null,
active: false,
saveState: 'idle' as const,
canComment: true,
currentUserId: 'user-1',
onTextChange: vi.fn(),
onFocus: vi.fn(),
onDeleteClick: vi.fn(),
onRetry: vi.fn()
};
// Renders TranscriptionBlock via the host, which provides ConfirmService context.
function renderBlock(overrides: Record<string, unknown> = {}) {
return render(TranscriptionBlock, {
blockId: 'block-1',
documentId: 'doc-1',
blockNumber: 3,
text: 'Liebe Mutter,',
label: null,
active: false,
saveState: 'idle' as const,
canComment: true,
currentUserId: 'user-1',
onTextChange: vi.fn(),
onFocus: vi.fn(),
onDeleteClick: vi.fn(),
onRetry: vi.fn(),
return render(TranscriptionBlockHost, {
...BASE_PROPS,
onServiceReady: () => {},
...overrides
});
}
@@ -162,29 +169,57 @@ describe('TranscriptionBlock — reorder controls', () => {
// ─── Delete confirmation ──────────────────────────────────────────────────────
describe('TranscriptionBlock — delete confirmation', () => {
it('does not call onDeleteClick when user cancels confirm dialog', async () => {
const onDeleteClick = vi.fn();
vi.spyOn(window, 'confirm').mockReturnValue(false);
renderBlock({ onDeleteClick });
function renderBlockWithService(overrides: Record<string, unknown> = {}) {
let service!: ConfirmService;
render(TranscriptionBlockHost, {
blockId: 'block-1',
documentId: 'doc-1',
blockNumber: 3,
text: 'Liebe Mutter,',
label: null,
active: false,
saveState: 'idle' as const,
canComment: true,
currentUserId: 'user-1',
onTextChange: vi.fn(),
onFocus: vi.fn(),
onDeleteClick: vi.fn(),
onRetry: vi.fn(),
onServiceReady: (s: ConfirmService) => {
service = s;
},
...overrides
});
return { service };
}
const deleteBtn = page.getByRole('button', { name: 'Löschen' });
await deleteBtn.click();
describe('TranscriptionBlock — delete confirmation', () => {
it('does not call onDeleteClick when user cancels via confirm service', async () => {
const onDeleteClick = vi.fn();
const { service } = renderBlockWithService({ onDeleteClick });
// Use native DOM click so the async handler starts but yields at the await,
// letting the test observe service.options and settle the promise.
const deleteBtn = document.querySelector('button[aria-label="Löschen"]') as HTMLButtonElement;
deleteBtn.click();
await vi.waitFor(() => expect(service.options).not.toBeNull());
service.settle(false);
await vi.waitFor(() => expect(service.options).toBeNull());
expect(onDeleteClick).not.toHaveBeenCalled();
vi.restoreAllMocks();
});
it('calls onDeleteClick when user confirms deletion', async () => {
it('calls onDeleteClick when user confirms via confirm service', async () => {
const onDeleteClick = vi.fn();
vi.spyOn(window, 'confirm').mockReturnValue(true);
renderBlock({ onDeleteClick });
const { service } = renderBlockWithService({ onDeleteClick });
const deleteBtn = page.getByRole('button', { name: 'Löschen' });
await deleteBtn.click();
const deleteBtn = document.querySelector('button[aria-label="Löschen"]') as HTMLButtonElement;
deleteBtn.click();
await vi.waitFor(() => expect(service.options).not.toBeNull());
service.settle(true);
await vi.waitFor(() => expect(service.options).toBeNull());
expect(onDeleteClick).toHaveBeenCalledOnce();
vi.restoreAllMocks();
});
});