CI / changes (pull_request) Successful in 9s
CI / lint (pull_request) Successful in 1m14s
CI / frontend (pull_request) Successful in 2m19s
CI / backend (pull_request) Successful in 2m9s
CI / e2e (pull_request) Successful in 3m0s
CI / semgrep (pull_request) Successful in 1m5s
CI / api-client-drift (pull_request) Successful in 1m48s
CI / changes (push) Successful in 7s
CI / lint (push) Successful in 1m15s
CI / frontend (push) Successful in 2m15s
CI / storybook-a11y (pull_request) Successful in 13m11s
CI / backend (push) Successful in 2m10s
CI / e2e (push) Successful in 2m58s
CI / semgrep (push) Successful in 1m2s
CI / api-client-drift (push) Successful in 1m49s
CI / storybook-a11y (push) Successful in 10m36s
Catches drift accumulated since the Application → Aanvraag rename (Step 1/8, Step 2/8) plus the new tests from this branch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1366 lines
46 KiB
Plaintext
1366 lines
46 KiB
Plaintext
{/* GENERATED by `npm run gen:behaviour-spec` (scripts/gen-behaviour-spec.mjs) — do not
|
||
edit. Every bullet below is a real `it()` title or backend test method name, extracted
|
||
verbatim from the suite. The team rejected Cucumber/Gherkin for BDD scenarios (runtime string
|
||
matching undoes the compile-time guarantees WP-70 bought, and needs two frameworks for
|
||
.NET+TS) — this page is the replacement: business-readable documentation generated FROM test
|
||
names, so it can never drift from what the suite actually asserts. A test name changing (or a
|
||
test being added/removed) is the only way this page changes; hand-editing it is pointless,
|
||
the next `npm run gen:behaviour-spec` overwrites it. */}
|
||
|
||
import { Meta } from '@storybook/addon-docs/blocks';
|
||
|
||
<Meta title="Foundations/Behaviour spec" />
|
||
|
||
# Behaviour spec
|
||
|
||
_Generated by `npm run gen:behaviour-spec` — do not hand-edit; the next generation
|
||
overwrites this page. See [BDD](?path=/docs/foundations-bdd--docs) for how these names are
|
||
written, and [Testing strategy](?path=/docs/foundations-testing-strategy--docs) for what gets
|
||
tested where._
|
||
|
||
Every bullet below is a real test name from the suite — an `it()` title (frontend) or a test
|
||
method name (backend), read as a sentence. Nothing here is hand-written prose: this page
|
||
**is** the suite, reshaped for a business reader. 505 frontend behaviours across
|
||
9 contexts; 261 backend behaviours across 42 test
|
||
classes.
|
||
|
||
## Frontend (by context)
|
||
|
||
### auth
|
||
|
||
#### isAuthenticated
|
||
|
||
- narrows a present principal to Principal
|
||
- reports no principal as not authenticated
|
||
- narrows a present principal to Principal
|
||
- reports no principal as not authenticated
|
||
|
||
#### parseRollen
|
||
|
||
- parses a single recognized rol
|
||
- is case-insensitive and trims whitespace
|
||
- drops unrecognized tokens (the deny-path toggle, e.g. ?rollen=geen)
|
||
- returns an empty list for an empty string
|
||
|
||
#### parseStoredPrincipal
|
||
|
||
- returns null when nothing is stored
|
||
- returns null for a non-JSON string
|
||
- returns null when the stored shape is wrong (no naam)
|
||
- returns null when kind is not medewerker
|
||
- returns null when rollen holds an unrecognized token
|
||
- restores a well-shaped stored principal as-is (no BSN to strip)
|
||
- returns null when nothing is stored
|
||
- returns null for a non-JSON string
|
||
- returns null when the stored shape is wrong (no naam)
|
||
- G1: a stored bsn is never restored, even if present in the raw value
|
||
|
||
### behandeling
|
||
|
||
#### besluit reduce
|
||
|
||
- SetField updates the draft while editing
|
||
- Submit with no besluit chosen stays Editing and reports a field error
|
||
- Submit Afwijzen without a toelichting stays Editing and reports a field error
|
||
- Submit Goedkeuren with no toelichting moves to Submitting (optional there)
|
||
- Submit Afwijzen with a toelichting moves to Submitting with the trimmed value
|
||
- SubmitConfirmed maps Submitting to Submitted
|
||
- SubmitFailed maps Submitting to Failed with the error
|
||
- Retry re-submits a failure
|
||
- Reset returns to the initial editing state
|
||
|
||
#### detailRows
|
||
|
||
- lists soort/status/referentie/eigenaar/ingediend
|
||
- a reden row is present only for Afgewezen and MeerInfoGevraagd
|
||
|
||
#### parseBeoordelingStatus
|
||
|
||
- parses each tag with its required fields
|
||
- rejects a malformed status
|
||
|
||
#### parseBeoordelingView
|
||
|
||
- maps a valid DTO to domain
|
||
- rejects a malformed view
|
||
- defaults an absent documenten list to empty
|
||
|
||
#### parseWerkvoorraad
|
||
|
||
- parses a list and fails fast on a bad element
|
||
|
||
#### parseWerkvoorraadItem
|
||
|
||
- parses Ingediend and InBehandeling
|
||
- rejects a case whose status is not an open queue tag
|
||
- rejects a missing owner, bad type, and non-objects
|
||
|
||
#### statusLabel
|
||
|
||
- labels every tag distinctly
|
||
|
||
#### werkvoorraadRow
|
||
|
||
- heading is the type, subtitle carries the owner BSN
|
||
- status line carries the status label, reference and submit date
|
||
- manual review is called out distinctly from an automatic InBehandeling
|
||
- a missing submit date leaves no dangling separator
|
||
|
||
### beheer
|
||
|
||
#### StamdataStore undo/redo (WP-32)
|
||
|
||
- records a cell edit, undoes and redoes it
|
||
- records addRow and undoes it
|
||
- clears history when switching table
|
||
|
||
#### StamdataStore.download (RB-28)
|
||
|
||
- does not call the presenter while the two-clause guard blocks (nothing dirty yet)
|
||
- does not call the presenter while previewing a date, even with edits
|
||
- passes toJson(...)'s exact output and the table id as the filename (success path)
|
||
|
||
#### activeOn (valid-time, half-open [van, tot))
|
||
|
||
- includes a row whose window covers the date
|
||
- excludes a row before its geldigVan
|
||
- excludes on the geldigTot boundary (half-open)
|
||
|
||
#### changeCounts (diff against the loaded snapshot, by key)
|
||
|
||
- counts an added key
|
||
- counts a removed key
|
||
- counts an edited cell
|
||
|
||
#### parseStamdataTable
|
||
|
||
- maps schema + rows and turns a null cell into empty text
|
||
- falls back to text for an unknown column type
|
||
- rejects a response with no columns
|
||
|
||
#### rowErrors / isValid (format only)
|
||
|
||
- flags a blank key
|
||
- flags a missing geldigVan on a temporal table
|
||
- flags geldigTot on or before geldigVan
|
||
- passes a well-formed row
|
||
|
||
#### stamdata-editor reduce
|
||
|
||
- Loaded snapshots original independently of rows
|
||
- RowAdded appends an empty row shaped by the schema
|
||
- RowRemoved drops the row at the index
|
||
- edit messages are ignored unless loaded
|
||
- LoadFailed and Loading transition regardless of prior state
|
||
|
||
#### toJson (draft → file shape)
|
||
|
||
- reconstructs an open-ended geldigTot as null and pretty-prints
|
||
- coerces a number column
|
||
|
||
### brief
|
||
|
||
#### BriefStore action state (Idle | Busy | Failed)
|
||
|
||
- is Busy synchronously once a transition starts
|
||
- settles to Idle on a successful transition
|
||
- goes Busy then Failed on a failing transition, surfacing the error
|
||
- a subsequent successful transition clears a prior Failed state
|
||
|
||
#### BriefStore rejection diff
|
||
|
||
- captures the rejected letter and diffs a subsequent edit against it
|
||
|
||
#### BriefStore undo/redo history
|
||
|
||
- starts with nothing to undo
|
||
- records an edit and makes it undoable
|
||
- undo reverts the edit and enables redo
|
||
- redo reapplies the undone edit
|
||
- a no-op edit does not clear the redo future
|
||
- a new edit clears the redo future
|
||
- caps history at 50 snapshots
|
||
|
||
#### BriefStore.flushPending (CanDeactivate guard / beforeunload)
|
||
|
||
- flushes a pending debounced edit immediately and clears the pending flag
|
||
- is a no-op when no edit is pending
|
||
|
||
#### BriefStore.load — 404 tolerance (RB-22)
|
||
|
||
- a 404 drives exactly one reset(), which populates the store
|
||
- a second 404 does not drive a second reset()
|
||
|
||
#### BriefStore.previewLetter
|
||
|
||
- opens the composed letter via BLOB_PRESENTER on success (RB-28)
|
||
- surfaces the error without opening a tab on failure
|
||
|
||
#### BriefStore.revealBigNummer (PRD-0002 §5c)
|
||
|
||
- swaps the masked value for the revealed one on success
|
||
- keeps the value masked and surfaces the error on failure
|
||
|
||
#### LetterPreviewAdapter.preview (BIO-012)
|
||
|
||
- sends no X-Role/X-Subject headers outside isDevMode()
|
||
- sends X-Role (and X-Subject when known) under isDevMode()
|
||
|
||
#### OrgTemplateStore.proefbrief (RB-28)
|
||
|
||
- opens the rendered proefbrief via BLOB_PRESENTER on success
|
||
- surfaces the error without opening a tab on failure
|
||
|
||
#### RevealBigNummerAdapter.reveal (BIO-006a + BIO-012)
|
||
|
||
- sends X-Step-Up only when the caller passes stepUp: true
|
||
- sends X-Role only under isDevMode()
|
||
|
||
#### besluitGuidance
|
||
|
||
- positief: counts inserted passages, no reden needed (positief has no redenen)
|
||
- negatief without a reden: flags that a reden must be chosen
|
||
- negatief with a reden: no longer flags, and the reason passage is counted
|
||
|
||
#### brief selectors
|
||
|
||
- unresolvedPlaceholders returns deduped manual keys only (auto excluded)
|
||
- allDiagnostics flattens across sections and blocks
|
||
- canSubmit is false when a required section is empty, true otherwise
|
||
|
||
#### brief.adapter parse boundary
|
||
|
||
- parses a well-formed view into the domain unions
|
||
- rejects a view whose case context is missing or malformed
|
||
- parses the org template and drops a null logoDocumentId
|
||
- rejects a view whose org template is missing or malformed
|
||
- rejects a view whose decisions are missing or malformed
|
||
- narrows node variants and rejects unknown ones
|
||
- rejects a status DTO missing its required fields
|
||
- reads section.locked (default false) and paragraph.list
|
||
- rejects a library passage with an unknown scope
|
||
- rejects a passage block missing provenance
|
||
|
||
#### brief.machine reduce
|
||
|
||
- BriefLoaded moves loading to loaded
|
||
- BriefLoadFailed moves loading to failed with the reason
|
||
- Seed sets the state directly
|
||
- BesluitSelected composes the kern: the besluit passages, in reading order, as frozen local blocks
|
||
- BesluitSelected swaps the passages when the selection changes, keeping free text
|
||
- BesluitSelected deep-copies content — later library mutation does not leak in
|
||
- FreeTextBlockAdded appends an empty free-text block
|
||
- BlockContentEdited replaces content and marks a passage block edited
|
||
- BlockMovedWithinSection reorders blocks within a section
|
||
- BlockRemoved drops a block from a section
|
||
- edits to a locked section are no-ops (besluit, free-text, content, remove, move)
|
||
- edits are no-ops once submitted (status invariant)
|
||
- editing a rejected letter reopens it to draft
|
||
- Submitted fires only from draft and only when required sections are filled
|
||
- approve fires only from submitted
|
||
- reject fires from submitted, carrying comments
|
||
- send fires only from approved
|
||
- a status transition replaces decisions with the fresh server value
|
||
|
||
#### diffBlocks
|
||
|
||
- marks added, removed, changed and unchanged by blockId
|
||
- changedBlocks drops unchanged and keeps added/removed/changed
|
||
|
||
#### errorMessage (TE-002 trust boundary)
|
||
|
||
- surfaces the ProblemDetails detail when present
|
||
- falls back to PREVIEW_FAILED when the body has no detail
|
||
- falls back to PREVIEW_FAILED when the body is not JSON
|
||
|
||
#### inferSelection
|
||
|
||
- round-trips a positief selection
|
||
- round-trips a negatief selection with redenen (in order)
|
||
- an empty kern (nothing chosen) infers no besluit
|
||
- ignores free-text blocks and unknown passage ids
|
||
|
||
#### lintPlaceholders
|
||
|
||
- clean content (auto-resolvable, fillable, current key) yields no diagnostics
|
||
- flags an unknown key as an error
|
||
- flags a not-fillable key as an error
|
||
- flags a deprecated key as a warning
|
||
- flags a manual placeholder as unresolved-at-send (warning)
|
||
- flags raw braces in text as malformed (paste safety net)
|
||
- returns diagnostics in document order across paragraphs/nodes
|
||
- severityOf maps each code to its policy
|
||
|
||
#### org-template.machine
|
||
|
||
- DraftLoaded moves to loaded with the draft, clean
|
||
- LoadFailed carries the reason
|
||
- FieldEdited edits the draft and marks dirty
|
||
- MarginEdited edits one edge and marks dirty
|
||
- DraftSaved clears dirty when the saved draft is the current one
|
||
- DraftSaved keeps dirty when an edit landed during the save round-trip
|
||
- edits are no-ops in non-loaded states
|
||
- a completed logo upload sets logoDocumentId + dirty
|
||
- removing the logo clears logoDocumentId + dirty
|
||
- DraftLoaded (sub-org switch) keeps the loaded logo category, drops uploads
|
||
|
||
#### parseOrgTemplateAdminView
|
||
|
||
- parses a well-formed admin view
|
||
- rejects a missing draft
|
||
- rejects a missing count field
|
||
- rejects a malformed history entry
|
||
|
||
#### parseRevealed (TE-002 trust boundary)
|
||
|
||
- accepts a well-formed body
|
||
- rejects a bigNummer sent as a number
|
||
- rejects a missing bigNummer field
|
||
- rejects null and non-object bodies
|
||
|
||
#### passagesForBesluit
|
||
|
||
- positief = shared intro + the positief passage, no negatief/reason passages
|
||
- negatief without redenen = intro + negatief base, but no reason-specific passages
|
||
- negatief with a reden ticked includes that reason-specific passage only
|
||
- preserves library order (= reading order)
|
||
- never offers non-kern passages
|
||
|
||
#### proefbriefErrorMessage (TE-002 trust boundary)
|
||
|
||
- surfaces the ProblemDetails detail when present
|
||
- falls back to PROEFBRIEF_FAILED when the body has no detail
|
||
- falls back to PROEFBRIEF_FAILED when the body is not JSON
|
||
|
||
#### redenenFor
|
||
|
||
- derives reason checkboxes (code + label) from the negatief reason passages
|
||
- positief has no reason-specific redenen
|
||
|
||
### herregistratie
|
||
|
||
#### IntakeWizardComponent
|
||
|
||
- renders each field group as its own grey <fieldset>
|
||
|
||
#### STEPS (fixed) and inline questions
|
||
|
||
- always has the same three steps
|
||
- reveals the buitenland detail questions inline only when worked abroad
|
||
- reveals the scholing question only when NL-hours are below the threshold
|
||
- uses the (server-owned) threshold passed in, not a hardcoded constant
|
||
|
||
#### herregistratie hasProgress
|
||
|
||
- is false for a fresh form
|
||
- is true once a field is filled or the user advances
|
||
|
||
#### intake acceptance journeys
|
||
|
||
- high uren, no buitenland werk: no scholing question, straight through to Submitted
|
||
- low uren requires the scholing question, and punten only once scholing is followed
|
||
- buitenland gewerkt requires land and hours abroad before advancing
|
||
- gaNaarStap corrects an earlier answer without losing later ones
|
||
- raising uren above the threshold after answering scholing drops both fields (WP-69 §6)
|
||
- SetPolicy (server-owned threshold) can turn an already-answered uren into one that now requires scholing
|
||
|
||
#### intake hasProgress
|
||
|
||
- is false for a fresh questionnaire
|
||
- is true once an answer is given or the user advances
|
||
|
||
#### intake-policy.adapter parse boundary
|
||
|
||
- parses a well-formed policy
|
||
- rejects a missing or non-numeric threshold
|
||
|
||
#### navigation
|
||
|
||
- Next is a no-op (sets an error) when the current step is invalid
|
||
- Next advances once the step is valid
|
||
- editing an answer leaves the cursor fixed (steps never collapse)
|
||
- Back never goes below the first step
|
||
- gaNaarStap jumps back to an earlier step, clearing errors
|
||
- gaNaarStap ignores a same/forward jump and jumps outside Answering
|
||
|
||
#### reduce (message-driven happy path)
|
||
|
||
- drives abroad branch end to end
|
||
|
||
#### reduce (message-driven)
|
||
|
||
- drives the full happy path via messages
|
||
- blocks submit until required documents are satisfied
|
||
- SubmitFailed then Retry returns to Submitting with the same data
|
||
- Seed mounts an arbitrary state
|
||
|
||
#### submit
|
||
|
||
- reaches Submitting ONLY with valid answers
|
||
- punten is required only when aanvullende scholing was gevolgd
|
||
- low hours requires the scholing answer before submit
|
||
- does not require punten for a hidden question (WP-69 §6)
|
||
- drops punten when raising uren hides the question (WP-69 §6)
|
||
- resolve maps Submitting to Submitted on a successful submit
|
||
- resolve maps Submitting to Failed on a failed submit
|
||
|
||
#### wizard.machine
|
||
|
||
- next advances only when step 1 parses
|
||
- next advances step 2 → 3 only when punten parses
|
||
- submit reaches Submitting ONLY from step 3 with fully valid data
|
||
- next requires BOTH step-1 fields (uren and jaren)
|
||
- back steps down one (3 → 2 → 1) and is a no-op from step 1
|
||
- resolve maps a successful Submitting to Submitted
|
||
- resolve maps a failing Submitting to Failed
|
||
- gaNaarStap jumps back to an earlier step, clearing errors
|
||
- gaNaarStap ignores a same/forward jump and jumps outside Editing
|
||
|
||
### registratie
|
||
|
||
#### AanvragenStore
|
||
|
||
- loads and parses the list
|
||
- cancels optimistically and confirms via the DELETE endpoint
|
||
- rolls back the removal and surfaces the error when the cancel fails
|
||
- clears a stale error on the next cancel attempt
|
||
|
||
#### AdminCasesStore
|
||
|
||
- loads and parses the cross-owner list
|
||
- deletes optimistically and confirms via the admin endpoint
|
||
- rolls back the removal and surfaces the error when the delete fails
|
||
- clears a stale error on the next delete attempt
|
||
|
||
#### STEPS (fixed)
|
||
|
||
- always has the same three steps
|
||
|
||
#### adres origin (BRP vs handmatig)
|
||
|
||
- prefillAdres flags origin brp
|
||
- editing a prefilled address field flips origin to handmatig
|
||
- typing an address with no BRP prefill yields handmatig
|
||
- editing the e-mail field does not change the address origin
|
||
- a manually entered address still submits (only manual diploma is gated)
|
||
|
||
#### big-register.adapter parse boundary
|
||
|
||
- parses known aantekening types
|
||
- rejects an unknown type
|
||
|
||
#### blockActions
|
||
|
||
- a Concept can be resumed or cancelled
|
||
- an in-behandeling aanvraag only exposes its documents
|
||
- ingediend and meer-info-gevraagd behave like in-behandeling
|
||
- resolved aanvragen have no actions
|
||
|
||
#### change-request reduce
|
||
|
||
- SetField updates the draft while editing
|
||
- Submit with an invalid draft stays Editing and reports field errors
|
||
- Submit with a valid draft moves to Submitting with parsed (normalised) data
|
||
- SubmitConfirmed maps Submitting to Submitted with the referentie
|
||
- SubmitFailed maps Submitting to Failed with the error
|
||
- Retry re-submits a failure
|
||
- Reset returns to the initial editing state
|
||
|
||
#### createDraftSync
|
||
|
||
- coalesces rapid snapshot changes into ONE debounced sync of the latest value
|
||
- a trailing change after the debounce fires schedules its own sync
|
||
|
||
#### createDraftSync › flushPending (CanDeactivate guard / beforeunload)
|
||
|
||
- hasPendingSave reflects an armed debounce timer
|
||
- flushPending writes the pending draft immediately, before the debounce fires
|
||
- flushPending is a no-op when nothing is pending
|
||
|
||
#### createDraftSync › submit
|
||
|
||
- resolves ok with the server response on success
|
||
- folds a rejected submit into a Result error, never throwing
|
||
- recovers from a create conflict by adopting the existing Concept (WP-35)
|
||
|
||
#### createSubmitChangeRequest
|
||
|
||
- resolves ok with the referentie on success
|
||
- folds a rejected call into a Result error, never throwing
|
||
- surfaces a ProblemDetails detail message when the server rejects with one
|
||
|
||
#### detailRows
|
||
|
||
- lists soort/waarvoor/status/referentie/ingediend, plus reason when rejected
|
||
- reference falls back to em dash for a Concept
|
||
|
||
#### findConcept
|
||
|
||
- returns the id of the existing Concept of the given type
|
||
- returns undefined when the list has no application of the given type
|
||
- returns undefined when the matching type is not a Concept
|
||
- returns undefined when adapter.list() resolves with an unparsable shape
|
||
- returns undefined when adapter.list() rejects
|
||
|
||
#### hasProgress
|
||
|
||
- is false for a fresh wizard
|
||
- ignores an auto-prefilled BRP address at step 0
|
||
- is true once the user advances, picks correspondence/diploma, or is past step 0
|
||
|
||
#### inline document upload (beroep step)
|
||
|
||
- routes Upload messages through the upload reducer
|
||
- blocks the beroep step until a required category is satisfied
|
||
- includes delivery refs in the submitted data
|
||
|
||
#### kiesDiploma
|
||
|
||
- derives the beroep from the chosen diploma and flags origin duo
|
||
|
||
#### loadConcept
|
||
|
||
- reads the draft off a Concept
|
||
- reports a missing draft as null
|
||
- reports not-concept when the id has moved past Concept (submitted)
|
||
- reports not-concept when the id is unknown or deleted (detail rejects)
|
||
|
||
#### manual diploma fallback
|
||
|
||
- KiesHandmatig flags handmatig with the maximal question set and no beroep yet
|
||
- requires a declared beroep + all maximal questions before submit
|
||
|
||
#### navigation
|
||
|
||
- Next is a no-op (sets errors) when the adres step is invalid
|
||
- Next advances once the adres step is valid
|
||
- requires a valid e-mail only when the channel is email
|
||
- beroep step requires a chosen diploma
|
||
- Back never goes below the first step and preserves the draft
|
||
- GaNaarStap only jumps backwards
|
||
|
||
#### parseAanvraagStatus
|
||
|
||
- parses each tag with its required fields
|
||
- rejects a missing status, unknown tag, and wrong-typed fields
|
||
|
||
#### parseAanvraagSummary
|
||
|
||
- maps a valid DTO to domain
|
||
- rejects a bad type and non-objects
|
||
|
||
#### parseAanvragen / parseAanvraagDetail
|
||
|
||
- parses a list and fails fast on a bad element
|
||
- carries the opaque draft through detail
|
||
|
||
#### parseBigNummer
|
||
|
||
- accepts exactly 11 digits, trimming whitespace
|
||
- rejects wrong length or non-digits
|
||
|
||
#### parseBrpAddress (trust boundary)
|
||
|
||
- accepts a found address
|
||
- accepts "geen adres" (gevonden: false) as a valid outcome
|
||
- rejects malformed responses
|
||
|
||
#### parseDashboardView (trust boundary)
|
||
|
||
- maps a valid response into a DashboardView
|
||
- rejects malformed responses instead of trusting them
|
||
- rejects a status whose tag is present but its required fields are missing
|
||
- rejects an unknown status tag
|
||
- rejects a person with an incomplete adres
|
||
|
||
#### parseDuoLookup (trust boundary)
|
||
|
||
- maps a valid lookup (diplomas + manual fallback)
|
||
- accepts an empty diploma list (forces manual entry)
|
||
- rejects malformed responses
|
||
|
||
#### parseEmail
|
||
|
||
- accepts a well-formed address and trims it
|
||
- rejects malformed addresses
|
||
|
||
#### parsePostcode
|
||
|
||
- normalises to "1234 AB" (uppercase, single space, trimmed)
|
||
- rejects malformed postcodes
|
||
|
||
#### parseTelefoonnummer
|
||
|
||
- accepts a 10-digit number starting 0 and strips formatting
|
||
- normalises a +31 prefix to a leading 0
|
||
- rejects a too-short number, a non-0 start, and junk
|
||
|
||
#### parseUren
|
||
|
||
- accepts non-negative whole numbers, including 0
|
||
- rejects empty, negative, and non-integer input
|
||
|
||
#### policy questions (geldigheidsvragen)
|
||
|
||
- a diploma with questions blocks Next until they are answered
|
||
- validateAll keeps only the answers to the questions that applied
|
||
|
||
#### reduce (message-driven happy path)
|
||
|
||
- adres and correspondentie set, Next advances from adres to beroep
|
||
- diploma chosen, Next advances from beroep to controle
|
||
- Submit moves a complete Invullen draft to Indienen
|
||
- SubmitConfirmed moves Indienen to Ingediend
|
||
- SubmitFailed moves Indienen to Mislukt
|
||
- Retry returns Mislukt to Indienen with the same data
|
||
|
||
#### registration.policy
|
||
|
||
- statusLabel echoes the tag
|
||
- statusColor is total over the union
|
||
- herregistratieDeadline is only set for an active registration
|
||
|
||
#### sortForDashboard / concepten / ingediend
|
||
|
||
- sorts Concept, then still-open, then resolved last
|
||
- does not mutate the input array
|
||
- concepten/ingediend split on the Concept tag
|
||
|
||
#### submit
|
||
|
||
- stays in Invullen when the draft is incomplete (no diploma)
|
||
- reaches Indienen with a complete, valid draft, carrying its data
|
||
- resolve maps Indienen to Ingediend with the referentie
|
||
- resolve maps Indienen to Mislukt on a failed submit
|
||
|
||
#### submittedRow
|
||
|
||
- heading is the type, subtitle is the purpose
|
||
- status line carries the status label, reference and submit date
|
||
- manual review adds a note
|
||
- rejection adds its reason
|
||
- meer-info-gevraagd adds its reason, like a rejection
|
||
|
||
#### tasksFromProfile
|
||
|
||
- offers herregistratie when the server says eligible, with the formatted deadline
|
||
- offers nothing when the server says not eligible
|
||
- surfaces a notice for a suspended registration (independent of eligibility)
|
||
- surfaces a notice for a struck-off registration
|
||
|
||
### shared
|
||
|
||
#### BackgroundUploadsReturned
|
||
|
||
- resolves each in-flight upload to complete or failed
|
||
|
||
#### CategoriesLoadFailed / BackgroundSyncAvailability
|
||
|
||
- records the error
|
||
- flips background sync availability
|
||
|
||
#### CategoriesLoaded
|
||
|
||
- defaults every category to digital without clobbering existing choices
|
||
- clears a prior categoriesError
|
||
- drops uploads + channel choices for categories that disappear
|
||
|
||
#### DeliveryChannelChanged
|
||
|
||
- switching to post removes that category uploads
|
||
- rejects post for a category that does not allow it
|
||
- switching back to digital starts clean
|
||
|
||
#### FileRejected
|
||
|
||
- stores a per-category message
|
||
|
||
#### FileSelected
|
||
|
||
- queues a new upload and clears any rejection for that category
|
||
- ignores selection for an unknown category
|
||
- ignores selection for a category set to post-delivery
|
||
- single-file category: a new selection replaces the existing upload
|
||
- multiple category: selections accumulate
|
||
|
||
#### PendingSaves registry
|
||
|
||
- hasPending is true only while some registered owner has a pending write
|
||
- unregister removes an owner so it no longer counts
|
||
- flushAll flushes only the pending owners
|
||
- flushAll awaits every owner and swallows a rejected flush
|
||
|
||
#### RemoteData combinators
|
||
|
||
- map only touches Success
|
||
- map2 precedence: Failure > Loading > Success
|
||
|
||
#### UploadShellService.cancel
|
||
|
||
- calls the transport cancel function for an in-flight upload and forgets it
|
||
- is a no-op for a localId with nothing in flight
|
||
|
||
#### UploadShellService.delete
|
||
|
||
- dispatches UploadDeleting, then UploadDeleteComplete on success
|
||
- dispatches UploadDeleteFailed with the server detail on failure
|
||
- falls back to an empty reason when the server sends no detail
|
||
|
||
#### UploadShellService.pollReturning
|
||
|
||
- does nothing when there are no uploads to poll
|
||
- dispatches BackgroundUploadsReturned for uploads the server reports complete
|
||
- does not dispatch when nothing has arrived yet
|
||
|
||
#### UploadShellService.upload
|
||
|
||
- dispatches UploadQueued with the transport backgroundSync flag, then sends via the transport
|
||
- translates a progress callback into UploadProgress
|
||
- translates a resolved transport into UploadComplete
|
||
- translates a rejected transport into UploadFailed with the reason
|
||
- does not dispatch UploadFailed on a user-initiated abort
|
||
|
||
#### authGuard
|
||
|
||
- allows an authenticated user
|
||
- redirects an anonymous user to /login
|
||
|
||
#### capabilityGuard
|
||
|
||
- waits for /me, then allows an entitled admin
|
||
- sends an authenticated-but-unentitled user to /dashboard (not a login loop)
|
||
- redirects an anonymous user to /login without waiting for caps
|
||
- reads authentication through the port, not an app-local store
|
||
|
||
#### createDebouncedSave
|
||
|
||
- flushes after the delay when canSave is true
|
||
- does not schedule when canSave is false
|
||
- coalesces rapid schedules into a single flush
|
||
- flushPending runs the save immediately and clears; no-op when idle
|
||
- cancel drops a scheduled save without running it
|
||
|
||
#### createHistory
|
||
|
||
- starts empty; undo/redo are no-ops
|
||
- records pre-edit snapshots, then undoes and redoes through them
|
||
- record() clears the redo stack (no dead redo after a fresh edit)
|
||
- caps the stack depth
|
||
- clear() empties both stacks
|
||
|
||
#### createStore
|
||
|
||
- applies the pure update on dispatch
|
||
- dispatch from inside an effect does not self-loop
|
||
|
||
#### currentRole (dev mechanism)
|
||
|
||
- lists the three roles
|
||
- reads a valid ?role= from the URL and persists it for the tab
|
||
- falls back to drafter when nothing is set or the value is invalid
|
||
|
||
#### currentRole (dev mechanism) › outside isDevMode() (production build)
|
||
|
||
- ignores a ?role= in the URL and returns the default
|
||
- never touches sessionStorage
|
||
- ignores a role already sitting in sessionStorage from a prior dev session
|
||
|
||
#### currentSubject (dev mechanism)
|
||
|
||
- reads a ?subject= from the URL and persists it for the tab
|
||
- returns undefined when nothing has ever been set
|
||
|
||
#### currentSubject (dev mechanism) › outside isDevMode() (production build)
|
||
|
||
- ignores a ?subject= (a BSN) in the URL and returns undefined
|
||
- never writes the BSN into sessionStorage
|
||
- ignores a subject already sitting in sessionStorage from a prior dev session
|
||
|
||
#### delete flow (optimistic, revertible)
|
||
|
||
- UploadDeleteRequested keeps the documentId for revert
|
||
- UploadDeleteComplete removes the upload
|
||
- UploadDeleteFailed reverts to complete with the original documentId
|
||
|
||
#### deliveryRefs
|
||
|
||
- emits documentId for completed digital uploads and channel for post
|
||
- omits digital categories with no completed upload
|
||
|
||
#### flushPendingGuard
|
||
|
||
- flushes then allows navigation when a write is pending
|
||
- allows navigation immediately when nothing is pending
|
||
|
||
#### formatDatumNl
|
||
|
||
- formats a Date in long Dutch form
|
||
- formats an ISO string the same way
|
||
- is empty-safe: undefined, null, and empty string all yield the empty string
|
||
- returns empty for an unparseable string rather than "Invalid Date"
|
||
|
||
#### httpClientFetch
|
||
|
||
- sends the pending idempotency key as a header for a write, not a fresh one per attempt
|
||
- retries a failing GET twice before giving up
|
||
- never retries a failing write
|
||
|
||
#### inFlight
|
||
|
||
- returns only queued/uploading uploads
|
||
|
||
#### localeLinks (nl at root, en under /en/)
|
||
|
||
- an nl route (no prefix) links nl to the bare path, en under /en, marks active
|
||
- an en route strips the /en prefix for the nl target (deep path, en active)
|
||
- keeps query + hash on both targets
|
||
- the root maps nl → / and en → /en/
|
||
|
||
#### machineRemoteData
|
||
|
||
- maps loading → Loading
|
||
- maps failed → Failure carrying an Error with the reason
|
||
- maps loaded → Success carrying the whole loaded state
|
||
|
||
#### parseBsn (elfproef)
|
||
|
||
- accepts a valid BSN (passes the elfproef)
|
||
- rejects a 9-digit number that fails the elfproef
|
||
- rejects wrong length / non-digits / all zeros
|
||
|
||
#### parseMe (trust boundary)
|
||
|
||
- parses a known capability list
|
||
- parses an empty list (drafter — no capabilities)
|
||
- recognizes the admin org-template capability (WP-23)
|
||
- recognizes the behandelportal besluit capability (WP-66)
|
||
- drops unrecognized capability strings instead of rejecting the response
|
||
- rejects malformed responses instead of trusting them
|
||
|
||
#### pii maskers
|
||
|
||
- maskBsn keeps the last 3 digits
|
||
- maskTail keeps the requested tail length
|
||
- masks the whole value when it is not longer than the kept tail
|
||
|
||
#### planFileSelection
|
||
|
||
- plans nothing for an unknown category
|
||
- rejects the whole batch with reason "multiple" for a single-file category
|
||
- does not reject a single file against a single-file category
|
||
- rejects one file via rejectReason (wrong type)
|
||
- rejects one file via rejectReason (too large)
|
||
- plans a FileSelected entry for a file that passes format validation
|
||
- judges each file independently and preserves order for a mixed multiple-file category
|
||
|
||
#### problemDetail
|
||
|
||
- extracts the detail from an RFC-7807 ProblemDetails
|
||
- falls back when there is no detail
|
||
|
||
#### problemFieldErrors (G4 seam)
|
||
|
||
- maps a ValidationProblemDetails errors dict to first-message-per-field
|
||
- returns {} when there is no errors envelope (the current backend shape)
|
||
|
||
#### rejectReason
|
||
|
||
- rejects a disallowed type
|
||
- rejects an oversized file
|
||
- accepts a valid file
|
||
- allows any type when the category lists none
|
||
|
||
#### rich-text
|
||
|
||
- emptyBlock is one empty paragraph and reads as empty
|
||
- isBlockEmpty is false when any placeholder or non-blank text exists
|
||
- placeholderKeysIn walks in document order, keeping duplicates
|
||
- deepCopyBlock is an independent value copy (frozen snapshot)
|
||
|
||
#### rich-text DOM boundary
|
||
|
||
- round-trips text, marks, placeholders, line breaks and multiple paragraphs
|
||
- round-trips an empty paragraph (filler <br> is not a line break)
|
||
- renders a placeholder as a non-editable chip carrying its key and label
|
||
- reads combined marks in canonical order regardless of nesting
|
||
- round-trips bullet and numbered lists mixed with paragraphs
|
||
- groups consecutive same-kind list lines into one <ul>/<ol>
|
||
- adjacentChip finds a chip next to a collapsed caret so Backspace/Delete can remove it
|
||
- marks auto-resolvable vs manual chips with data-auto for styling
|
||
|
||
#### roleInterceptor
|
||
|
||
- leaves an unrelated endpoint untouched
|
||
|
||
#### runResult
|
||
|
||
- folds a resolved call into ok(value)
|
||
- maps a ProblemDetails rejection to err(detail)
|
||
- falls back when the rejection has no detail
|
||
- mints no Idempotency-Key — the read fold
|
||
|
||
#### runSubmit
|
||
|
||
- folds a resolved call into ok(value)
|
||
- maps a ProblemDetails rejection to err(detail)
|
||
- falls back when the rejection has no detail
|
||
- mints exactly one Idempotency-Key for the whole call — the write fold
|
||
|
||
#### satisfaction helpers
|
||
|
||
- a post-delivery choice satisfies a required category
|
||
- an active upload satisfies a required category
|
||
- a failed upload does not satisfy a required category
|
||
- requiredCategoriesSatisfied ignores optional categories
|
||
|
||
#### scenario (dev mechanism)
|
||
|
||
- reads a valid ?scenario= from the URL and persists it for the tab
|
||
- falls back to default when nothing is set or the value is invalid
|
||
- setScenario persists the chosen scenario
|
||
|
||
#### stripDevParams (WP-37)
|
||
|
||
- removes ?scenario and ?role so the stored dev value wins on reload
|
||
- keeps unrelated query params and the path/hash
|
||
- is a no-op when neither param is present
|
||
|
||
#### subjectInterceptor
|
||
|
||
- stamps X-Subject on an /api/v1/ request once ?subject= has been seen
|
||
- keeps stamping later requests on the same tab after the query param is gone (WP-33-style stickiness)
|
||
- leaves a non-API request untouched even when a subject is known
|
||
- sends no header at all when no subject has ever been seen
|
||
|
||
#### successOf
|
||
|
||
- unwraps a Success value
|
||
- is undefined for every other state
|
||
|
||
#### upload lifecycle messages
|
||
|
||
- queued → progress → complete
|
||
- failed then retried returns to queued
|
||
- UploadRemoved drops the upload
|
||
|
||
#### uploadOutcome
|
||
|
||
- resolves a 2xx response with a valid JSON body to the document id
|
||
- falls back to the generic error when a 2xx body is not valid JSON
|
||
- maps a non-2xx ProblemDetails body to its detail
|
||
- falls back to the generic error for a non-2xx body without a ProblemDetails detail
|
||
- treats status 200-299 as success and everything else as failure
|
||
|
||
#### withIdempotencyKey / currentIdempotencyKey
|
||
|
||
- threads the key to every read made inside the wrapped fn
|
||
- clears the key once the wrapped fn settles
|
||
- falls back to a generated uuid-shaped key when none is pending
|
||
|
||
### shell
|
||
|
||
#### redactProfile
|
||
|
||
- masks the BIG-nummer to its last 3 digits
|
||
- redacts the name on both the registration and the person
|
||
- redacts every date of birth
|
||
- redacts the address
|
||
- keeps structural/decision-relevant fields untouched
|
||
|
||
### showcase
|
||
|
||
#### highlightTs
|
||
|
||
- wraps keywords, strings and comments in the styling spans
|
||
- escapes HTML metacharacters so the [innerHTML] sink is safe
|
||
- treats the whole // tail as one comment (keywords after // are not re-highlighted)
|
||
|
||
## Backend (by test class)
|
||
|
||
### AanvraagTests
|
||
|
||
- Create then list shows a concept with step progress
|
||
- Draft sync is readable back from detail
|
||
- Submit duo registratie is in behandeling and auto
|
||
- Submit handmatig registratie succeeds as manual case
|
||
- Submit herregistratie with zero uren is afgewezen
|
||
- Submitting twice conflicts
|
||
- Creating a second concept of the same type conflicts
|
||
- A concept of a different type is allowed
|
||
- A new concept is allowed once the previous one is submitted
|
||
- Cancel concept removes it
|
||
- Cancel submitted aanvraag conflicts
|
||
- Applications are scoped to the caller bsn
|
||
- Submitting a foreign documentId is rejected and leaves it deletable by its owner
|
||
- Draft sync with a foreign documentId is rejected
|
||
- AutoApprovable flips to goedgekeurd after the window
|
||
- Manual case never auto advances
|
||
|
||
### AdminCasesTests
|
||
|
||
- Admin lists every case with its owner
|
||
- Non admin is forbidden
|
||
- Admin can delete a submitted case
|
||
- Deleting a missing case is not found
|
||
|
||
### ApplicationRuleTests
|
||
|
||
- AanvraagStatusTag covers the published lifecycle
|
||
|
||
### AuthzAuditTests
|
||
|
||
- A denied admin action is recorded
|
||
- A reveal attempt is recorded
|
||
- An allowed admin action is recorded
|
||
- An admin upload delete is recorded
|
||
- A feature flag toggle records which flag changed
|
||
- A refused brief transition is recorded
|
||
- No audit row carries a subjects bsn
|
||
- The audit schema carries no pii
|
||
|
||
### AuthzTests
|
||
|
||
- Drafter may not approve or reject even when submitted
|
||
- Approver may approve and reject a different drafters letter
|
||
- Send is not role gated
|
||
- Decisions CanEdit true for drafter in editable statuses
|
||
- Decisions CanApprove requires submitted status and approver role
|
||
- Decisions CanSend requires approved status only
|
||
- RoleCapabilities are empty for drafter and the three brief capabilities for approver
|
||
- CanRevealBigNummer only for the case drafter behandelaar
|
||
- Decisions CanRevealBigNummer is status independent
|
||
- CanBeoordelen true for a medewerker with the behandelaar rol
|
||
- CanBeoordelen false for a medewerker without it
|
||
- CanBeoordelen false for a zorgverlener regardless of role
|
||
|
||
### BeoordelingIdMismatchTests
|
||
|
||
- Besluit resolves by referentie when the case id differs from the local aanvraag id
|
||
|
||
### BeoordelingRuleTests
|
||
|
||
- Only open statuses are decidable
|
||
- Only a non approval requires a toelichting
|
||
- A terminal decision refuses any further besluit
|
||
- MeerInfoOpvragen is not terminal a further besluit is still legal
|
||
|
||
### BeoordelingTests
|
||
|
||
- Detail shows status documents and a masked owner
|
||
- Concept and unknown id are not found
|
||
- Zorgverlener is forbidden even with admin role
|
||
- Medewerker without behandelaar rol is forbidden
|
||
- Goedkeuren advances status to Goedgekeurd
|
||
- Afwijzen requires a toelichting
|
||
- MeerInfoOpvragen is still decidable afterwards
|
||
- Already decided case rejects a further besluit
|
||
- Concurrent besluiten on the same aanvraag yield exactly one success
|
||
- Unknown id 404s
|
||
- Zorgverlener is forbidden from deciding
|
||
|
||
### BesluitLifecycleTests
|
||
|
||
- A terminal besluit is frozen
|
||
- MeerInfoGevraagd can be decided again
|
||
- A recorded decision wins over the auto approve computation
|
||
- Afwijzen requires a toelichting
|
||
|
||
### BriefEndpointTests
|
||
|
||
- Get returns 404 and writes no row when no brief exists for the owner
|
||
- SeedBrief creates a draft with expected sections locked and empty
|
||
- Get offers only global and arts scoped besluit tagged passages
|
||
- Get joins the case context with the BIG nummer masked
|
||
- Reveal returns the unmasked BIG nummer for the drafter with step up
|
||
- Reveal is forbidden without the step up
|
||
- Reveal is forbidden for a role without the capability
|
||
- Save is drafter only
|
||
- Submit blocks on empty required section
|
||
- Submit succeeds when required sections filled
|
||
- Drafter cannot approve own letter but a different reviewer can
|
||
- Reject returns comments
|
||
- Editing a rejected letter reopens it to draft
|
||
- Send only from approved
|
||
- Decisions on the view mirror the acting principal and live status
|
||
- Me returns no capabilities for drafter and the brief set for approver
|
||
- Reset recreates a fresh draft with locked prefilled sections
|
||
|
||
### BriefRuleTests
|
||
|
||
- A drafter may save a draft or rejected letter
|
||
- A drafter may not save a non editable letter
|
||
- A non drafter is forbidden to save regardless of status
|
||
- Saving a rejected letter reopens it to draft
|
||
- Saving a draft letter leaves its status unchanged
|
||
- No required sections means nothing to fill
|
||
- An optional empty section does not block submission
|
||
- A required section with a block is filled
|
||
- A required section with no blocks is not filled
|
||
- One unfilled required section blocks submission even if others are filled
|
||
- A drafter may submit a filled draft
|
||
- A drafter may not submit an unfilled draft
|
||
- A drafter may not submit a letter that is not a draft
|
||
- A non drafter is forbidden to submit even a filled draft
|
||
- An approved letter may be sent
|
||
- Only an approved letter may be sent
|
||
- An approver may decide a submitted letter drafted by someone else
|
||
- A drafter may not approve or reject
|
||
- An approver may not decide a letter they drafted themselves
|
||
- An approver may not decide a letter that is not submitted
|
||
- Entitlement is checked before status forbidden wins over conflict
|
||
|
||
### DiplomaRuleTests
|
||
|
||
- Profession is derived from program
|
||
- English diploma requires dutch proficiency
|
||
- Dutch diploma has no policy questions
|
||
- Manual diploma gets maximal set
|
||
- Manual professions match known programs
|
||
|
||
### DocumentRuleTests
|
||
|
||
- Rejects unknown category
|
||
- Rejects disallowed type
|
||
- Rejects oversized file
|
||
- Accepts valid file
|
||
- First load has no diploma upload
|
||
- Manual diploma needs a diploma upload
|
||
- Duo diploma skips diploma upload
|
||
- Confirmed dutch proficiency requires taalvaardigheid proof
|
||
- Unconfirmed proficiency requires no taalvaardigheid proof
|
||
- Find resolves taalvaardigheid for upload validation
|
||
|
||
### EndpointTests
|
||
|
||
- DashboardView computes eligibility decision
|
||
- Notes returns seeded aantekeningen
|
||
- Brp returns address
|
||
- Duo lookup carries server decided questions and professions
|
||
- IntakePolicy returns scholing threshold
|
||
- Change request with valid phone succeeds
|
||
- Change request with bad phone is rejected with problem details
|
||
- Health endpoint is ok
|
||
- Correlation id supplied by the caller is echoed back
|
||
- Correlation id is generated when the caller omits it
|
||
- Categories are server owned config
|
||
- Upload then status reports complete for known localId
|
||
- Upload content is served back with its type inline for pdf
|
||
- Upload content 404 for unknown document
|
||
- Upload rejects wrong type
|
||
- User delete succeeds then 404
|
||
- User delete blocked with 409 once linked to submission
|
||
- Admin delete requires admin role
|
||
- Audit log records upload and delete metadata only
|
||
|
||
### FeatureFlagTests
|
||
|
||
- The catalog has unique keys
|
||
- Get flags returns the catalog
|
||
- Toggling is admin only and an unknown key is 404
|
||
- Closing inschrijving blocks a registratie then reopening allows it
|
||
|
||
### HerregistratieRuleTests
|
||
|
||
- Eligible within window
|
||
- Not eligible before window
|
||
- Eligible on window boundary
|
||
- Suspended is not eligible
|
||
|
||
### IdempotencyTests
|
||
|
||
- Replaying the same idempotency key returns the same reference not a new one
|
||
- Different idempotency keys are independent submissions
|
||
- A caller replaying another callers idempotency key does not get their cached result
|
||
- A rejected submission replays the same rejection not a retry
|
||
|
||
### IntakeRuleTests
|
||
|
||
- Below threshold with no answer is incomplete
|
||
- At the threshold no answer is required
|
||
- Niet gevolgd is a complete answer below threshold
|
||
- Gevolgd without punten is incomplete
|
||
- Gevolgd with zero punten is valid
|
||
- Gevolgd with negative punten is refused
|
||
|
||
### IntakeSubmissionTests
|
||
|
||
- Below threshold without an answer is rejected and stays a concept
|
||
- Below threshold with an answer succeeds
|
||
- Above threshold needs no answer
|
||
- Punten without gevolgd is rejected
|
||
- Herregistratie is unaffected by the intake only gate
|
||
- Zero uren is still afgewezen not a 400
|
||
|
||
### LetterHtmlTests
|
||
|
||
- Render matches the golden file
|
||
- Render resolves the body datum placeholder from the given at not the wall clock
|
||
- Render keeps the letterhead date and the body datum in agreement for a historical at
|
||
- Every letter prefixed class exists in letter css
|
||
|
||
### NotificatieTests
|
||
|
||
- Correct shared secret is accepted and recorded
|
||
- Wrong secret is rejected and recorded
|
||
- Missing authorization header is rejected
|
||
|
||
### OpenZaakDocumentSourceTests
|
||
|
||
- Upload registers an eio in drc and persists its url locally
|
||
- Upload falls back to openbaar for a category absent from the confidentialiteit table
|
||
- Upload keeps the local document when the category has no configured informatieobjecttype
|
||
- Upload keeps the local document and does not throw when drc rejects it
|
||
- LinkToZaak posts a zaakinformatieobject per document once a zaak exists
|
||
- LinkToZaak makes no zgw call when the local source created no zaak
|
||
|
||
### OpenZaakIntegrationTests
|
||
|
||
- Admin cases returns the seeded zaak mapped through real HTTP and JWT
|
||
|
||
### OpenZaakZaakSourceTests
|
||
|
||
- Follows pagination maps the internal aanvraag type and sends bearer token
|
||
- ListCases throws when a zaak zaaktype has no configured aanvraag type
|
||
- ListMyCases filters by the callers bsn
|
||
- CreateZaak posts zaak status and rol and maps the result back
|
||
- CreateZaak throws when the aanvraag type has no configured zaaktype
|
||
- RecordBesluit posts the last statustype with besluit and toelichting
|
||
- RecordBesluit creates a resultaat before posting the eindstatus
|
||
- RecordBesluit does nothing when the aanvraag has no zaak
|
||
- RecordBesluit throws when the aanvraag type has no configured zaaktype
|
||
- CreateZaak retries a transient failure and then succeeds
|
||
- CreateZaak gives up after three attempts on a persistent transient failure
|
||
- CreateZaak does not retry a permanent rejection
|
||
|
||
### OrgTemplateEndpointTests
|
||
|
||
- Admin endpoints are admin only
|
||
- Publish increments the version
|
||
- Publish appends to the version history
|
||
- Publish counts the unsent briefs it affects
|
||
- Save draft validates margins
|
||
- Save draft round trips the edited values
|
||
- Rollback copies an old version into the draft without rewriting history
|
||
- Sent brief keeps its pinned template after a republish
|
||
- Unsent brief follows a republish
|
||
- Me returns the orgtemplate capability for admin
|
||
- Admin cannot slip into the brief review flow
|
||
|
||
### OrgTemplateRuleTests
|
||
|
||
- Accepts a complete draft within the margin bounds
|
||
- Rejects a missing organisation name
|
||
- Rejects a missing signature name
|
||
- Rejects a margin outside the allowed range
|
||
- Accepts margins on the boundary
|
||
|
||
### PhoneFormatContractTests
|
||
|
||
- A leading plus31 is accepted like the frontends normalised form
|
||
- Parentheses around the area code are accepted like the frontend
|
||
|
||
### PreviewEndpointTests
|
||
|
||
- Preview of an unsent brief renders live with a watermark
|
||
- Preview of a sent brief serves the archive unchanged after a republish
|
||
- Proefbrief is admin only
|
||
- Proefbrief renders the draft template with a watermark
|
||
|
||
### ProductionIdentityProviderTests
|
||
|
||
- Production environment with no real identity provider fails at startup
|
||
|
||
### ProfessionsTests
|
||
|
||
- A mapping is absent before its geldigVan
|
||
- A mapping is present on and after its geldigVan
|
||
- A closed mapping is absent from its geldigTot onwards
|
||
- ByProgram is evaluated per call not captured at type load
|
||
|
||
### RouteInventoryTests
|
||
|
||
- Every mapped route is authz gated or on the named allow list
|
||
- Every gate marker names a known admin wrapper
|
||
|
||
### StamdataEndpointTests
|
||
|
||
- Stamdata reads are admin only
|
||
- Table list exposes the reflected schema
|
||
- Table returns all rows without a peildatum
|
||
- Peildatum before the seed windows hides every row
|
||
- Unparseable peildatum is 400 not 500
|
||
- Unknown table is 404
|
||
|
||
### StamdataValidationTests
|
||
|
||
- Every declared reference into stamdata resolves
|
||
- Profession map has no blank programs or professions
|
||
- Manual professions are non empty and distinct
|
||
- Every policy question has an id and wording
|
||
- Manual question set has distinct ids
|
||
- Every catalog table is valid
|
||
|
||
### StubIdentityProviderTests
|
||
|
||
- No headers resolves to the seeded citizen as a drafter
|
||
- X role maps to the principal role
|
||
- X subject overrides the default bsn
|
||
- No headers resolves a zorgverlener kind
|
||
- X medewerker resolves a medewerker with the default behandelaar rol
|
||
- X medewerker takes precedence over x subject
|
||
- Empty x medewerker falls through to the zorgverlener default
|
||
- X rollen parses known tokens and drops unknown ones
|
||
- X role still applies to a medewerker
|
||
- Never returns null even with no headers at all
|
||
|
||
### SubmissionRuleTests
|
||
|
||
- Zero hours is rejected
|
||
- Worked hours are accepted
|
||
- Phone change is validated
|
||
|
||
### SwaggerGateTests
|
||
|
||
- Swagger document is served in development
|
||
- Swagger document is not served outside development
|
||
|
||
### UploadAccessTests
|
||
|
||
- The owner can read the bytes
|
||
- Another citizen gets 404 not 403
|
||
- A behandelaar can read a linked document
|
||
- A medewerker without the behandelaar rol does not
|
||
- The document audit trail records a masked actor
|
||
- Status reports another citizens localId as unknown
|
||
|
||
### WerkvoorraadTests
|
||
|
||
- Behandelaar sees submitted cases in the queue
|
||
- Queue excludes concepts
|
||
- Zorgverlener is forbidden even with admin role
|
||
- Medewerker without behandelaar rol is forbidden
|
||
- Me reports the capability only for a behandelaar
|
||
|
||
### ZgwDiagnosticHandlerTests
|
||
|
||
- Passes request and response through unchanged
|
||
|
||
### ZgwDivergenceTests
|
||
|
||
- Submit with a failing zgw flags the divergence instead of diverging silently
|
||
- Submit with a healthy zgw leaves no divergence flag
|
||
- A recorded divergence carries no response body and no query string
|
||
|
||
### ZgwTokenProviderTests
|
||
|
||
- Mints a three part jwt with the required claims
|
||
- Mint with a caller carries that citizen not the static config identity
|
||
- Mint with a medewerker caller uses the medewerkerId as user id
|
||
- Signature verifies with the shared secret
|
||
|
||
### ZgwZaakMapperTests
|
||
|
||
- Maps url identity zaaktype and open status
|
||
- Closed zaak maps to goedgekeurd
|
||
- Uuid extracts trailing segment ignoring trailing slash
|