2403 Commits

Author SHA1 Message Date
Marcel
4b223df330 test(admin/tags): cover the tag-edit page branches
Heading with tag name, name input hydration, color picker visible only
for top-level tags, color swatch grid (10 entries), aria-pressed for
active color, success banner branch, error banner branch, merge-success
banner branch.

8 tests covering ~30 branches in the tag-edit page.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
f684ba3a61 test(documents): smoke-cover the new document page
Renders BulkDocumentEditLayout with prop pass-through and an
empty-values branch.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
931c4f7134 test(enrich): smoke-cover the enrich document page
Mounts the page, renders the orchestrator, exposes the hidden skip-form,
and renders the three submit-action buttons (skip, save, save+review).

4 tests covering the orchestration entry path of enrich/[id].

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
4ea8968af4 test(documents): smoke-cover the edit page with confirm-service mock
Renders the document edit page with mocked confirm service. Verifies
DocumentEditLayout mounts, both hidden submit-target forms (review and
delete) exist, and the delete button is present in the action bar.

3 tests covering the orchestration entry path of documents/[id]/edit.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
3891cb79b4 test(aktivitaeten): smoke-cover the page with mocked notification store
Mounts the aktivitaeten page with mocks for the notification SSE
singleton (init/destroy/markRead/markAllRead) and $app/state. Verifies
heading renders, error state renders main element, empty state renders
main, and a non-default filter renders without crashing.

4 tests covering the orchestration entry path.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
16c97dc329 test(documents): smoke-cover the document detail orchestrator
Mounts the page with mocked $app/state, $app/navigation, and confirm
service. Verifies the top bar renders, the viewer container exists, and
the last-visited localStorage write happens onMount.

3 tests covering the orchestration entry path of the 558-line
documents/[id]/+page.svelte.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
13e1a9497c test(persons): cover the edit page orchestrator branches
Edit heading, persons-section heading, form-error banner branch,
default no-error state, save-bar discard href targets the person
detail. Mocks confirm service.

5 tests, ~15 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
2bde11c612 test(routes): cover the home-page (/) dashboard branches
isReader vs contributor dashboard layout switch, greeting visibility tied
to user prop, DropZone rendering gated on canWrite, ReaderDraftsModule
gated on isReader+canBlogWrite, mission-control section caption.

7 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
9fd0d7f512 test(admin/ocr): cover index and per-person page branches
admin/ocr index: heading, sender-models heading, global-history link,
defensive defaults for missing trainingInfo fields.

admin/ocr/[personId]: person name from personNames lookup, Unknown
fallback when not found, back-link href, missing-personNames defensive
handling.

8 tests across two pages.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
ba96db968b test: cover five small index/empty-state route components
Three admin/index pages (groups/tags/users) — each renders a single
"Wähle X aus der Liste" prompt for the desktop split-view layout.
AuthHeader: brand link href + wordmark.
PersonsEmptyState: empty heading + explanation text.

6 tests across five small files.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
fbff5d9bd2 test: cover four small primitives
RelationshipPill: label render, empty-string handling.
OverflowPillDisplay: +N rendering, +0 edge case, aria-hidden marker.
TimelineYAxis: max/0 labels, barAreaHeight inline style, zero handling.
TranscriptionSection: heading + textarea, initial-value hydration,
empty default.

11 tests across four small primitives.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
bdcf813e71 test(ocr): cover OcrProgress SSE state branches
Running default render, progress bar element, document event updates
aria-valuenow, done event triggers onDone + clears running view, error
event flips heading, retry button in error state. Mocks EventSource
via Proxy so the SSE effect uses a stub, not a real connection.

6 tests, ~15 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
2d5768f635 test(admin/tags): cover TagTreeNode recursive branches
Tag link href, document-count visibility branch, color-dot at depth 0
vs deeper, aria-current matrix, children list rendering, collapse-map
hides children, expand/collapse toggle for nodes with children.

9 tests covering ~30 branches in the recursive tree-node component.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
c4b90b2c12 test(admin): cover the admin entry-page picker branches
Heading, all 5 links when full permissions, per-permission gating
matrix (users+invites, groups, tags, system), entity counts in rows.

