test(17-06): framework and admin SPA unit tests for the blog companions

- signpost: activation refusals, host overrides, D-02 pattern layers
  incl. PatternFrom, ReferenceOptions depths
- seaglass: removal report, bluemonday bypass corpus, Check
- pact Option.Depth omitempty and the menu item type contracts; party
  activates menu item types after Register and before the first Boot
- cabana: repeater compile and decode, dependsOn compile and recheck,
  richeditor keys and notices, reorder and singleton boot checks
  (Docker-free); repeater save, dependent recheck, richeditor save,
  reorder and singleton routes on Postgres; conformance cases for the
  documented 404, 409 and 422 answers of the new routes
- admin: richeditor value contract, link popover, notices and chunk
  failure; repeater bounds, remove and reorder, collapsed rows;
  dependent dropdown states and last request wins; reorder
  announcements, partition switch and tree rules; SingletonForm spec
- gate: required names in the go, admin and postgres stages
This commit is contained in:
2026-10-12 19:29:37 +02:00
parent 490a4e3e6a
commit 91593da1f7
17 changed files with 3136 additions and 17 deletions

View File

@@ -60,14 +60,17 @@ FAQ_LAYER="${FAQ_LAYER:-$ROOT/../vue-faq-layer}"
# must pass; a name that skips or does not run fails the stage.
# go stage: Docker-free framework suites (-short).
SIGNPOST_TESTS=(TestSignpostSmoke TestRegistryDuplicateKey)
SEAGLASS_TESTS=(TestSeaglassSmoke TestSanitizeByteStable)
SIGNPOST_TESTS=(TestSignpostSmoke TestRegistryDuplicateKey TestRegistryActivate TestRegistryHostOverrideUnknown TestRegistryPatternLayers TestReferenceOptions)
SEAGLASS_TESTS=(TestSeaglassSmoke TestSanitizeByteStable TestSanitizeReport TestSanitizeBypassCorpus TestCheck)
PACT_TESTS=(TestOptionDepthOmitEmpty TestMenuItemTypeContracts)
PARTY_TESTS=(TestActivateMenuItemTypesOrder)
CABANA_SHORT_TESTS=(TestRepeaterCompile TestRepeaterDecode TestDependentDropdownCompile TestDependentValues TestRichEditorCompile TestReorderConfigCompile TestSingletonCompile TestPhase10ConformanceInventory)
# plugins stage: Docker-free plugin and host suites (-short).
SITEMAP_SHORT_TESTS=(TestSitemapGolden TestSitemapTiersConfig)
# postgres stage: testcontainers suites.
PG_CABANA_TESTS=(TestCompanionsDependentSmoke TestCompanionsRichEditorSmoke TestCompanionsRepeaterSmoke TestCompanionsReorderSmoke TestCompanionsSingletonSmoke TestPhase10OpenAPIConformance)
PG_CABANA_TESTS=(TestCompanionsDependentSmoke TestCompanionsRichEditorSmoke TestCompanionsRepeaterSmoke TestCompanionsReorderSmoke TestCompanionsSingletonSmoke TestRepeaterSave TestDependentRecheck TestRichEditor TestReorderPostgres TestSingleton TestPhase10OpenAPIConformance)
PG_JOURNAL_TESTS=(TestMenuItemTypesSmoke)
PG_SITEMAP_TESTS=(TestSitemapTracer TestSitemapImportSmoke TestSitemapAdminSmoke)
PG_MENU_TESTS=(TestMenuAdminSmoke TestMenuImportSmoke TestMenuAPISmoke)
@@ -80,14 +83,55 @@ ADMIN_FILES=(
tests/form/RepeaterField.test.ts
tests/form/DependentDropdown.test.ts
tests/views/ReorderView.test.ts
tests/form/SingletonForm.test.ts
)
ADMIN_REQUIRE=(
"RichEditorField RichEditorField tracer: untouched value is submitted byte-identical"
"RichEditorField RichEditorField edit emits editor HTML"
"RepeaterField RepeaterField tracer: add, edit nested, reorder and remove change form state only"
"DependentDropdown DependentDropdown loads options for the sibling value and clears a stale value"
"DependentDropdown waits for the sibling, and offers a retry when loading fails"
"DependentDropdown states shows loading while the options load, then the empty state naming the type"
"DependentDropdown states drops a late answer for an old sibling value: the last request wins"
"DependentDropdown states shows the placeholder for a stored value no option offers, without clearing it"
"DependentDropdown states a dropdown inside a repeater row asks with the row path and its row sibling"
"RepeaterField RepeaterField tracer: add, edit nested, reorder and remove change form state only"
"RepeaterField expands rows with path errors, shows the chip and focuses the first invalid nested control"
"RepeaterField shows the empty state with the prompt"
"RepeaterField rows enforces minItems and maxItems on remove, add and the counter"
"RepeaterField rows asks before removing a row with a value, never for an empty or default row, and keeps it on cancel"
"RepeaterField rows reorders by the arrow keys and the buttons, announces repeater.moved and stops at the ends"
"RepeaterField rows collapsed rows do not mount their richeditors and keep their values"
"RepeaterField rows read-only shows every row expanded with no controls"
"RichEditorField RichEditorField tracer: untouched value is submitted byte-identical"
"RichEditorField shows the lossy note for markup outside the editor schema and keeps the HTML view lossless"
"RichEditorField sends the editor HTML after an edit and shows what the server removed"
"RichEditorField RichEditorField edit emits editor HTML"
"RichEditorField renders read-only values through the display policy, never as stored"
"richeditor policy helpers accepts policy links only"
"richeditor policy helpers compares tag names case-insensitively for the lossy note"
"richeditor policy helpers unwraps unknown elements and drops scripts for display"
"RichEditorField value contract an empty paragraph is the empty string, any content its HTML"
"RichEditorField value contract a value from outside replaces the document and leaves the field untouched"
"RichEditorField value contract shows the lossy note only for markup outside the editor schema"
"RichEditorField value contract reads empty and read-only values"
"richeditor link popover refuses a URL outside the allowlist and applies a policy URL on Enter"
"richeditor link popover starts from the current link and offers Remove link inside one"
"richeditor notices callout lists every notice of the field in one warning callout after a save"
"RichEditorField chunk failure falls back to the HTML view with the load_failed note, and saving still works"
"SingletonForm opens through /singleton from settings, has no Delete, and Save and close returns to settings"
"SingletonForm back returns to the settings index"
"SingletonForm a link to a controller that is not a singleton opens its list"
"SingletonForm a modified click opens the link as it is, without asking for the record"
"SingletonForm a form without the singleton flag keeps Delete and returns to its list"
"ReorderView ReorderView tracer: a keyboard move sends one debounced POST with the full node set"
"ReorderView restores the saved tree when a save fails and reloads on a stale set"
"ReorderView shows the empty state and the 403 alert"
"list Reorder button links to the reorder page with the filtered partition"
"singleton form opens the one record from settings, without Delete, and returns to the settings index"
"ReorderView moves announces every keyboard move and moves children with their parent"
"ReorderView moves shows the loading skeleton, then the load failure alert"
"ReorderView moves a partition switch sends the pending save first, then loads the chosen partition"
"reorder tree rules builds the tree by sort order and puts unknown parents and cycles at the top"
"reorder tree rules refuses a drop into the node itself or its own subtree and leaves the tree as it was"
"reorder tree rules moves only where a sibling or parent exists, and flattens pre-order from 1"
)
# layers stage: test files (must exist and match the test script's glob) and
@@ -467,6 +511,9 @@ run_go() {
(cd "$ROOT" && go vet ./...)
go_named "$ROOT" ./modules/signpost -short "${SIGNPOST_TESTS[@]}"
go_named "$ROOT" ./modules/seaglass -short "${SEAGLASS_TESTS[@]}"
go_named "$ROOT" ./modules/pact -short "${PACT_TESTS[@]}"
go_named "$ROOT" ./modules/party -short "${PARTY_TESTS[@]}"
go_named "$ROOT" ./modules/cabana -short "${CABANA_SHORT_TESTS[@]}"
echo "phase17 go passed"
}