# Acceptance criteria and test plan **Status: proposed criteria — all implementation acceptance checks below are Not Tested in this investigation.** Existing tests were inspected, not executed. FlowCV evidence and Jobjakt source inspection establish design inputs, not production readiness. ## Acceptance criteria | ID | Measurable acceptance | Evidence to collect after implementation | |---|---|---| | AC-01 Document ownership | General/linked-application context is accurate. Local CV overrides never mutate career facts; reset-to-source is explicit | Unit plus E2E before/after source assertions; EN/NB screenshots | | AC-02 Candidate selection | Opening, selecting and cancelling a theme preview makes zero save requests. Late responses cannot replace the selected candidate. Apply changes only permitted visual values and is one undo step | Held-response tests; request counts; draft/content equivalence assertions | | AC-03 Editing/reorder | Existing typed/custom content, hide/reset/order survive template changes and reload. Every reorder works with Move up/down and retains focus with accurate position feedback | Unit tests; keyboard E2E; manual touch check | | AC-04 CV recovery | Saving, Saved, Retry and conflict states remain distinct. Stale save returns conflict and preserves recovery draft; blank name cannot silently persist | Existing readiness tests plus held/failure/conflict E2E | | AC-05 Preview accuracy | Real renderer sample labelled as sample. Current preview waits for fonts/images and ignores stale responses; failed refresh keeps labelled last-good output | Render/fragmentation tests; failure screenshot; PDF comparison | | AC-06 Complete letter revision boundary | Every letter mutation path records intended history atomically. Missing revision on mutation is 428; stale is 409. Existing null/clear semantics are preserved and no-op text save does not add history | Two-context relational concurrency tests covering every writer; DTO/client contract tests | | AC-07 Letter draft integrity | Typing, formatting, copying and AI Apply alter local draft until explicit Save. Failed save/navigation recovery preserves it. Restore creates a new text-and-settings version | Assets unit tests, held-save and restore E2E, old-version fixture | | AC-08 Letter copy/match | Core contact fields require reviewed copy; optional identity fields are not selected by default. Design mapping preserves body/recipient and is a snapshot independent of later CV edits/deletion | Field-selection tests, cancel tests, source-change test and screenshots | | AC-09 Export fidelity | Dirty draft is saved before export; failed or stale save yields no old-document download. PDF matches requested saved revision; foreign owner receives no output | API integration; byte/text markers; request-order E2E; manual PDF review | | AC-10 Historical integrity | Settings-history wording explains current-master resolution. Recorded application packages retain immutable content/artifacts; legacy text-only records still open | Source-mutation tests, exact-byte/hash package tests, copy review | | AC-11 Accessibility | Named buttons/fields, modal focus/return, visible focus, accurate errors and status announcements. All primary workflows usable by keyboard; inactive mobile pane excluded from focus/AX | Testing Library, axe triage, keyboard and screen-reader human checks | | AC-12 Responsive/localised | No application overflow or obscured primary action at 320/390/768/899/900/1024/1440px. EN/NB and light/dark remain usable at 200% text zoom; real keyboard does not cover active field | Width matrix; manual phone, browser zoom, long-label screenshots | | AC-13 Safe rendering/resources | Untrusted text cannot execute HTML/script or unsafe URLs/CSS. PDF honours bounded admission, timeout and cancellation without leaked work | Renderer security tests; resource/failure integration checks | | AC-14 Data portability | Current text, settings and history survive account export/backup round-trip; existing CSV/JSON data exports continue to work; owner filtering retained | Export/import fixtures, backward-compatible snapshot and owner tests | | AC-15 Release evidence | Exact commit and reproducible commands/results recorded. No automated result is described as human, real-device or production acceptance | Signed-off checklist listing tests run, skips, defects and release limitations | ## Existing tests to extend, not duplicate | Area | Inspected existing coverage | Future extension | |---|---|---| | CV editor/library | `job-tracker-ui/src/cv-builder-page.test.tsx` loading/retry/creation/locks/duplicate/conflict; `e2e/cv-editor-frame.spec.ts` editor save/undo/export/history/mobile | New context/history copy and named actions only where changed | | Controls/themes | `src/cv-document-controls.test.tsx`, `src/cvBuilder.test.ts`, `src/cv-template-gallery.test.tsx`, `src/cv-template-thumbnail.test.tsx` | Candidate cancel/apply/stale response; preserve existing capability and visual reset rules | | Preview/responsive | `e2e/cv-preview-presentation.spec.ts`, `cv-responsive-workflow.spec.ts`, `cv-pagination.spec.ts` | Inactive-pane focus; letter equivalent; shared readiness regression | | CV backend | `JobTrackerApi.Tests/CvBuilderTests.cs`, `CvRevisionReadinessTests.cs`, `PublicCvControllerTests.cs`, `CvExportRetentionTests.cs` | Reuse as regression gates; do not rewrite working CV services merely to add letters | | Letter editing | `job-tracker-ui/src/application-assets.test.tsx` explicit Apply/Save, reject, failed save, restore and ownership changes | Text/settings revision, cross-writer conflicts, preview and export ordering | | Letter/backend | `JobTrackerApi.Tests/ApplicationAssetsTests.cs` version/no-op/restore/owner/AI behaviour | Relational concurrency and writer bypass regression tests | | Document records | `SubmittedApplicationPackageTests.cs`, `DocumentsControllerTests.cs`; frontend document contracts | Designed-letter artifact snapshot, old record compatibility and portable data | Frontend paths abbreviated as `src`/`e2e` are under `job-tracker-ui`. Coverage listed is **Verified — test source exists**, not a pass result. Assertions must be checked against the final code and supported provider at execution time. ## Functional scenarios and fixtures Use synthetic names, roles and text only. Fixtures: empty career profile; one short CV; custom/hidden/overridden entries; 15-section long CV; two unrelated applications; two owners; old text-only letter/history/package; a designed letter; a missing/deleted attached CV; slow font/image; invalid Markdown links; long æ/ø/å text; 10-page letter; two tabs at one revision. 1. Create/open a CV with current supported themes; edit a local override; verify master unchanged; undo/redo; reload; export; restore settings with correct warning. 2. Open theme candidates, cancel, race two preview requests, retry failure, apply, undo/redo and verify content/metadata preservation. 3. Reorder first/middle/last sections and entries by keyboard controls, desktop drag and real touch alternatives. Check focus and actual announced positions. 4. Write letter, preview without saving, edit formatting, attempt navigation, cancel guard, save, reopen and restore. Repeat after failed save and application switch. 5. Copy reviewed contact details and compatible design separately; cancel both; change/delete source CV and verify no silent letter update. 6. Export a dirty letter while save is held, fails or conflicts. Download only the requested successful saved revision. Compare document markers in preview/PDF. 7. Capture an application package, change source data/design, reopen package and export account/backup data. Original record must remain immutable; capture must not imply delivery. ## Deliberate “Break Jobjakt” failure, abuse and resilience phase Run only in an approved disposable local/test environment after implementation. No load, destructive data or abuse testing against FlowCV or production is authorised by this research plan. | Challenge | Required behaviour / evidence | |---|---| | Two tabs save same CV revision | One accepted, stale edit conflicts; recovery draft retained; no blind retry loop | | Letter dedicated save races generic job update/draft update/restore | Exactly one intended revision wins; no silent overwrite or orphan history; other writer receives conflict | | Slow request finishes after user changes application/theme | Stale result ignored; no cross-application draft or preview leak | | Network drops during save/export | Unsaved text/settings retained; retry explicit; no false success or old-document export | | Server commits but client loses response | Reload/reconciliation identifies saved revision; repeat save cannot duplicate history unnecessarily | | Empty name, whitespace, reversed month/year, year-only date | Validated at actual trust boundary; precision semantics documented; error associated with field; no silent destructive normalisation | | Unknown theme, hidden capability, extreme numeric/CSS input | Server allowlists/clamps or rejects consistently; unsupported values cannot execute CSS or corrupt layout | | Script tags, unsafe URLs, Markdown nesting, huge links | Escaped/safe output, bounded work, no execution in preview/PDF | | Foreign owner job/CV/history/artifact id | No content, metadata or existence leakage beyond established policy; no writes | | Expired consent, exhausted plan, AI failure/cancel | Existing policy enforced; draft unchanged; stale proposal cannot apply after relevant data/revision changes | | Long Nordic text, oversized entry, slow/missing font/image | Physical pagination remains stable; visible error/last-good output where needed; export bounded | | Repeated PDF requests and cancelled clients | Admission and timeout enforced; browser/page resources cleaned; no unbounded new pool | | Delete source CV / update career profile after match | Saved letter remains a snapshot; CV history copy stays truthful; frozen records remain identical | | Legacy backup/versions missing settings; duplicate historic version rows | Defaults preserve readability; preflight blocks unsafe uniqueness migration; no automatic deletion | | Mobile keyboard, orientation, 200% text zoom, keyboard-only dialog | No obscured action or trapped focus; input selection/draft preserved; safe areas honoured | ## Verification levels and release gates **Gate A — source:** all writers/callers/DTOs/fixtures/exporters inventoried; planned contract reviewed. This investigation meets the research inventory boundary only. **Gate B — automated:** focused unit, supported relational integration and E2E checks pass on the final commit; include logs and test counts. Test doubles are not proof of production database concurrency. Axe findings are triage, not an accessibility certification. **Gate C — human:** keyboard and screen-reader walkthrough, real touch phone with keyboard, EN/NB copy review, and manually opened PDFs. Capture screenshots/results with synthetic data. Browser emulation is not real-device acceptance. **Gate D — release:** migration/data compatibility, rollback procedure, bounded performance and any production configuration checks approved separately. No production-readiness or security certification follows automatically from Gates A–C. ## Known research limits carried forward FlowCV resume initial creation, successful paid duplication, revision history, manual/pinch zoom, paid AI result quality, reload durability, all advanced controls, real phone input and downloaded PDF fidelity were not tested. Letter mobile and live resume-to-letter synchronisation were not tested. Jobjakt was inspected from source only; no app, tests, database, build or deployed behaviour was exercised. The complete proposal remains **Not Tested** until the gates above are met.