7 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
010481e7ca test: cover DashboardFamilyPulse and UserMenu branches
DashboardFamilyPulse: null-pulse early return, eyebrow always shown,
headline gated on pages>0, you-line gated on yourPages>0, contributor
chips visibility, count tile rendering.

UserMenu: avatar button vs icon-only branch, aria-expanded matrix,
menu open/close, profile link + logout form rendering, POST/logout
form attributes.

14 tests covering ~30 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
be2ae4b429 test(briefwechsel): cover CorrespondenzHero branches
Headline + cross-link, recent-persons divider/chips visibility tied to
list length, onSelectPerson callback wiring, avatar initial uppercase
derivation.

5 tests, ~15 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
950dd116df test: cover UserProfileSection and AccountSection branches
UserProfileSection: four input fields render, prop hydration including
German date conversion, hidden ISO birthDate input, contact textarea
hydration, empty defaults.

AccountSection: heading, email input attributes, password input
attributes.

9 tests across two account-form helpers.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
2772652bc6 test(admin/system): cover the system page render branches
Backfill cards rendered, both backfill buttons enabled by default,
no success banner before any action. Smoke-level coverage of the
admin maintenance page.

5 tests covering basic render branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
c607fffacd test(briefwechsel): cover ConversationTimeline branches
Year divider rendering, distinct-year branch, no-duplicate consecutive
years, no-divider for documents without documentDate, canWrite-gated
new-document link with senderId-only and senderId+receiverId href
variants.

7 tests covering ~20 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
94a9fa9034 test(briefwechsel): cover CorrespondenzPersonBar branches
Two PersonTypeahead inputs render, swap button visibility tied to
both-persons-set, sort button label/aria-pressed switch on DESC vs ASC,
document count rendering, sort and swap callback wirings.

9 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
ff8f1b4c00 test(admin): cover EntityNav permission-gated rendering
All-sections render when full permissions, users/invites hidden when
!canManageUsers, groups hidden when !canManagePermissions, tags hidden
when !canManageTags, system/ocr hidden when !canRunMaintenance,
flyout closed by default.

6 tests covering ~30 branches in the permission matrix.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
4a794c8beb test(briefwechsel): cover the index page branches
Hero state when no senderId set, results card when senderId set,
SinglePersonHintBar gating on senderId × !receiverId, empty-results
message branch.

5 tests covering ~15 branches in the orchestrator.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
890f2d3051 test(admin/tags): cover TagsListPanel branches
Tree label rendering, empty placeholder branch, top-level node
rendering, collapse-button visibility, autocollapse vs manual collapse
via localStorage, expand-on-click flow, localStorage parse path,
malformed-JSON resilience.

9 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
6aed9afbe5 test(admin/users): cover UsersListPanel branches
Expanded list, per-user email+fullName rendering with null-name
fallback, group chip rendering, search filter (positive + empty result
branches), aria-current matrix, collapsed view via autocollapse.

8 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
26611676a9 test(admin/groups): cover GroupsListPanel branches
Expanded list with header, per-group rendering with permission count,
empty placeholder branch, new-group link, aria-current matrix, collapsed
view via autocollapse prop, localStorage preference path, expand-on-click
flow.

8 tests covering ~25 branches (collapsed/expanded × autocollapse ×
localStorage × empty × active matrix).

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
80c1bac991 test(document): cover TimelineBars branches
One bar per filled bucket, singular vs plural aria-label, aria-pressed
matrix, drag-window visibility tied to isDragging, onbarclick callback,
minimum-height handling for zero-count buckets.

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
2bce127065 test(notification): cover NotificationDropdown branches
Dialog with bell label, empty state vs populated list, mark-all-read
visibility branch, REPLY vs MENTION text, unread-dot rendering, all
three callback wirings (onMarkRead, onMarkAllRead, onClose).

10 tests covering the notification dropdown surface.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
71292635ce test(documents): cover documents/+ list page render branches
Screen-reader heading, result count visibility tied to totalElements,
new-document CTA gated on canWrite, bulk-edit-all CTA gated on
canWrite × totalElements > 0. Mocks $app/state and $app/navigation.

7 tests covering the orchestration branches without populating items
(DocumentList children require richer DTO shape covered separately).

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
c6f6822781 test: cover register and admin/users/new page branches
register page (350 lines): hero render when no codeError, NO_INVITE_CODE
vs other-codeError card branches, form hidden when codeError set,
back-to-login link, form section rendering, prefill hydration of
firstName/lastName/email, prefill-hint visibility branch, hidden
code input with code-null fallback.

