diff --git a/infra/run-domain-check.sh b/infra/run-domain-check.sh index ef9f95d..409ea76 100755 --- a/infra/run-domain-check.sh +++ b/infra/run-domain-check.sh @@ -158,6 +158,49 @@ done [ -n "$gone" ] || { echo "FAIL — Beoordelen task for $reg_id2 still active after withdrawal" >&2; docker logs "$dom" 2>&1 | tail -15 >&2; exit 1; } echo "OK — withdrawal cancelled the Beoordelen task; the registratie process ended (ingetrokken)" +# ── S-13: diploma-eligibility routing. A registration with a FOREIGN diploma must route through the +# extra CBGVAdvies user task before Beoordelen (the DMN businessRuleTask sets route=CBGV_ADVIES and the +# gateway branches, ADR-0016). The domestic DIRECT path is already proven by the first registration +# above, which parked straight at Beoordelen. ────────────────────────────────────────────────────── +cbgv_query='{"processDefinitionKey":"registratie","taskDefinitionKey":"CBGVAdvies","includeProcessVariables":true}' +echo ">> submitting a registration with a foreign diploma" +locf="$(docker run --rm --network "$net" curlimages/curl:latest \ + -fsS -D - -o /dev/null -X POST "http://$dom_ip:8080/registrations" \ + -H 'Content-Type: application/json' -d '{"bsn":"123456782","diplomaOrigin":"Buitenlands"}' \ + | sed -n 's/\r$//; s/^[Ll]ocation: //p' | head -1)" +[ -n "$locf" ] || { echo "FAIL — foreign POST /registrations returned no Location" >&2; exit 1; } +reg_idf="${locf##*/}" +echo ">> foreign registration $reg_idf" + +echo ">> polling Flowable for its CBGV-advies task (foreign diplomas route here first)" +cbgv_task="" +for _ in $(seq 1 30); do + resp="$(flcurl -X POST "$fl_base/query/tasks" -H 'Content-Type: application/json' -d "$cbgv_query" 2>/dev/null || true)" + cbgv_task="$(printf '%s' "$resp" | task_for_reg "$reg_idf")" + [ -n "$cbgv_task" ] && break + sleep 2 +done +[ -n "$cbgv_task" ] || { echo "FAIL — no CBGVAdvies task appeared for the foreign registration $reg_idf" >&2; docker logs "$dom" 2>&1 | tail -15 >&2; exit 1; } +echo ">> CBGVAdvies task $cbgv_task is waiting" + +echo ">> asserting it has NOT reached Beoordelen yet (still awaiting CBGV-advies)" +resp="$(flcurl -X POST "$fl_base/query/tasks" -H 'Content-Type: application/json' -d "$query")" +early="$(printf '%s' "$resp" | task_for_reg "$reg_idf")" +[ -z "$early" ] || { echo "FAIL — foreign registration reached Beoordelen ($early) before CBGV-advies" >&2; exit 1; } + +echo ">> completing the CBGV-advies task" +flcurl -X POST "$fl_base/runtime/tasks/$cbgv_task" -H 'Content-Type: application/json' -d '{"action":"complete"}' >/dev/null + +echo ">> asserting it now advances to Beoordelen" +onward="" +for _ in $(seq 1 15); do + resp="$(flcurl -X POST "$fl_base/query/tasks" -H 'Content-Type: application/json' -d "$query" 2>/dev/null || true)" + [ -n "$(printf '%s' "$resp" | task_for_reg "$reg_idf")" ] && { onward=1; break; } + sleep 2 +done +[ -n "$onward" ] || { echo "FAIL — foreign registration did not reach Beoordelen after CBGV-advies" >&2; exit 1; } +echo "OK — foreign diploma routed through CBGV-advies, then on to Beoordelen (DMN + gateway)" + # ── S-14: escalation. A third registration parks at Beoordelen. We fire its 14-day boundary timer # early via Flowable's management API (the timer job is moved to executable and run), which routes a # parallel token to the BeoordelingEscaleren external task. The domain's escalation worker acquires diff --git a/tests/acceptance/Features/EenDiplomaRouteren.feature b/tests/acceptance/Features/EenDiplomaRouteren.feature new file mode 100644 index 0000000..f404ab5 --- /dev/null +++ b/tests/acceptance/Features/EenDiplomaRouteren.feature @@ -0,0 +1,19 @@ +# language: en +# Drives S-13 (#14). A registration's diploma origin decides its route: a domestic (Binnenlands) +# diploma goes straight to beoordeling, a foreign (Buitenlands) one is routed through an extra +# CBGV-advies step (PRD flow 4). The decision itself is a DMN evaluated inside the workflow +# (ADR-0016); the domain's part — verified here — is carrying the origin into the process so the DMN +# can route on it. The DMN evaluation and the CBGV routing are verified live (verify-domain). +Feature: Een diploma op herkomst routeren + Als register wil ik een aanvraag met een buitenlands diploma extra laten toetsen + zodat een CBGV-advies wordt ingewonnen voordat een behandelaar beoordeelt. + + Scenario: Een binnenlands diploma start de registratie als binnenlands + Given a zorgprofessional with a "Binnenlands" diploma + When they submit their registration + Then the registratie process is started carrying a "Binnenlands" diploma + + Scenario: Een buitenlands diploma start de registratie als buitenlands + Given a zorgprofessional with a "Buitenlands" diploma + When they submit their registration + Then the registratie process is started carrying a "Buitenlands" diploma diff --git a/tests/acceptance/Steps/EenDiplomaRouterenSteps.cs b/tests/acceptance/Steps/EenDiplomaRouterenSteps.cs new file mode 100644 index 0000000..187f3ca --- /dev/null +++ b/tests/acceptance/Steps/EenDiplomaRouterenSteps.cs @@ -0,0 +1,36 @@ +using Acceptance.Support; +using Big.Application; +using Big.Domain; +using Reqnroll; +using Xunit; + +namespace Acceptance.Steps; + +/// Bindings for EenDiplomaRouteren.feature (S-13). Drives the submit use case against +/// in-memory ports and asserts the registratie process is started carrying the diploma origin — the +/// domain's contribution to flow 4. The DMN evaluation and the foreign→CBGV-advies routing it drives +/// are verified live (verify-domain); one instance per scenario. +[Binding] +[Scope(Feature = "Een diploma op herkomst routeren")] +public sealed class EenDiplomaRouterenSteps +{ + private readonly InMemoryRegistrationStore _store = new(); + private readonly InMemoryWorkflowClient _workflow = new(); + private DiplomaOrigin _origin; + + [Given("a zorgprofessional with a \"(.*)\" diploma")] + public void GivenAZorgprofessionalWithADiploma(string origin) + => _origin = Enum.Parse(origin, ignoreCase: true); + + [When("they submit their registration")] + public async Task WhenTheySubmitTheirRegistration() + => await new SubmitRegistration(_store, _workflow).HandleAsync( + new SubmitRegistrationCommand("123456782", _origin)); + + [Then("the registratie process is started carrying a \"(.*)\" diploma")] + public void ThenTheProcessIsStartedCarryingTheDiploma(string expected) + { + Assert.NotNull(_workflow.StartedFor); + Assert.Equal(Enum.Parse(expected, ignoreCase: true), _workflow.StartedWithOrigin); + } +}