diff --git a/changelog/19139.txt b/changelog/19139.txt new file mode 100644 index 000000000..75e9a7847 --- /dev/null +++ b/changelog/19139.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: fixes bug in kmip role form that caused `operation_all` to persist after deselecting all operation checkboxes +``` diff --git a/ui/app/models/kmip/role.js b/ui/app/models/kmip/role.js index 5e5a0734d..767b31d11 100644 --- a/ui/app/models/kmip/role.js +++ b/ui/app/models/kmip/role.js @@ -58,7 +58,7 @@ const ModelExport = Model.extend(COMPUTEDS, { ]; const attributes = ['operationAddAttribute', 'operationGetAttributes']; - const server = ['operationDiscoverVersion']; + const server = ['operationDiscoverVersions']; const others = this.operationFieldsWithoutSpecial .slice() .removeObjects(objects.concat(attributes, server)); diff --git a/ui/lib/kmip/addon/components/edit-form-kmip-role.js b/ui/lib/kmip/addon/components/edit-form-kmip-role.js index 3de03f8f8..aad136dfc 100644 --- a/ui/lib/kmip/addon/components/edit-form-kmip-role.js +++ b/ui/lib/kmip/addon/components/edit-form-kmip-role.js @@ -40,6 +40,11 @@ export default EditForm.extend({ if (model.operationAll || model.operationNone) { model.operationFieldsWithoutSpecial.forEach((field) => model.set(field, null)); } + // set operationNone if user unchecks 'operationAll' instead of toggling the 'operationNone' input + // doing here instead of on the 'operationNone' input because a user might deselect all, then reselect some options + // and immediately setting operationNone will hide all of the checkboxes in the UI + this.model.operationNone = + model.operationFieldsWithoutSpecial.every((attr) => !model[attr]) && !this.model.operationAll; }, }, }); diff --git a/ui/tests/integration/components/edit-form-kmip-role-test.js b/ui/tests/integration/components/edit-form-kmip-role-test.js index 4092527c6..9fc988518 100644 --- a/ui/tests/integration/components/edit-form-kmip-role-test.js +++ b/ui/tests/integration/components/edit-form-kmip-role-test.js @@ -68,35 +68,81 @@ module('Integration | Component | edit form kmip role', function (hooks) { }); test('it renders: new model', async function (assert) { + assert.expect(3); const model = createModel({ isNew: true }); this.set('model', model); - await render(hbs``, this.context); + this.onSave = ({ model }) => { + assert.false(model.operationNone, 'callback fires with operationNone as false'); + assert.true(model.operationAll, 'callback fires with operationAll as true'); + }; + await render(hbs``, this.context); assert.dom('[data-test-input="operationAll"]').isChecked('sets operationAll'); + await click('[data-test-edit-form-submit]'); }); test('it renders: operationAll', async function (assert) { + assert.expect(3); const model = createModel({ operationAll: true }); this.set('model', model); - await render(hbs``, this.context); + this.onSave = ({ model }) => { + assert.false(model.operationNone, 'callback fires with operationNone as false'); + assert.true(model.operationAll, 'callback fires with operationAll as true'); + }; + await render(hbs``, this.context); assert.dom('[data-test-input="operationAll"]').isChecked('sets operationAll'); + await click('[data-test-edit-form-submit]'); }); test('it renders: operationNone', async function (assert) { - const model = createModel({ operationNone: true }); + assert.expect(2); + const model = createModel({ operationNone: true, operationAll: undefined }); this.set('model', model); - await render(hbs``, this.context); + this.onSave = ({ model }) => { + assert.true(model.operationNone, 'callback fires with operationNone as true'); + }; + await render(hbs``, this.context); assert.dom('[data-test-input="operationNone"]').isNotChecked('sets operationNone'); + await click('[data-test-edit-form-submit]'); }); test('it renders: choose operations', async function (assert) { + assert.expect(3); const model = createModel({ operationGet: true }); this.set('model', model); - await render(hbs``, this.context); + this.onSave = ({ model }) => { + assert.false(model.operationNone, 'callback fires with operationNone as false'); + }; + await render(hbs``, this.context); assert.dom('[data-test-input="operationNone"]').isChecked('sets operationNone'); assert.dom('[data-test-input="operationAll"]').isNotChecked('sets operationAll'); + await click('[data-test-edit-form-submit]'); + }); + + test('it saves operationNone=true when unchecking operationAll box', async function (assert) { + assert.expect(15); + const model = createModel({ isNew: true }); + this.set('model', model); + this.onSave = ({ model }) => { + assert.true(model.operationNone, 'callback fires with operationNone as true'); + assert.false(model.operationAll, 'callback fires with operationAll as false'); + }; + + await render(hbs``, this.context); + await click('[data-test-input="operationAll"]'); + for (const field of model.fields) { + const { name } = field; + if (name === 'operationNone') continue; + assert.dom(`[data-test-input="${name}"]`).isNotChecked(`${name} is unchecked`); + } + + assert.dom('[data-test-input="operationAll"]').isNotChecked('sets operationAll'); + assert + .dom('[data-test-input="operationNone"]') + .isChecked('operationNone toggle is true which means allow operations'); + await click('[data-test-edit-form-submit]'); }); const savingTests = [