admin/users/new: heading, three card sections, group checkboxes
rendered, form-error banner branch, cancel link, submit button.

17 tests across two pages.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
cdf10e079d test(routes): cover AppNav navigation branches
Brand link, four primary nav links, admin link gated on isAdmin,
hamburger menu open/close state via aria-expanded. Mocks $app/state
so the page URL drives the active-route highlighting.

6 tests, ~30 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
750f2463a2 test(hilfe): cover the Transkriptions-Richtlinien page
Title, all four section headings, secure Wikipedia link rel
attributes, five rule cards rendered, four klaerung chips rendered.

7 tests covering the static help page.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
f1a0076cc0 test(admin/groups): cover the group-edit page branches
Heading, name hydration, per-permission checkbox checked-state matrix,
success/error banner branches, cancel link, delete + save buttons.
Mocks confirm service.

7 tests, ~30 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
b4d25620ed test(geschichten): cover the index page branches
Heading, canBlogWrite-gated CTA, no-filter empty state vs for-persons
empty state, all-pill aria-pressed matrix, person-filter chip
rendering, populated card list. Mocks $app/navigation since the filter
buttons call goto.

9 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
a9371e4307 test(admin/users): cover the user-edit page branches
Heading with email, three card sections (profile/groups/password),
success vs error form banners, group preselection from editUser.groups,
cancel link, delete button. Mocks the confirm service.

7 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
145ea1c53b test(persons): cover persons/+ list page branches
Heading + stats bar render, empty-state placeholder, populated card
grid, canWrite-gated new-person CTA, search-input hydration from
data.q, document-count chip singular/plural/zero branches, alias
rendering. Mocks $app/navigation since the search debounce calls goto.

10 tests, ~30 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
434a6fecc9 test: cover login and persons/[id] page branches
login: form rendering, registered-success banner branch, form-error
banner branch, form-action wiring, email/password input attributes,
forgot-password link.

persons/[id]: PersonCard heading via prop pass-through, document section
headings, empty-message branches, GeschichtenCard hidden when empty,
co-correspondents derived from sent documents, canWrite gating the edit
link.

14 tests across two large pages.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
1e0684e9b2 test(document): cover TimelineControls and TimelineXAxis branches
TimelineControls: empty render when neither flag is set, reset button
gated on isZoomed, clear button gated on hasSelection, both-on, both
callback wirings.

TimelineXAxis: empty filled → no ticks, populated → ticks render,
omit-year branch when all buckets share a year, show-year branch
across multiple years, length-4 bucket-string fallback.

11 tests across two timeline primitives.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
dce99543d2 test: cover UserPasswordSection and CorrespondenzFilterControls
UserPasswordSection: input rendering, type=password attribute,
required-prop propagation in both directions.

CorrespondenzFilterControls: dual date label rendering, both DateInput
ids, value hydration from fromDate/toDate, change-event smoke check.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
f4e1117757 test: cover ScriptTypeSelect, SinglePersonHintBar, UserGroupsSection
ScriptTypeSelect: option list, placeholder disabled, value
initialisation, disabled prop propagation.

SinglePersonHintBar: hasDateFilter false vs true branches, sortDir
DESC vs ASC label switch, year-range with only fromDate fallback.

UserGroupsSection: per-group checkbox rendering, label visibility,
selectedGroupIds preselection, empty groups list, default empty
selection.

15 tests across three small primitives.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
ff19e7da35 test: cover DocumentThumbnail, UnsavedWarningBanner, PersonsStatsBar
DocumentThumbnail: thumbnailUrl→img branch, no-thumbnail→placeholder
icon branch, sm vs lg size container class, lazy/async loading attrs.

UnsavedWarningBanner: warning text, discard button, callback wiring.

PersonsStatsBar: count rendering, singular/plural label switching for
both persons and documents (4 branches), zero-count plural fallback.

14 tests across three small primitive files.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
056de96159 test(persons): cover PersonEditSaveBar branches
Four tests: discard link href, save button label, form attribute
wiring, formaction. Small focused component.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
79f995af10 test: cover enrich/done and documents/bulk-edit page branches
enrich/done: heading, body, both CTA links.

