Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x | /**
* `access.role` — the **Record Access** matrix (the ACL pivot).
*
* The generic `createAndEditModel` helper drives the captures; this spec only
* adds what the matrix needs to be deterministic. Two things are specific:
*
* 1. **The row set is filtered.** The matrix rows are the whole
* `access.aclTarget` dropdown — every role, user and organization in the
* graph — so an unfiltered capture drifts with whatever else the database
* holds (other specs, leftovers from earlier runs). The `filters` declaration
* narrows the grid to the `all: (all records)` wildcard row, which is the
* tri-state evidence row: `find` cycled to Allow, `get` cycled to Deny and
* the remaining verbs left blank, with no row-edit column (every editable
* column of the pivot is a click-to-cycle cell).
* 2. **The run ends with the cells released.** The edit phase clears both cells
* back to "Not set", so the role owns no `access_acl` rows afterwards and the
* suite's `cleanupModel` can delete it — a stored rule would trip the
* `access_acl` foreign key and leave the role behind to pollute the next run.
* The *persisted* state is still evidenced: `-tab-matrix-open` captures the
* matrix of the loaded role, showing the Allow/Deny written by the create
* phase.
*
* The matrix write/load/enforce path is additionally proved end-to-end by
* `test.acl.flow` (steps 14-16) in `realm/blong-party`.
*/
import {expect, test} from '@feasibleone/blong-browser/playwright';
import {createAndEditModel} from '@feasibleone/blong-browser/playwright/model';
test.use({blongPermissions: true});
const ROLE_NAME = 'ACC-PLAY-Matrix';
test.describe('Access Role · Record Access matrix', () => {
createAndEditModel(test, expect, {
subject: 'access',
object: 'role',
fields: {
'role.roleName': ROLE_NAME,
// `access_role.roleBit` is UNIQUE and the default 0 is already taken
// by a seeded role: the insert would be silently ignored (MySQL
// `INSERT IGNORE`) and the role row would never exist — a resource
// without a role, which the browse cannot even show. The role spec
// uses 999; the matrix takes the next free bit.
'role.roleBit': 998,
'role.description': 'ACC-PLAY matrix role',
},
editFields: {
'role.description': 'ACC-PLAY matrix role edited',
},
// Its own baseline names — `role.play.ts` drives the same entity.
baselinePrefix: 'access-role-matrix',
// The edit test opens its row through the role browse filter: without
// this it would open whichever role happens to be listed first and
// capture *that* role's matrix. The text matches this role only (the
// other specs' descriptions carry 'ACC-PLAY role', not 'matrix role').
search: 'matrix role',
details: [
{
object: 'matrix',
tab: 'Record Access',
pivot: true,
// Narrow the grid to the wildcard scope: the matrix otherwise
// lists every role, user and organization in the graph.
filters: {targetName: '(all records)'},
// Tri-state evidence in one row: `find` cycled to allow, `get`
// cycled to deny and the remaining verbs left blank. The entity
// comes from the pivot defaults, so no row-edit mode is involved.
fields: {
find: {widget: 'cycle', value: 'Allow'},
get: {widget: 'cycle', value: 'Deny'},
},
// Editing proof: the loaded allow/deny are cycled back to "Not
// set", which also releases the ACL rules so the role stays
// deletable. The load itself is the `-tab-matrix-open` capture.
editFields: {
find: {widget: 'cycle', value: 'Not set'},
get: {widget: 'cycle', value: 'Not set'},
},
},
],
});
});
|