test(transcribe): prove Delete fires once via real shape + action (#327)

Review follow-up (Sara): the prior single-owner evidence was two separate
unit facts against an inert DOM stub. This renders a real AnnotationShape,
attaches the live transcribeShortcuts action, focuses the region, and presses
Delete once — asserting deleteCurrentRegion fires exactly once. A genuine
integration guard against re-introducing a double-bind.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-04 17:16:03 +02:00
parent 194340c716
commit f7bc3ccfc1

View File

@@ -2,9 +2,32 @@ import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import AnnotationShape from './AnnotationShape.svelte';
import {
transcribeShortcuts,
type TranscribeShortcutOptions
} from '$lib/shared/actions/transcribeShortcuts';
afterEach(cleanup);
function noopShortcutOptions(
overrides: Partial<TranscribeShortcutOptions> = {}
): TranscribeShortcutOptions {
return {
isPanelOpen: () => true,
isCheatsheetOpen: () => false,
panelMode: () => 'edit',
goToNextRegion: () => {},
goToPrevRegion: () => {},
toggleMode: () => {},
closePanel: () => {},
startDrawMode: () => {},
toggleTrainingMark: () => {},
deleteCurrentRegion: () => {},
openCheatsheet: () => {},
...overrides
};
}
function makeAnnotation(id = 'ann-1') {
return {
id,
@@ -128,4 +151,29 @@ describe('AnnotationShape', () => {
expect(onfocus).toHaveBeenCalledOnce();
});
// Integration: a real rendered shape + the live transcribeShortcuts action.
// Pressing Delete on the focused region must delete exactly once — proving the
// action is the single owner and the shape contributes no competing handler.
it('with the transcribeShortcuts action active, Delete deletes the focused region exactly once', () => {
const deleteCurrentRegion = vi.fn();
render(AnnotationShape, {
annotation: makeAnnotation(),
isHovered: false,
isActive: true,
showDelete: true,
onclick: () => {},
onpointerenter: () => {},
onpointerleave: () => {}
});
const annotationEl = page.getByTestId('annotation-ann-1').element() as HTMLElement;
const action = transcribeShortcuts(annotationEl, noopShortcutOptions({ deleteCurrentRegion }));
annotationEl.focus();
annotationEl.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', bubbles: true }));
expect(deleteCurrentRegion).toHaveBeenCalledTimes(1);
action.destroy();
});
});