Clarify campaign review interventions

This commit is contained in:
2026-08-03 07:22:27 +02:00
parent 5df26be074
commit 1d6c745991
11 changed files with 416 additions and 18 deletions
@@ -0,0 +1,19 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const here = dirname(fileURLToPath(import.meta.url));
const guidance = readFileSync(resolve(here, "../src/features/campaigns/review/ReviewWorkflowGuidance.tsx"), "utf8");
const page = readFileSync(resolve(here, "../src/features/campaigns/ReviewSendPage.tsx"), "utf8");
assert.match(guidance, /<ActionBlockerHint/);
assert.match(guidance, /<GuidedReviewList/);
assert.match(guidance, /tone="danger"/);
assert.match(guidance, /tone="warning"/);
assert.match(guidance, /requiredAction: requiredActionLabel/);
assert.match(guidance, /target: destinationLabel/);
assert.match(page, /calculateBuildReviewProgress/);
assert.match(page, /<WorkflowFact label="i18n:govoplan-campaign\.remaining\.cc632b5e"/);
assert.doesNotMatch(page, /blocked_or_failed_message_s_must_be_resolved_bef/);
assert.doesNotMatch(page, /resolve_the_blocking_entries_then_validate_again/);
@@ -0,0 +1,54 @@
import assert from "node:assert/strict";
import test from "node:test";
import { calculateBuildReviewProgress } from "../src/features/campaigns/review/reviewProgress.ts";
test("separates blocking, individual, and group review work", () => {
assert.deepEqual(calculateBuildReviewProgress({
blocking: 2,
individualRequired: 3,
individualReviewed: 1,
groupRequired: 4,
reviewComplete: false
}), {
blocking: 2,
individualRequired: 3,
individualReviewed: 1,
individualRemaining: 2,
groupRequired: 4,
groupReviewed: 0,
groupRemaining: 4,
required: 7,
reviewed: 1,
remaining: 6
});
});
test("a recorded review completion acknowledges every review decision", () => {
const progress = calculateBuildReviewProgress({
blocking: 0,
individualRequired: 3,
individualReviewed: 3,
groupRequired: 4,
reviewComplete: true
});
assert.equal(progress.reviewed, 7);
assert.equal(progress.remaining, 0);
assert.equal(progress.individualRemaining, 0);
assert.equal(progress.groupRemaining, 0);
});
test("normalizes malformed counters without overstating progress", () => {
const progress = calculateBuildReviewProgress({
blocking: -2,
individualRequired: 2.9,
individualReviewed: 99,
groupRequired: Number.NaN,
reviewComplete: false
});
assert.equal(progress.blocking, 0);
assert.equal(progress.individualRequired, 2);
assert.equal(progress.individualReviewed, 2);
assert.equal(progress.required, 2);
assert.equal(progress.remaining, 0);
});