Separate shipped policies from site policies in the list

The list mixed both kinds of configuration policy into one table, so the only
way to tell a shipped default from something the site had written was to read
the source column. Split them into two tables under their own headings.

The split is presentational only. Both tables render the same Edit and Delete
buttons gated on the same iseditable(p) rule, so a shipped policy is not
stranded behind a dead button the way it was when the buttons gated on
source === 'local'.

The spec counted exactly two disabled bindings, which the second table would
have broken while the behaviour it was guarding stayed correct. It now counts
Edit and Delete in pairs and asserts the two always agree, so adding a group
does not fail a test about button gating.
This commit is contained in:
benjamin.baker
2026-09-20 13:23:23 -04:00
parent 3c91e7c314
commit 790ed4ec66
3 changed files with 143 additions and 13 deletions

View File

@@ -20,8 +20,26 @@ describe('the configuration policy buttons follow the API guard', () => {
expect(view).not.toContain(":disabled=\"p.source !== 'local'\"")
})
// Counted in pairs rather than pinned to a fixed number: the list renders
// shipped and site policies as two separate tables, so there is one Edit and
// one Delete per table. What matters is that the two buttons always agree
// with each other and both defer to iseditable - not how many tables exist.
it('gates edit and delete on the same rule', () => {
const disabled = view.match(/:disabled="!iseditable\(p\)"/g) || []
expect(disabled).toHaveLength(2)
const edits = view.match(/@click="openModal\(p\)"/g) || []
const deletes = view.match(/@click="remove\(p\)"/g) || []
expect(disabled.length).toBe(edits.length + deletes.length)
expect(edits.length).toBe(deletes.length)
expect(edits.length).toBeGreaterThan(0)
})
// The split is presentational. Both groups must render the same buttons
// under the same rule, so a shipped row is never stranded behind a dead
// button the way it was when the buttons gated on source === 'local'.
it('renders both policy groups from the same editable rule', () => {
expect(view).toContain('shippedPolicies')
expect(view).toContain('localPolicies')
expect(view).toContain("p.source === 'shipped'")
expect(view).toContain("p.source !== 'shipped'")
})
})