test(19.6.1): complete UAT - 24 passed, 1 issue

This commit is contained in:
Jakub Zych
2026-10-22 13:17:34 +02:00
parent eadc7810be
commit 422bd1e01f
2 changed files with 185 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
---
status: complete
phase: 19.6.1-backend-administrators-screen
source: 19.6.1-01-SUMMARY.md, 19.6.1-02-SUMMARY.md, 19.6.1-03-SUMMARY.md
started: 2026-10-22T11:00:00Z
updated: 2026-10-22T11:40:00Z
---
## Current Test
[testing complete]
## Tests
### 1. Settings tiles and Administrators list (superuser)
expected: Settings → System shows Administrators then Roles tiles (no new sidebar item). The Administrators list shows admins with a Superuser column and filters, including Active and Deleted; all labels are translated, with no raw lang keys.
result: pass
### 2. Create an administrator
expected: Create opens the form with login, email, name, password + confirmation, role, a Superuser switch and Permission overrides. Saving with a mismatched or 3-character password shows a field error. Saving a valid admin (role e.g. developer, Superuser off) lands on the record and shows a success toast.
result: issue
reported: "All pass. Small issue - i select Developer role, i see Developer role in dropdown. I switch to permissions tab, go back to Account tab and dropdown shows \"1\" (role id) instead of label. After save, user gets assigned Developer role properly so it's only labeling issue."
severity: minor
### 3. Superuser switch locks the permission overrides
expected: On the new admin's form, turning Superuser ON makes the Permission overrides editor read-only with a note explaining why; turning it OFF makes the overrides editable again (radio per permission: inherit / grant / deny). Saving an override persists after reload.
result: pass
### 4. Deactivate, delete, restore
expected: On the admin's preview, Deactivate shows a toast and the status hint/callout changes; Activate brings them back. Delete soft-deletes: the row disappears from the default list and appears under the Deleted filter, where Restore returns it. The preview footer buttons don't overlap or wrap badly at around 1024px wide.
result: pass
### 5. Own record restrictions (superuser)
expected: Opening your own record (admin): no Deactivate/Delete offered or they are refused with a readable toast; the role, superuser switch and permission rows are locked with a note; the password field points you to My Account instead of letting you set it here.
result: pass
### 6. Roles screen
expected: Roles lists roles; create a role with a code, name and permissions via the permission editor, then save it. Code-declared grants on system roles show as locked rows with a note. Deleting a role still held by an admin is refused with a toast that names the role and the count; deleting a system role is refused; a system role's code is not editable.
result: pass
note: "add todo to add users list (relation widget if we have one for this) in Roles" (todo roles-screen-holders-list.md)
### 7. Limited admin with only manage_users
expected: Create a role holding only backend.manage_users (plus whatever is needed to reach Settings), assign it to a new non-superuser admin, sign in as them in a private window. Only the Administrators tile shows (no Roles). No Superuser column, filter or switch; superusers (admin) are not listed. Permission rows they don't hold show locked; roles above their ceiling are locked in the role picker; their own record shows locked permissions and no Deactivate.
result: pass
### 8. Limited admin with only manage_roles
expected: Signed in as a non-superuser holding only backend.manage_roles: only the Roles tile shows. In the permission editor, permissions they don't hold are locked; they can't grant beyond their own set. (Known open gap CR-01: renaming a role's code onto a plugin-declared code escalates privileges — being fixed in the gap-closure session; note it, don't fail this test on it.)
result: pass
### 9. pact action-extension seam: a plugin adds record actions to summercms.cabana.users
expected: pact action-extension seam: a plugin adds record actions to summercms.cabana.users; offered on the preview after the owner's, run in the row-locked tx; unknown controller ID stops boot
result: pass
source: automated
coverage_id: 01-D1
### 10. Pseudo-plugin activation, tiles and orders
expected: Pseudo-plugin activates only with admin controllers; settings tile Administrators (order 100) and Roles (110) under System; codes granted to no role
result: pass
source: automated
coverage_id: 01-D2
### 11. Administrators form server rules
expected: Administrators form: create with password, superuser projection, D-03 hiding, D-05 superuser-only switch, D-08 own role/flag refusals, D-20 own password refusal, superuser demotion with a second superuser
result: pass
source: automated
coverage_id: 01-D3
### 12. Lifecycle server rules
expected: Lifecycle: deactivate revokes JWTs, soft delete with deleted row state, restore, trashed filter, self delete and self bulk-deactivate refused with whole-selection rollback, preview hint
result: pass
source: automated
coverage_id: 01-D4
### 13. Roles screen server rules
expected: Roles screen: create, code taken, in-use and system-role delete refusals, system code lock, settings order
result: pass
source: automated
coverage_id: 01-D5
### 14. Record-lock save rule
expected: Record-lock save rule: absent locked code keeps stored, differing present value is 403, equal body passes, no locks asked on create; meta.permissionLocks present only with a provider
result: pass
source: automated
coverage_id: 02-D1
### 15. Roles and Administrators saves under the record-lock rule
expected: Roles and Administrators saves keep working under the record-lock rule (system role grants, own record)
result: pass
source: automated
coverage_id: 02-D2
### 16. Trigger compile rules
expected: Valid trigger reaches the localized schema; malformed triggers are boot errors naming controller, field and trigger; settings and relation forms refuse it; Administrators permissions carries the D-06 trigger
result: pass
source: automated
coverage_id: 02-D3
### 17. Generated OpenAPI, schema.d.ts and admin build match
expected: Generated OpenAPI, schema.d.ts and the committed admin build match fresh generations
result: pass
source: automated
coverage_id: 02-D4
### 18. Save-path rules over HTTP on Postgres
expected: Superuser flag (D-05), hiding incl. scoped-token superusers (D-03), projection, permission and role ceilings (D-06, D-07), self edit (D-08), password and identity (D-11), outranking (D-19), own password (D-20)
result: pass
source: automated
coverage_id: 03-D1
### 19. Concurrent last-superuser protection
expected: Concurrent last-superuser protection on demote, record and bulk deactivate, form and bulk delete (held advisory lock), plus ten unsynchronized rounds
result: pass
source: automated
coverage_id: 03-D2
### 20. Lifecycle and revocation
expected: Lifecycle (Applies, 409, bulk Affected, soft delete, trashed filter, hint precedence) and revocation (JWT and personal tokens after deactivate and delete, sessions after a password set)
result: pass
source: automated
coverage_id: 03-D3
### 21. D-14 seam tests
expected: Boot refusals and order, offer and run only with both permissions, 409 when Applies turns false, Run in the transaction with the record; activation only with an admin
result: pass
source: automated
coverage_id: 03-D4
### 22. Roles tests
expected: Code taken and locked, plugin-declared system roles, in-use delete with soft-deleted holders, bulk delete rollback, permission ceiling
result: pass
source: automated
coverage_id: 03-D5
### 23. D-21 server side
expected: Trigger boot rules, record-lock save rule in both modes, code-declared and own-record locks on Postgres
result: pass
source: automated
coverage_id: 03-D6
### 24. D-21 SPA backstops
expected: Trigger disable, absent controlling field, hide-tab removal with the banner line, record-locked rows and payload omission, preview hide; footer wrap at 1024px with two 40-character contributed labels
result: pass
source: automated
coverage_id: 03-D7
### 25. Phase gate
expected: bash scripts/check-phase19.6.1.sh --all exits 0; SC-1 regression tests pass unchanged
result: pass
source: automated
coverage_id: 03-D8
## Summary
total: 25
passed: 24
issues: 1
pending: 0
skipped: 0
blocked: 0
## Gaps
- truth: "After picking a role in the Administrators form, the role dropdown keeps showing the role's name when the user switches tabs and comes back"
status: failed
reason: "User reported: I switch to permissions tab, go back to Account tab and dropdown shows \"1\" (role id) instead of label. After save, user gets assigned Developer role properly so it's only labeling issue."
severity: minor
test: 2
root_cause: "FormView renders only the active tab's fields, so RelationField unmounts on a tab switch. On remount its id->label cache (known) is rebuilt only from props.labels (the server's meta.labels for the value stored at load time); the label of an option picked from an options page is lost and labelOf() falls back to String(id). Pre-existing in the generic relation field, not specific to this phase."
artifacts:
- path: "admin/src/components/form/fields/RelationField.vue"
issue: "known label cache is component-local and seeded only from props.labels (lines ~31-79, labelOf)"
- path: "admin/src/views/FormView.vue"
issue: "inactive tab panels are unmounted, discarding field-local state"
missing:
- "Keep picked option labels across remounts: lift the label cache to the form context (per field) or emit the picked label with update:modelValue so FormView passes it back in labels; alternatively keep tab panels mounted with v-show"
- "Vitest backstop: pick an option, switch tab and back, label still shown"
debug_session: ""

View File

@@ -0,0 +1,8 @@
---
title: Show the administrators holding a role on the Roles screen
date: 2026-10-22
priority: low
area: cabana
---
From the 19.6.1 UAT (test 6): the Roles form and preview show a role's code, name and permissions but not who holds it. Add a list of the role's administrators, using the relation widget if cabana's relation field can render a has-many list for `summercms.cabana.roles` (WinterCMS `UserRoles` shows the users as a relation list). It is read-only at minimum; assignment stays on the Administrators form. Respect D-03: superusers stay hidden from non-superuser editors in that list as well.