test(export): pin the selection controls against going inert again

Two layers, because the defect had two halves and each needs its own kind of
proof.

The structural guard walks the panel's control shape, folds every control
through the wire schema and the resolver the route uses, and fails when
flipping one changes nothing in the resolved selection. It also checks the
panel renders a row for every control it declares, and that every resolved
flag is read downstream, either by gating measurement types or by name in the
aggregator. That is the link nobody had written: the dead switches were dead
for several releases and no test connected "the panel renders this" to "the
export honours this".

The behavioural half runs the real export route and reads what comes out. The
previously-dead measurement switches are asserted against the FHIR bundle and
the PDF table, with a positive control beside each exclusion so nothing passes
on an empty fixture. The screening totals are asserted absent for a caller
that names other sections and for a caller that sends no sections at all, then
present when asked for by name. Allergies and family history are asserted
absent from the bundle and never read from the database, and the package case
opens the zip and checks the bundle inside it agrees with the PDF beside it.

Mutation-checked: reverting the allergy gate, the medication-list gate, the
screener entries or the measurement entries turns the matching cases red and
leaves the rest green; removing a control's fold entry or its aggregator entry
turns the guard red with the control named.

The remaining changes update fixtures the new shapes touch: prefs objects now
resolve the added flags from the defaults, and the share-link fixtures drop
the retired FHIR scope, with a case pinning that the create route now refuses
those keys instead of ignoring them.
This commit is contained in:
Marc-André Bombeck committed 2026-07-26 00:45:08 +02:00
1 parent 68b9903966
commit f90219784b
11 files changed
+533 -58

No files matched your search

@@ -112,19 +112,17 @@ describe("buildShareLinkCreatePayload — scope contract", () => {
expiryDays: 30,
};
it("document-only: empty report scope, FHIR off, and the launched doc always rides along", () => {
it("document-only: empty report scope and the launched doc always rides along", () => {
const payload = buildShareLinkCreatePayload({
...common,
// Even if the caller state still holds record-scope values, they must be
// dropped: a document link never carries a health scope.
allowFhirApi: true,
resourceTypes: ["Patient", "Observation"],
documentIds: ["doc-1"],
documentOnly: true,
});
expect(payload.resourceTypes).toEqual([]);
expect(payload.allowFhirApi).toBe(false);
expect(payload.documentOnly).toBe(true);
// The retired FHIR scope keys are gone from the wire entirely,
// so a share link can no longer advertise a face that was never served.
expect(payload).not.toHaveProperty("resourceTypes");
expect(payload).not.toHaveProperty("allowFhirApi");
// No report sections are ever sent for a document link.
expect(payload).not.toHaveProperty("sections");
// The launched document is always in the created link (pre-attach fix).
@@ -132,15 +130,15 @@ describe("buildShareLinkCreatePayload — scope contract", () => {
expect(payload.label).toBe("Blood panel 2026");
});
it("record share: keeps the full scope and omits documentIds when none picked", () => {
it("record share: keeps the window scope and omits documentIds when none picked", () => {
const payload = buildShareLinkCreatePayload({
...common,
allowFhirApi: false,
resourceTypes: ["Patient", "Observation"],
documentIds: [],
documentOnly: false,
});
expect(payload.resourceTypes).toEqual(["Patient", "Observation"]);
expect(payload.rangeEnd).toBeNull();
expect(payload).not.toHaveProperty("resourceTypes");
expect(payload).not.toHaveProperty("allowFhirApi");
expect(payload).not.toHaveProperty("documentIds");
expect(payload).not.toHaveProperty("documentOnly");
});
@@ -148,8 +146,6 @@ describe("buildShareLinkCreatePayload — scope contract", () => {
it("record share: attaches the picked documents when the owner chose some", () => {
const payload = buildShareLinkCreatePayload({
...common,
allowFhirApi: false,
resourceTypes: ["Patient", "Observation"],
documentIds: ["a", "b"],
documentOnly: false,
});
@@ -33,8 +33,6 @@ const FIXTURE_LINKS = [
label: "Cardiology referral",
rangeStart: "2026-01-01T00:00:00.000Z",
rangeEnd: null,
resourceTypes: ["Patient", "Observation"],
allowFhirApi: true,
documentCount: 2,
expiresAt: "2099-01-01T00:00:00.000Z",
createdAt: "2026-06-01T00:00:00.000Z",
@@ -48,8 +46,6 @@ const FIXTURE_LINKS = [
label: "Old GP link",
rangeStart: "2026-01-01T00:00:00.000Z",
rangeEnd: null,
resourceTypes: [],
allowFhirApi: false,
documentCount: 0,
expiresAt: "2099-01-01T00:00:00.000Z",
createdAt: "2026-05-01T00:00:00.000Z",
@@ -100,8 +96,9 @@ describe("<SharingSection> — owner share-link surface (C7)", () => {
// The list response shape carries no token; the markup must not surface
// an `hls_` string anywhere.
expect(html).not.toContain("hls_");
// The FHIR badge surfaces for the FHIR-enabled link.
expect(html).toContain("FHIR");
// No FHIR badge: the link has never served FHIR, so advertising
// it on the owner's list was the last place the promise still showed.
expect(html).not.toContain("FHIR");
});
it("folds revoked links into the inactive list (not the active list)", () => {