Files
govoplan-campaign/webui/tests/review-workflow-guidance-ui-structure.test.mjs
zemion c51fc180fb
Module Package Release / publish-packages (push) Successful in 12s
Release govoplan-campaign v0.1.28: stabilize saving, review and delivery recovery
2026-09-08 01:32:26 +02:00

75 lines
5.4 KiB
JavaScript

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");
const attachmentsPage = readFileSync(resolve(here, "../src/features/campaigns/AttachmentsDataPage.tsx"), "utf8");
const mailPage = readFileSync(resolve(here, "../src/features/campaigns/MailSettingsPage.tsx"), "utf8");
const migrationNotice = readFileSync(resolve(here, "../src/features/campaigns/components/LegacyMailMigrationNotice.tsx"), "utf8");
const draftEditor = readFileSync(resolve(here, "../src/features/campaigns/hooks/useCampaignDraftEditor.ts"), "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(guidance, /documentation=\{\{ topicId: documentationTopicId \}\}/);
assert.match(guidance, /campaigns\.workflow\.prepare-validate-and-build/);
assert.match(guidance, /campaigns\.workflow\.complete-review/);
assert.doesNotMatch(guidance, /showUnacknowledgedWarning|buildWarnings/,
"aggregate warnings must not create extra review requirements for expected or already accepted outcomes");
assert.match(page, /calculateBuildReviewProgress/);
assert.match(page, /<MetricCard[^>]+label="i18n:govoplan-campaign\.remaining\.cc632b5e"/);
assert.match(page, /showBuiltDetails\(\{ messageState: 'list:\["needs_review"\]' \}\)/);
assert.doesNotMatch(page, /showAllReviewJobs|visibleValidationIssues|attachmentReuseFindings\.slice\(0, 10\)/);
assert.match(page, /<ValidationDetails/);
assert.match(page, /<RepeatedFilesDetails/);
assert.match(page, /data-residual-file-policy/);
assert.match(page, /build\.residual_file_disposition/);
assert.match(page, /residual_file_count/);
assert.match(page, /watched_source_count/);
assert.match(page, /data-attachment-reuse-policy/);
assert.match(page, /build\.attachment_reuse/);
assert.match(page, /attachmentReusePolicy\.allow_within/);
assert.match(attachmentsPage, /patch\(\["attachments", "reuse_policy"\]/);
for (const action of ["allow", "warn", "review", "block"]) {
assert.match(attachmentsPage, new RegExp(`<option value="${action}">`));
}
for (const allowance of ["none", "same_recipient", "same_message"]) {
assert.match(attachmentsPage, new RegExp(`<option value="${allowance}">`));
}
assert.doesNotMatch(page, /blocked_or_failed_message_s_must_be_resolved_bef/);
assert.doesNotMatch(page, /resolve_the_blocking_entries_then_validate_again/);
assert.match(page, /readOnlyVersion = [^;]*mailProfileMigrationRequired/);
assert.match(page, /reloadAttachmentPreview = useCallback\(async[^]*?if \(!version\?\.id \|\| mailProfileMigrationRequired\)/);
assert.match(page, /<LegacyMailMigrationNotice campaignId=\{campaignId\} versionId=\{version\?\.id\}/);
assert.match(page, /state: mailProfileSelected && !mailProfileMigrationRequired \? "ready" : "blocked"/);
assert.match(page, /label: "Attachments",\s*\.\.\.attachmentDeliveryPreflight/);
assert.match(page, /inspectionComplete: inspectionSatisfied/);
assert.match(page, /use_reviewed_build: true/);
assert.match(page, /mailProfileMigrationRequired \? <DismissibleAlert[^>]*>\s*i18n:govoplan-campaign\.attachment_checks_await_mail_migration\s*<\/DismissibleAlert> : <AttachmentLinkingPreview/);
assert.match(mailPage, /campaignMailProfileListOptions\(view, campaignId\)/);
assert.doesNotMatch(mailPage, /Promise\.all/);
assert.match(mailPage, /const generation = \+\+profileLoadGeneration\.current/);
assert.match(mailPage, /if \(generation !== profileLoadGeneration\.current\) return;/);
assert.match(mailPage, /if \(generation === profileLoadGeneration\.current\) setProfilesLoading\(false\)/);
assert.match(mailPage, /if \(isPolicyView\) setPolicyProfiles\(\[\]\);\s*else setMailProfiles\(\[\]\)/);
assert.match(mailPage, /const canMigrate = migrationRequired && !locked && !saving && Boolean\(draft\) && Boolean\(selectedProfile\) && !profilesLoading/);
assert.doesNotMatch(mailPage, /const canMigrate = [^;]*dirty/);
assert.match(mailPage, /async function migrateMailProfile\(\)[^]*?await saveDraft\("manual"\)/);
assert.match(mailPage, /onMigrate=\{!isPolicyView && !locked/);
assert.match(migrationNotice, /useGuardedNavigate/);
assert.match(migrationNotice, /\?version=\$\{encodeURIComponent\(versionId\)\}/);
assert.match(migrationNotice, /disabled=\{!canMigrate \|\| busy\}/);
assert.match(draftEditor, /version\.mail_profile_migration_required && !additionalPayload\.migrate_legacy_mail_settings/);
assert.match(draftEditor, /!campaignMailReferencesUnchanged\(baseDraftRef\.current \?\? getCampaignJson\(version\), draftToSave\)/);
assert.match(draftEditor, /throw new Error\("i18n:govoplan-campaign\.legacy_mail_migration_required"\)/);
for (const editor of ["TemplateDataPage.tsx", "CampaignFieldsPage.tsx", "AttachmentsDataPage.tsx", "GlobalSettingsPage.tsx", "components/CampaignDraftPageScaffold.tsx"]) {
const source = readFileSync(resolve(here, "../src/features/campaigns", editor), "utf8");
assert.match(source, /version\?\.mail_profile_migration_required && <LegacyMailMigrationNotice/);
}