Commit Graph

14 Commits

Author SHA1 Message Date
Marcel
6c7d696d56 test(discussion): rewrite MentionEditor test with vi.waitFor
Replaces 16 setTimeout(350ms / 30ms / 50ms) sleeps with vi.waitFor on
the actual signal — popup listbox appearance/disappearance, option
aria-selected state — so the test no longer races the 200ms internal
debounce against the real clock under CI load.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
f3915c4878 test(discussion): rewrite CommentThread test with behavioral assertions
Replaces 8 setTimeout sleeps with vi.waitFor on the actual signal
(textarea value, fetch URL recorded, onCountChange call) and converts
3 .not.toThrow smoke tests into behavioural assertions:

- "no onCountChange wired" → asserts initial comment text still renders
- "network error during reload" → asserts empty-hint state is shown
- "non-OK reload" → asserts empty-hint state is shown

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
f989fa00d4 test(discussion): expand CommentThread coverage further
Whitespace-only quotedText not seeded, no onCountChange not provided,
fetch network error during reload, non-OK reload response, own
comment with edit/delete affordances.

5 new tests covering ~10 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
6050773da5 test(discussion): expand MentionEditor coverage further
Adds mousedown-to-select flow, Enter-to-select with highlighted
result, fetch network throw handling.

3 new tests covering ~6 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
a93034a8d7 test(discussion): expand CommentThread coverage
Adds onCountChange-after-reload (loadOnMount=true), null currentUserId
isOwn behavior, replies flattened in display.

3 new tests covering ~10 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
d1aa0dc9f0 test(discussion): cover CommentThread branches
Empty hint, populated comment list, singular vs plural label,
canComment toggle, showCompose flag with empty/non-empty messages,
quotedText pre-fills textarea, onCountChange on mount, URL routing
for annotation/block/document comment endpoints.

12 tests covering ~25 branches in CommentThread.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
6b4a5ba0da test(discussion): cover MentionEditor branches
Textarea props (placeholder, rows, disabled), popup not shown
initially, popup opens on @ + query, empty results from API,
HTTP error → empty popup, Enter submits when popup closed,
Shift+Enter does not submit, Escape closes popup, Arrow{Up,Down}
navigation, Enter with no results.

12 tests covering ~30 branches in MentionEditor.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
a47fe9fbce test(discussion): cover CommentMessage branches
Author + initials, comment body, edited label gated on updatedAt vs
createdAt, edit-mode textarea, delete button gated on isOwn, onDelete
callback wiring.

8 tests covering ~16 of CommentMessage's branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
8db051d99c test(discussion): cover MentionDropdown branches
Listbox label, empty-state placeholder, create-new escape hatch with
noopener target, populated list, default aria-selected on first item,
life-date range visibility, position fallback when clientRect is null,
positioning from clientRect.

8 tests covering ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
0c765d8112 fix(tests): fix 13 pre-existing vitest-browser spec failures
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m54s
CI / OCR Service Tests (pull_request) Successful in 33s
CI / Backend Unit Tests (pull_request) Failing after 3m13s
CI / Unit & Component Tests (push) Failing after 3m48s
CI / OCR Service Tests (push) Successful in 39s
CI / Backend Unit Tests (push) Failing after 3m24s
Fixes all remaining failing tests in the browser project. Root cause in
every case: Playwright CDP-based clicks/keyboard events do not reliably
trigger Svelte 5 onclick/onkeydown handlers. Pattern applied throughout:

- Buttons / result items: native `.element().click()` or
  `dispatchEvent(new MouseEvent('click', { bubbles: true }))`
- Keyboard events: `dispatchEvent(new KeyboardEvent('keydown', { key }))`
  on the target DOM element
- TipTap selection: `element.focus()` + Selection API +
  `document.dispatchEvent(new Event('selectionchange'))`
- ProseMirror focus for onFocus: `dispatchEvent(new FocusEvent('focus'))`

Also fixes pre-existing content/logic issues found during analysis:
- ChronikErrorCard, BulkDropZone, CorrespondenzHero: stale i18n strings
  and wrong ARIA role (combobox not textbox)
- RichtlinienRuleCard: beide beispielInput + beispielOutput required for
  arrow to render; querySelectorAll to get last code element
- admin/system/page: vi.unstubAllGlobals() in afterEach; strict-mode
  heading selector; per-call mockResolvedValueOnce for dual-card page
- DocumentList: add total prop + result count paragraph (test relied on it)
- PersonTypeahead keyboard navigation: pressKey() helper with native
  KeyboardEvent dispatch replaces userEvent.keyboard()
- PersonMultiSelect: native element clicks for result selection and
  chip removal; keydown dispatch on result div for Enter key test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 13:15:54 +02:00
Marcel
4966855c24 feat(eslint): add boundaries/dependencies rule preventing cross-domain imports
Adds eslint-plugin-boundaries with one element type per Tier-1 domain and an
explicit allow-list encoding the architectural dependency graph:
- document may import from: shared, person, tag, ocr, activity, conversation
- geschichte may import from: shared, person, document
- ocr may import from: shared, document
- activity may import from: shared, notification
- all others (person, tag, user, notification, conversation): shared only
- routes may import from any domain

Default is 'disallow', so any unlisted cross-domain import is an error.
Two eslint-disable-next-line comments remain in shared/discussion where
person-domain helpers (getInitials, formatLifeDateRange) are needed to render
participant metadata; moving them to shared would lose the person-type context.

Closes #410
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 18:09:01 +02:00
Marcel
567612761d refactor: move lib-root files to lib/shared/ and finalize domain structure
- Move api.server.ts, errors.ts, types.ts, utils.ts, relativeTime.ts to lib/shared/
- Move person relationship components to lib/person/relationship/
- Move Stammbaum components to lib/person/genealogy/
- Move HelpPopover to lib/shared/primitives/
- Update all import paths across routes, specs, and lib files
- Update vi.mock() paths in server-project test files
- Remove now-empty legacy directories (components/, hooks/, server/, etc.)
- Update vite.config.ts coverage include paths for new structure
- Update frontend/CLAUDE.md to reflect domain-based lib/ layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:53:31 +02:00
Marcel
efcc347c00 refactor: move shared components to lib/shared/ sub-packages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:40:14 +02:00
Marcel
d6db7a07bd refactor: move shared utilities to lib/shared/ sub-packages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:35:15 +02:00