test(17): complete UAT - 40 passed, 0 issues
This commit is contained in:
289
.planning/phases/17-blog-companions/17-UAT.md
Normal file
289
.planning/phases/17-blog-companions/17-UAT.md
Normal file
@@ -0,0 +1,289 @@
|
||||
---
|
||||
status: complete
|
||||
phase: 17-blog-companions
|
||||
source: [17-01-SUMMARY.md, 17-02-SUMMARY.md, 17-03-SUMMARY.md, 17-04-SUMMARY.md, 17-05-SUMMARY.md, 17-06-SUMMARY.md]
|
||||
started: 2026-10-19T10:02:15Z
|
||||
updated: 2026-10-19T10:24:39Z
|
||||
---
|
||||
|
||||
## Current Test
|
||||
|
||||
[testing complete]
|
||||
|
||||
## Tests
|
||||
|
||||
<!-- MVP user flow. Story: As a blog site editor, I want to manage menus, FAQs and the sitemap in the SummerCMS admin through the shared sitemap, menu and FAQ plugins, so that they are no longer hardcoded in the Nuxt app. -->
|
||||
|
||||
### 1. Cold Start Smoke Test
|
||||
expected: On the UAT server, restart grzybyfunkcjonalne-go and the Nuxt service. Both come up without errors in the journal, and https://uat.grzybyfunkcjonalne.pl shows the homepage with the header menu and the FAQ block, and /gfadmin shows the admin login.
|
||||
result: pass
|
||||
|
||||
### 2. Header menu on the site
|
||||
expected: Open https://uat.grzybyfunkcjonalne.pl. The header shows the PHP site's menu (main-menu). The categories entry opens a dropdown on hover and on click, listing the Journal categories, each linking to /<slug>. Esc closes the dropdown. The link to the current page is marked active. At phone width the menu collapses behind a toggle that opens and closes it.
|
||||
result: pass
|
||||
coverage_id: 17-05/D7
|
||||
|
||||
### 3. Homepage FAQ
|
||||
expected: On the homepage, the FAQ block "what-mushrooms-can-give-you" lists the PHP site's questions. Clicking a question opens its answer and clicking again closes it. The answers read as formatted text, with no stray markup.
|
||||
result: pass
|
||||
coverage_id: 17-05/D7
|
||||
|
||||
### 4. Edit a menu entry in the admin
|
||||
expected: In /gfadmin open Menus, then Menu entries of main-menu. Edit an entry: change its title, and for a Journal type pick the reference from the dropdown that loads after you choose the type. Save. Reload the site: the header shows the new title (the save purges the Nuxt cache). Known, not part of this check: a refused save, such as a javascript: URL, shows its error as a raw phrase key (deferred item 1 of 17-04).
|
||||
result: pass
|
||||
note: "First run failed against the 2026-10-12 UAT build (no save purge, 300 s page cache); passed after the 2026-10-19 redeploy."
|
||||
coverage_id: 17-04/D6
|
||||
|
||||
### 5. Reorder menu entries
|
||||
expected: From the Menu entries list, click Reorder. Move an entry with the mouse and with the keyboard; the page announces each move and the tree keeps parents and children together. Reload the site: the header shows the new order.
|
||||
result: pass
|
||||
note: "First run failed against the 2026-10-12 UAT build (no save purge, 300 s page cache); passed after the 2026-10-19 redeploy."
|
||||
coverage_id: 17-02/D4
|
||||
|
||||
### 6. Edit a FAQ answer with the rich editor
|
||||
expected: In /gfadmin open FAQ and the "what-mushrooms-can-give-you" entry. The questions show as repeater rows you can add, collapse, move and remove. Edit an answer in the rich editor: the toolbar (bold, italic, lists, link) works, the link popover sets a link, and the HTML view shows the markup. Type a script element in the HTML view and save: a notice says what was removed. The homepage FAQ shows the edited answer.
|
||||
result: pass
|
||||
coverage_id: 17-02/D1, 17-04/D6
|
||||
|
||||
### 7. Sitemap definition and settings in the admin
|
||||
expected: In /gfadmin open Settings, then Sitemap. The definition form lists the items as repeater rows; add a URL item (for example /kontakt) and save. Sitemap settings open and save. https://uat.grzybyfunkcjonalne.pl/sitemap.xml lists the new URL, and in a browser it renders through the XSL stylesheet as a readable table.
|
||||
result: pass
|
||||
coverage_id: 17-03/D6
|
||||
|
||||
<!-- Technical checks, after the user flow -->
|
||||
|
||||
### 8. UAT sitemap matches the live PHP sitemap
|
||||
expected: The loc set of the UAT /sitemap.xml equals the live grzybyfunkcjonalne.pl sitemap's with the host removed: all 71 live paths are present on UAT, and the only extra is /blog/uat-16-2-blog-editor, a post that exists only in UAT data. You accept that one extra as UAT data, not a difference in the plugin.
|
||||
result: pass
|
||||
coverage_id: 17-05/D6
|
||||
|
||||
### 9. Plugin READMEs
|
||||
expected: The READMEs of sm-journal-plugin (menu item types section), sm-sitemap-plugin, sm-menu-plugin and sm-faq-plugin read correctly: API paths, example and error bodies, rate-limit buckets, host CORS paths, the Winter import workflow and the Winter adaptations are documented, and none of them names a consuming application.
|
||||
result: pass
|
||||
coverage_id: 17-03/D7, 17-04/D7
|
||||
|
||||
<!-- Auto-passed by passing tests in each SUMMARY's coverage block (#1602), not presented -->
|
||||
|
||||
### 10. Typed menu item type registry: HasMenuItemTypes collected at boot by signpost.Activate in party, duplicate/empty/invalid types fail boot, layered patterns incl. PatternFrom, Resolve and ReferenceOptions
|
||||
expected: Typed menu item type registry: HasMenuItemTypes collected at boot by signpost.Activate in party, duplicate/empty/invalid types fail boot, layered patterns incl. PatternFrom, Resolve and ReferenceOptions
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D1
|
||||
|
||||
### 11. Dependent dropdown (dependsOn) with GET fields/{field}/dependent-options fed by signpost.ReferenceOptions, depths, applies false for a type without references, 401 anonymous
|
||||
expected: Dependent dropdown (dependsOn) with GET fields/{field}/dependent-options fed by signpost.ReferenceOptions, depths, applies false for a type without references, 401 anonymous
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D2
|
||||
|
||||
### 12. richeditor field type sanitized through seaglass on every save, clean HTML byte-identical, removals in meta.notices, non-string 422
|
||||
expected: richeditor field type sanitized through seaglass on every save, clean HTML byte-identical, removals in meta.notices, non-string 422
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D3
|
||||
|
||||
### 13. repeater field type: nested keys only, per-row required (rows.1.title), nested richeditor sanitized, nested and top-level dependent recheck (form.dependent_invalid), row bounds
|
||||
expected: repeater field type: nested keys only, per-row required (rows.1.title), nested richeditor sanitized, nested and top-level dependent recheck (form.dependent_invalid), row bounds
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D4
|
||||
|
||||
### 14. Tree reorder: config_reorder.yaml, GET/POST reorder with partition, both columns written, 409 reorder_stale for omitted or foreign nodes, 422 for cycles
|
||||
expected: Tree reorder: config_reorder.yaml, GET/POST reorder with partition, both columns written, 409 reorder_stale for omitted or foreign nodes, 422 for cycles
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D5
|
||||
|
||||
### 15. Singleton controller: GET singleton first-or-create returns a stable id, list/create/delete 404, form schema singleton
|
||||
expected: Singleton controller: GET singleton first-or-create returns a stable id, list/create/delete 404, form schema singleton
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D6
|
||||
|
||||
### 16. Every new route has swag annotations, regenerated admin.json/schema.d.ts, inventory entries, token classes, CSRF walk and conformance cases; docs and READMEs pass the docs checker
|
||||
expected: Every new route has swag annotations, regenerated admin.json/schema.d.ts, inventory entries, token classes, CSRF walk and conformance cases; docs and READMEs pass the docs checker
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-01/D7
|
||||
|
||||
### 17. Repeater field: add, edit nested, reorder and remove rows change form state only
|
||||
expected: Repeater field: add, edit nested, reorder and remove rows change form state only
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-02/D2
|
||||
|
||||
### 18. Dependent dropdown loads options for the sibling value and clears a stale value
|
||||
expected: Dependent dropdown loads options for the sibling value and clears a stale value
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-02/D3
|
||||
|
||||
### 19. Dist, types and phrase keys ship with the features; framework tagged v0.1.23 after human approval
|
||||
expected: Dist, types and phrase keys ship with the features; framework tagged v0.1.23 after human approval
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-02/D5
|
||||
|
||||
### 20. Journal registers its five PHP menu item types with DefaultPattern/PatternFrom, references, layered patterns, ordered per-locale alternates, nesting subtree, published filters and the x-default rule
|
||||
expected: Journal registers its five PHP menu item types with DefaultPattern/PatternFrom, references, layered patterns, ordered per-locale alternates, nesting subtree, published filters and the x-default rule
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-03/D1
|
||||
|
||||
### 21. /sitemap.xml from a stored definition (url item + registry item) equals the PHP golden byte for byte with Content-Type application/xml; 404 without a definition, empty 200 without items
|
||||
expected: /sitemap.xml from a stored definition (url item + registry item) equals the PHP golden byte for byte with Content-Type application/xml; 404 without a definition, empty 200 without items
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-03/D2
|
||||
|
||||
### 22. Url::to port (58 PHP cases), escaping, per-alternate list expansion, nesting, tiers (default rules, custom settings, off), manifest lastmod, frontend_url rewrite, BeforeAddItem skip, AddItem extra, priority precision, 50000 URL cap; tier config refusals and host replacement; manifest fail-safe
|
||||
expected: Url::to port (58 PHP cases), escaping, per-alternate list expansion, nesting, tiers (default rules, custom settings, off), manifest lastmod, frontend_url rewrite, BeforeAddItem skip, AddItem extra, priority precision, 50000 URL cap; tier config refusals and host replacement; manifest fail-safe
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-03/D3
|
||||
|
||||
### 23. sitemap:import-winter maps and drops items with a report, refuses a non-empty definition without --force, copies settings; /sitemap.xml rewrite with frontend_url; /sitemap.xsl bytes and headers; BeforeAddItem skip; sitemap:import PHP semantics
|
||||
expected: sitemap:import-winter maps and drops items with a report, refuses a non-empty definition without --force, copies settings; /sitemap.xml rewrite with frontend_url; /sitemap.xsl bytes and headers; BeforeAddItem skip; sitemap:import PHP semantics
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-03/D4
|
||||
|
||||
### 24. Sitemap admin API: singleton created once, repeater rows stored with PHP keys, 422 on a reference not offered for its type, settings form saves, 403 without golem15.sitemap.access_definitions
|
||||
expected: Sitemap admin API: singleton created once, repeater rows stored with PHP keys, 422 on a reference not offered for its type, settings form saves, 403 without golem15.sitemap.access_definitions
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-03/D5
|
||||
|
||||
### 25. FAQ admin: repeater with richeditor answers, script and onclick stripped on save with a notice under content.1.answer, locale column in the list, locale required (422, nothing written), 403 without golem15.faq.faqs
|
||||
expected: FAQ admin: repeater with richeditor answers, script and onclick stripped on save with a notice under content.1.answer, locale column in the list, locale required (422, nothing written), 403 without golem15.faq.faqs
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-04/D1
|
||||
|
||||
### 26. Menu admin: PHP beforeSave rules, D-05 type set, dependent reference recheck, url_scheme and target 422s, parent cycle, menu-scoped reorder (409 for a foreign entry), menu filter
|
||||
expected: Menu admin: PHP beforeSave rules, D-05 type set, dependent reference recheck, url_scheme and target 422s, parent cycle, menu-scoped reorder (409 for a foreign entry), menu filter
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-04/D2
|
||||
|
||||
### 27. Winter imports: FAQ locale remap by code (unknown aborts), ids kept, sequence bumped, --force/--dry-run/empty file; menu link->url and blog_categories->all-journal-categories, page subtree dropped and reported, ids and parent_id kept, sequences bumped, dry run writes nothing
|
||||
expected: Winter imports: FAQ locale remap by code (unknown aborts), ids kept, sequence bumped, --force/--dry-run/empty file; menu link->url and blog_categories->all-journal-categories, page subtree dropped and reported, ids and parent_id kept, sequences bumped, dry run writes nothing
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-04/D3
|
||||
|
||||
### 28. FAQ API: default locale, ?locale=en/pl, raw-SQL unsafe HTML served sanitized, null description, duplicate slug serves lowest id, 404 JSON for inactive, unknown slug, malformed slug, unknown and disabled locale, 429 after 120 requests per client
|
||||
expected: FAQ API: default locale, ?locale=en/pl, raw-SQL unsafe HTML served sanitized, null description, duplicate slug serves lowest id, 404 JSON for inactive, unknown slug, malformed slug, unknown and disabled locale, 429 after 120 requests per client
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-04/D4
|
||||
|
||||
### 29. Menu API: 404 JSON for unknown, inactive and malformed codes; unpublished subtree absent; sort_order then id; javascript: URL and bad target null; single type resolved title/URL; url_pattern override; list type keeps stored title/URL with stored child first then generated children (id null, parent type); ?locale=en alternates; unregistered and unresolvable entries left out; 429 after 120 requests
|
||||
expected: Menu API: 404 JSON for unknown, inactive and malformed codes; unpublished subtree absent; sort_order then id; javascript: URL and bad target null; single type resolved title/URL; url_pattern override; list type keeps stored title/URL with stored child first then generated children (id null, parent type); ?locale=en alternates; unregistered and unresolvable entries left out; 429 after 120 requests
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-04/D5
|
||||
|
||||
### 30. Host boots the three plugins from their pushed repositories, imports fixture exports, and serves the menu with Journal categories at /<slug>, the sanitized FAQ and the sitemap
|
||||
expected: Host boots the three plugins from their pushed repositories, imports fixture exports, and serves the menu with Journal categories at /<slug>, the sanitized FAQ and the sitemap
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-05/D1
|
||||
|
||||
### 31. vue-menu-layer and vue-faq-layer: typed clients, MenuNav and FaqBlock, URL allowlist and rel noopener tests, SSR smokes, tag v0.1.0 on origin
|
||||
expected: vue-menu-layer and vue-faq-layer: typed clients, MenuNav and FaqBlock, URL allowlist and rel noopener tests, SSR smokes, tag v0.1.0 on origin
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-05/D2
|
||||
|
||||
### 32. Site app renders MenuNav in the header and FaqBlock on the homepage, app menu and FAQ data deleted, Nuxt sitemap disabled
|
||||
expected: Site app renders MenuNav in the header and FaqBlock on the homepage, app menu and FAQ data deleted, Nuxt sitemap disabled
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-05/D3
|
||||
|
||||
### 33. UAT serves /sitemap.xml, /sitemap.xsl, /_menu/ and /_faq/ from Go through nginx with the server-level security headers, GET and HEAD only, and the full smoke passes
|
||||
expected: UAT serves /sitemap.xml, /sitemap.xsl, /_menu/ and /_faq/ from Go through nginx with the server-level security headers, GET and HEAD only, and the full smoke passes
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-05/D4
|
||||
|
||||
### 34. Winter menu, FAQ and sitemap rows exported read-only and imported on UAT by the ordered import step
|
||||
expected: Winter menu, FAQ and sitemap rows exported read-only and imported on UAT by the ordered import step
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-05/D5
|
||||
|
||||
### 35. Fail-closed phase gate over eight repositories with detectors proven on planted output; --all ends with 'Phase 17 gate passed'
|
||||
expected: Fail-closed phase gate over eight repositories with detectors proven on planted output; --all ends with 'Phase 17 gate passed'
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D1
|
||||
|
||||
### 36. Framework unit tests: signpost activation, pattern layers and ReferenceOptions; seaglass byte stability, report and bypass corpus; pact contracts; the party hook; cabana repeater, dependent dropdown, richeditor, reorder and singleton compile and routes; conformance of the new routes' success and error answers
|
||||
expected: Framework unit tests: signpost activation, pattern layers and ReferenceOptions; seaglass byte stability, report and bypass corpus; pact contracts; the party hook; cabana repeater, dependent dropdown, richeditor, reorder and singleton compile and routes; conformance of the new routes' success and error answers
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D2
|
||||
|
||||
### 37. Admin SPA specs for the UI-SPEC backstops: richeditor untouched value, link popover, notices, chunk failure; repeater bounds, remove and reorder, collapsed rows; dependent dropdown states and last request wins; reorder announcements, partition switch, tree rules; singleton form
|
||||
expected: Admin SPA specs for the UI-SPEC backstops: richeditor untouched value, link popover, notices, chunk failure; repeater bounds, remove and reorder, collapsed rows; dependent dropdown states and last request wins; reorder announcements, partition switch, tree rules; singleton form
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D3
|
||||
|
||||
### 38. Plugin unit tests: Journal menu item types, sitemap parity (Url::to goldens, escaping, fillable, tiers, rewrite, hooks, manifest, item JSON, cap, backend URL), menu links, tree and model, FAQ decode, model and serializer; Postgres APIs, imports and beforeSave
|
||||
expected: Plugin unit tests: Journal menu item types, sitemap parity (Url::to goldens, escaping, fillable, tiers, rewrite, hooks, manifest, item JSON, cap, backend URL), menu links, tree and model, FAQ decode, model and serializer; Postgres APIs, imports and beforeSave
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D4
|
||||
|
||||
### 39. Host wiring and layers: TestCompanionsHost with CORS preflight and sitemap headers; menu and FAQ layer link rules, clients and composable bases
|
||||
expected: Host wiring and layers: TestCompanionsHost with CORS preflight and sitemap headers; menu and FAQ layer link rules, clients and composable bases
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D5
|
||||
|
||||
### 40. Filled 17-VALIDATION.md: every row with task IDs, gate commands, File Exists and status; Wave 0 ticked; manual rows keep the plan 05 human check
|
||||
expected: Filled 17-VALIDATION.md: every row with task IDs, gate commands, File Exists and status; Wave 0 ticked; manual rows keep the plan 05 human check
|
||||
result: pass
|
||||
source: automated
|
||||
coverage_id: 17-06/D6
|
||||
|
||||
## Summary
|
||||
|
||||
total: 40
|
||||
passed: 40
|
||||
issues: 0
|
||||
pending: 0
|
||||
skipped: 0
|
||||
blocked: 0
|
||||
|
||||
## Gaps
|
||||
|
||||
- gap_id: G-17-4
|
||||
truth: "In /gfadmin open Menus, then Menu entries of main-menu. Edit an entry: change its title, and for a Journal type pick the reference from the dropdown that loads after you choose the type. Save. Reload the site: the header shows the new title (the save purges the Nuxt cache). Known, not part of this check: a refused save, such as a javascript: URL, shows its error as a raw phrase key (deferred item 1 of 17-04)."
|
||||
status: resolved
|
||||
resolved_by: UAT redeploy 2026-10-19 (host master, cache purge from 19.3-04)
|
||||
resolved_at: 2026-10-19
|
||||
reason: "User reported: didn't work. changed Grzyby Funkcjonalne to Grzyby and uat.grzybyfunkcjonalne.pl still shows Grzyby Funkcjonalne. two options - actually nothing got deployed and I'm testing old hardcoded faq and navigation, or there is this painful 60s cache"
|
||||
severity: major
|
||||
test: 4
|
||||
root_cause: "Not a code gap: UAT runs the 2026-10-12 build (17-05). The save worked (menu API returned the new title) and the page showed it once the Nuxt swr cache (s-maxage=300) expired, as the user later confirmed. The save-triggered purge exists since 19.3-04 (sm-menu-plugin 559d96b, sm-faq-plugin c60ae6e, host d604509/85939c3) but was never deployed to UAT."
|
||||
artifacts:
|
||||
- path: "../sm-grzybyfunkcjonalne-app (UAT /srv/grzybyfunkcjonalne/go/bin, 2026-10-12)"
|
||||
issue: "deployed binary predates the site-cache purge"
|
||||
missing:
|
||||
- "Redeploy UAT from current host master, then re-run tests 4 and 5"
|
||||
- gap_id: G-17-5
|
||||
truth: "From the Menu entries list, click Reorder. Move an entry with the mouse and with the keyboard; the page announces each move and the tree keeps parents and children together. Reload the site: the header shows the new order."
|
||||
status: resolved
|
||||
resolved_by: UAT redeploy 2026-10-19 (host master, cache purge from 19.3-04)
|
||||
resolved_at: 2026-10-19
|
||||
reason: "User reported: failed, nothing happened, and my name change from previous step still doesn't appear. switching you to manual mode, confirm that I'm testing proper deployment"
|
||||
severity: major
|
||||
test: 5
|
||||
root_cause: "Same as G-17-4: the reorder saved and appeared on the site after the swr TTL; the deployed UAT build has no save-triggered purge."
|
||||
artifacts: []
|
||||
missing:
|
||||
- "Redeploy UAT from current host master, then re-run tests 4 and 5"
|
||||
Reference in New Issue
Block a user