Files
shopdb-flask/plugins/computers/frontend/views/configurationPolicyEditable.spec.js
benjamin.baker 67e701b538 Let the policy list edit the rows the API accepts
The shipped Configuration Policies rendered with working-looking Edit and
Delete buttons that did nothing. The API had already been widened to accept
shipped rows, but the buttons still carried :disabled on source !== local, so
the write was never sent and the change looked like it had never rolled.

Gate both buttons on the set the API actually accepts. The shipped badge stays:
it is provenance, not a lock, and it has to survive an edit so a site can still
tell a product-supplied row from one of its own.

Business Policies keep the local-only rule. Their API guard is unchanged and
no shipped Site Policy exists now, so the UI already matches.

Cover it with a spec, because the failure mode is a disabled attribute silently
disagreeing with a server guard - nothing errors, the button just does nothing.
2026-09-08 17:16:34 -04:00

28 lines
1.2 KiB
JavaScript

import { describe, it, expect } from 'vitest'
import { readFileSync } from 'fs'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
const here = dirname(fileURLToPath(import.meta.url))
const view = readFileSync(join(here, 'ConfigurationPoliciesList.vue'), 'utf8')
// The API decides what may be edited; the buttons only reflect that decision.
// These drifted once: policy_routes.py was widened to accept shipped rows while
// the buttons still disabled on source !== 'local', so every shipped policy sat
// behind a dead Edit button and the change looked like it had never rolled.
// If the API guard changes, EDITABLE_SOURCES here changes with it.
describe('the configuration policy buttons follow the API guard', () => {
it('treats shipped as editable, not read-only', () => {
expect(view).toContain("EDITABLE_SOURCES = ['local', 'autoapp', 'shipped']")
})
it('does not gate the buttons on local alone', () => {
expect(view).not.toContain(":disabled=\"p.source !== 'local'\"")
})
it('gates edit and delete on the same rule', () => {
const disabled = view.match(/:disabled="!iseditable\(p\)"/g) || []
expect(disabled).toHaveLength(2)
})
})