documents/bulk-edit: empty-store onMount redirect to /documents,
loading spinner during in-flight fetch, error banner on backend error
code, error banner on fetch rejection. Mocks fetch via vi.spyOn so the
async branches are exercised without a real backend.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
2bd62b8a4f test(shared): cover BackButton and OverflowPillButton
BackButton: visible vs aria-only label branches, custom class
application, history.back() click handler.

OverflowPillButton: +N pill render, aria-expanded matrix
(closed default → open after click), per-person link rendering with
correct href, Escape closes the dropdown.

Both are reused widely; their coverage closes the line and function gap
left after the DocumentTopBar split inflated the denominator.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
909c547e0e test(document): cover DocumentMetadataDrawer column branches
Sixteen tests covering the four-column drawer: details column always
renders, persons column branches (no-persons placeholder vs sender
vs receivers), receiver overflow + show-all toggle, tags column
branches (placeholder vs anchor list with /?tag href encoding),
geschichten column visibility (hidden by default, shown for
canBlogWrite, attach link gated on canBlogWrite + documentId, list
rendering, show-all overflow), inferred-relationship pill on the
single-receiver branch.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
54a9731bdc test: cover geschichten/new and geschichten/[id]/edit page renders
Both pages embed GeschichteEditor (TipTap-based). The tests assert
heading, BackButton presence, no-error default, editor inputs render,
and prop pass-through (initialPersons / initialDocuments). $app/navigation
is mocked because GeschichteEditor pulls beforeNavigate transitively.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
973314774a test: cover admin/groups/new and enrich/+ page branches
admin/groups/new: heading, both permission group renderings (4 standard
+ 4 administrative checkboxes), form-error banner branch, cancel link
href, submit button form-attribute wiring, name input requiredness.
Mocks $app/navigation so beforeNavigate doesn't crash the test runner.

enrich/+: heading, empty placeholder vs populated count + start CTA,
start CTA href derived from documents[0].id, per-row title rendering,
bulk-select checkbox gated on canWrite.

16 tests across two files.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
e5256c89a1 test: cover users/[id], admin/ocr/global, geschichten/[id] page branches
users/[id]: full-name derivation across all four branches
(both/firstName-only/lastName-only/email fallback), avatar initials
matrix, email/contact row visibility tied to data presence.

admin/ocr/global: heading + back link, runs prop pass-through,
defensive default for missing history fields.

geschichten/[id]: title rendering, author full-name vs email fallback
vs null, publishedAt suffix conditional, persons and documents sections
gated on array length, edit/delete actions gated on canBlogWrite. Mocks
the confirm service since it requires a ConfirmDialog mounted in layout.

26 tests across three files.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
00a8878146 test: cover PersonEditForm and SegmentationTrainingCard branches
PersonEditForm: PERSON vs INSTITUTION/GROUP visibility matrix (firstName,
title, alias, birth/deathYear toggle), lastName label switch, prop
hydration of all populated fields, fallback to PERSON for unknown type,
empty-string handling for null fields. 10 tests, ~30 branches.

SegmentationTrainingCard: trainingInfo null vs populated, block count
display, button disabled-state matrix (training × tooFewBlocks ×
serviceDown), too-few-blocks and service-down hints, success message
after a mocked fetch, training history heading. 10 tests, ~25 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
7d5a34edb7 refactor(document): extract DocumentTopBarActions from DocumentTopBar
Third Phase 5 split. The desktop action buttons — transcribe,
transcribe-stop, edit link, download link — become their own component
with a focused props interface (documentId, canWrite, isPdf,
transcribeMode bindable, filePath, originalFilename, fileUrl).

TDD: 8 tests covering empty render, transcribe button gating
(canWrite × isPdf × transcribeMode), stop-transcribe rendering, edit
link with documentId href, download link with filePath gating, all
hidden when in transcribe mode. After the test was red the component
was created.

DocumentTopBar dropped from 303 lines to 166. The orchestrator now
just composes BackButton, DocumentTopBarTitle, PersonChipRow,
OverflowPillButton, the details toggle, DocumentTopBarActions,
DocumentMobileMenu, and DocumentMetadataDrawer — each visual region
named in one or two words.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00