From b9b4e33f5a377da48ffd0034acee91373daaa3b4 Mon Sep 17 00:00:00 2001 From: Lisbet Alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Thu, 23 May 2024 15:35:49 -0700 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20remove=20route-actio?= =?UTF-8?q?n=20usage=20for=20roles=20(#2292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 remove route-action usage for roles ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12608 --- .../components/roles/role/actions/index.hbs | 2 +- .../controllers/scopes/scope/roles/index.js | 69 ++++++++++++++- .../app/controllers/scopes/scope/roles/new.js | 5 ++ .../scopes/scope/roles/role/add-principals.js | 30 +++++++ .../scopes/scope/roles/role/grants.js | 63 +++++++++++++ .../scopes/scope/roles/role/index.js | 5 ++ .../scopes/scope/roles/role/principals.js | 5 ++ ui/admin/app/routes/scopes/scope/roles.js | 53 ----------- .../app/routes/scopes/scope/roles/role.js | 12 --- .../scopes/scope/roles/role/add-principals.js | 26 ------ .../routes/scopes/scope/roles/role/grants.js | 50 +---------- .../scopes/scope/roles/role/principals.js | 21 ----- .../app/templates/scopes/scope/roles/new.hbs | 4 +- .../scope/roles/role/add-principals.hbs | 4 +- .../scopes/scope/roles/role/grants.hbs | 10 +-- .../scopes/scope/roles/role/index.hbs | 6 +- .../scopes/scope/roles/role/principals.hbs | 10 ++- .../scopes/scope/roles/index-test.js | 88 ++++++++++++++++++- .../scopes/scope/roles/new-test.js | 11 +++ .../scope/roles/role/add-principals-test.js | 57 +++++++++++- .../scopes/scope/roles/role/grants-test.js | 88 +++++++++++++++++++ .../scopes/scope/roles/role/index-test.js | 13 +++ .../scope/roles/role/principals-test.js | 16 ++++ 23 files changed, 466 insertions(+), 182 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/roles/new.js create mode 100644 ui/admin/app/controllers/scopes/scope/roles/role/grants.js create mode 100644 ui/admin/app/controllers/scopes/scope/roles/role/index.js create mode 100644 ui/admin/app/controllers/scopes/scope/roles/role/principals.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/roles/role/grants-test.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/roles/role/index-test.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/roles/role/principals-test.js diff --git a/ui/admin/app/components/roles/role/actions/index.hbs b/ui/admin/app/components/roles/role/actions/index.hbs index 79435f3c8..c12a990e8 100644 --- a/ui/admin/app/components/roles/role/actions/index.hbs +++ b/ui/admin/app/components/roles/role/actions/index.hbs @@ -18,7 +18,7 @@ {{t 'resources.role.actions.delete'}} diff --git a/ui/admin/app/controllers/scopes/scope/roles/index.js b/ui/admin/app/controllers/scopes/scope/roles/index.js index 8fc10cfa7..bae84f230 100644 --- a/ui/admin/app/controllers/scopes/scope/roles/index.js +++ b/ui/admin/app/controllers/scopes/scope/roles/index.js @@ -6,13 +6,17 @@ import Controller from '@ember/controller'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; +import { loading } from 'ember-loading'; import { tracked } from '@glimmer/tracking'; import { debounce } from 'core/decorators/debounce'; +import { confirm } from 'core/decorators/confirm'; +import { notifySuccess, notifyError } from 'core/decorators/notify'; export default class ScopesScopeRolesIndexController extends Controller { // =services - @service intl; + @service can; + @service router; // =attributes @@ -22,7 +26,7 @@ export default class ScopesScopeRolesIndexController extends Controller { @tracked page = 1; @tracked pageSize = 10; - // =methods + // =actions /** * Handles input on each keystroke and the search queryParam @@ -35,4 +39,65 @@ export default class ScopesScopeRolesIndexController extends Controller { this.search = value; this.page = 1; } + + /** + * Rollback changes on an role. + * @param {RoleModel} role + */ + @action + cancel(role) { + const { isNew } = role; + role.rollbackAttributes(); + if (isNew) this.router.transitionTo('scopes.scope.roles'); + } + + /** + * Save an role in current scope. + * @param {RoleModel} role + */ + @action + @loading + @notifyError(({ message }) => message) + @notifySuccess(({ isNew }) => + isNew ? 'notifications.create-success' : 'notifications.save-success', + ) + async save(role) { + await role.save(); + if (this.can.can('read model', role)) { + await this.router.transitionTo('scopes.scope.roles.role', role); + } else { + await this.router.transitionTo('scopes.scope.roles'); + } + await this.router.refresh(); + } + + /** + * Delete role in current scope and redirect to index. + * @param {RoleModel} role + */ + @action + @loading + @confirm('questions.delete-confirm') + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.delete-success') + async delete(role) { + await role.destroyRecord(); + this.router.replaceWith('scopes.scope.roles'); + await this.router.refresh(); + } + + /** + * Remove a principal from the current role and redirect to principals index. + * @param {RoleModel} role + * @param {UserModel, GroupModel, ManagedGroupModel} principal + */ + @action + @loading + @confirm('questions.remove-confirm') + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.remove-success') + async removePrincipal(role, principal) { + await role.removePrincipal(principal.id); + await this.router.refresh(); + } } diff --git a/ui/admin/app/controllers/scopes/scope/roles/new.js b/ui/admin/app/controllers/scopes/scope/roles/new.js new file mode 100644 index 000000000..f97ed248d --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/roles/new.js @@ -0,0 +1,5 @@ +import Controller, { inject as controller } from '@ember/controller'; + +export default class ScopesScopeRolesNewController extends Controller { + @controller('scopes/scope/roles/index') roles; +} diff --git a/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js b/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js index d1f59e215..052280a82 100644 --- a/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js +++ b/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js @@ -4,10 +4,16 @@ */ import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; +import { loading } from 'ember-loading'; +import { notifySuccess, notifyError } from 'core/decorators/notify'; export default class ScopesScopeRolesRoleAddPrincipalsController extends Controller { // =services + @service router; + // =attributes /** @@ -26,4 +32,28 @@ export default class ScopesScopeRolesRoleAddPrincipalsController extends Control const sorted = [global, ...orgsAndProjects].flat(); return sorted; } + + // =actions + + /** + * Save principal IDs to current role via the API. + * @param {RoleModel} role + * @param {[string]} principalIDs + */ + @action + @loading + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.add-success') + async addPrincipals(role, principalIDs) { + await role.addPrincipals(principalIDs); + this.router.replaceWith('scopes.scope.roles.role.principals'); + } + + /** + * Redirect to role principals as if nothing ever happened. + */ + @action + cancel() { + this.router.replaceWith('scopes.scope.roles.role.principals'); + } } diff --git a/ui/admin/app/controllers/scopes/scope/roles/role/grants.js b/ui/admin/app/controllers/scopes/scope/roles/role/grants.js new file mode 100644 index 000000000..8b4533b56 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/roles/role/grants.js @@ -0,0 +1,63 @@ +import Controller, { inject as controller } from '@ember/controller'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; +import { loading } from 'ember-loading'; +import { notifySuccess, notifyError } from 'core/decorators/notify'; + +export default class ScopesScopeRolesRoleGrantsController extends Controller { + @controller('scopes/scope/roles/index') roles; + + // =services + + @service router; + + // =actions + + /** + * Adds a new grant to the role at the beginning of the grants list. + * Grant creation is not immediately permanent; users may rollback the change + * via "cancel" or commit it via "save". + * @param {RoleModel} role + * @param {string} grantString + */ + @action + addGrant(role, grantString) { + role.grant_strings = [grantString].concat(role.grant_strings); + } + + /** + * Removes a grant from the role. Grant removal is not immediately permanent; + * users may rollback the change via "cancel" or commit it via "save". + * @param {RoleModel} role + * @param {string} grantString + */ + @action + removeGrant(role, grantString) { + role.grant_strings = role.grant_strings.filter( + (str) => str !== grantString, + ); + } + + /** + * Save a role. + * @param {RoleModel} role + * @param {[string]} grantStrings + */ + @action + @loading + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.save-success') + async save(role, grantStrings) { + await role.saveGrantStrings(grantStrings); + } + + /** + * Rollback changes on a role. + * @param {RoleModel} role + */ + @action + async cancel(role) { + role.rollbackAttributes(); + await this.router.refresh('scopes.scope.roles.role'); + } +} diff --git a/ui/admin/app/controllers/scopes/scope/roles/role/index.js b/ui/admin/app/controllers/scopes/scope/roles/role/index.js new file mode 100644 index 000000000..425842ba2 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/roles/role/index.js @@ -0,0 +1,5 @@ +import Controller, { inject as controller } from '@ember/controller'; + +export default class ScopesScopeRolesRoleIndexController extends Controller { + @controller('scopes/scope/roles/index') roles; +} diff --git a/ui/admin/app/controllers/scopes/scope/roles/role/principals.js b/ui/admin/app/controllers/scopes/scope/roles/role/principals.js new file mode 100644 index 000000000..83e7806f9 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/roles/role/principals.js @@ -0,0 +1,5 @@ +import Controller, { inject as controller } from '@ember/controller'; + +export default class ScopesScopeRolesRolePrincipalsController extends Controller { + @controller('scopes/scope/roles/index') roles; +} diff --git a/ui/admin/app/routes/scopes/scope/roles.js b/ui/admin/app/routes/scopes/scope/roles.js index 4801d1410..bd5021640 100644 --- a/ui/admin/app/routes/scopes/scope/roles.js +++ b/ui/admin/app/routes/scopes/scope/roles.js @@ -5,16 +5,11 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; -import { action } from '@ember/object'; -import { loading } from 'ember-loading'; -import { confirm } from 'core/decorators/confirm'; -import { notifySuccess, notifyError } from 'core/decorators/notify'; export default class ScopesScopeRolesRoute extends Route { // =services @service session; - @service can; @service router; // =methods @@ -25,52 +20,4 @@ export default class ScopesScopeRolesRoute extends Route { beforeModel() { if (!this.session.isAuthenticated) this.router.transitionTo('index'); } - - // =actions - - /** - * Rollback changes on an role. - * @param {RoleModel} role - */ - @action - cancel(role) { - const { isNew } = role; - role.rollbackAttributes(); - if (isNew) this.router.transitionTo('scopes.scope.roles'); - } - - /** - * Save an role in current scope. - * @param {RoleModel} role - */ - @action - @loading - @notifyError(({ message }) => message) - @notifySuccess(({ isNew }) => - isNew ? 'notifications.create-success' : 'notifications.save-success', - ) - async save(role) { - await role.save(); - if (this.can.can('read model', role)) { - await this.router.transitionTo('scopes.scope.roles.role', role); - } else { - await this.router.transitionTo('scopes.scope.roles'); - } - this.refresh(); - } - - /** - * Delete role in current scope and redirect to index. - * @param {RoleModel} role - */ - @action - @loading - @confirm('questions.delete-confirm') - @notifyError(({ message }) => message, { catch: true }) - @notifySuccess('notifications.delete-success') - async delete(role) { - await role.destroyRecord(); - this.router.replaceWith('scopes.scope.roles'); - this.refresh(); - } } diff --git a/ui/admin/app/routes/scopes/scope/roles/role.js b/ui/admin/app/routes/scopes/scope/roles/role.js index a32dd419d..5c74c405e 100644 --- a/ui/admin/app/routes/scopes/scope/roles/role.js +++ b/ui/admin/app/routes/scopes/scope/roles/role.js @@ -4,7 +4,6 @@ */ import Route from '@ember/routing/route'; -import { action } from '@ember/object'; import { inject as service } from '@ember/service'; export default class ScopesScopeRolesRoleRoute extends Route { @@ -41,15 +40,4 @@ export default class ScopesScopeRolesRoleRoute extends Route { this.router.replaceWith(transition.to.name, role.scopeID, role.id); } } - - // =actions - /** - * Rollback changes on a role. - * @param {RoleModel} role - */ - @action - cancel(role) { - role.rollbackAttributes(); - this.refresh(); - } } diff --git a/ui/admin/app/routes/scopes/scope/roles/role/add-principals.js b/ui/admin/app/routes/scopes/scope/roles/role/add-principals.js index 041cde507..5f79f8874 100644 --- a/ui/admin/app/routes/scopes/scope/roles/role/add-principals.js +++ b/ui/admin/app/routes/scopes/scope/roles/role/add-principals.js @@ -6,8 +6,6 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; -import { loading } from 'ember-loading'; -import { notifySuccess, notifyError } from 'core/decorators/notify'; import { resourceFilter } from 'core/decorators/resource-filter'; import { TYPE_AUTH_METHOD_OIDC, @@ -88,30 +86,6 @@ export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route { }; } - // =actions - - /** - * Save principal IDs to current role via the API. - * @param {RoleModel} role - * @param {[string]} principalIDs - */ - @action - @loading - @notifyError(({ message }) => message, { catch: true }) - @notifySuccess('notifications.add-success') - async addPrincipals(role, principalIDs) { - await role.addPrincipals(principalIDs); - this.router.replaceWith('scopes.scope.roles.role.principals'); - } - - /** - * Redirect to role principals as if nothing ever happened. - */ - @action - cancel() { - this.router.replaceWith('scopes.scope.roles.role.principals'); - } - /** * Sets the specified resource filter field to the specified value. * @param {string} field diff --git a/ui/admin/app/routes/scopes/scope/roles/role/grants.js b/ui/admin/app/routes/scopes/scope/roles/role/grants.js index 750f47e4f..39d9ff8ed 100644 --- a/ui/admin/app/routes/scopes/scope/roles/role/grants.js +++ b/ui/admin/app/routes/scopes/scope/roles/role/grants.js @@ -4,53 +4,5 @@ */ import Route from '@ember/routing/route'; -import { inject as service } from '@ember/service'; -import { action } from '@ember/object'; -import { loading } from 'ember-loading'; -import { notifySuccess, notifyError } from 'core/decorators/notify'; -export default class ScopesScopeRolesRoleGrantsRoute extends Route { - // =services - - @service intl; - - // =actions - - /** - * Adds a new grant to the role at the beginning of the grants list. - * Grant creation is not immediately permanent; users may rollback the change - * via "cancel" or commit it via "save". - * @param {RoleModel} role - * @param {string} grantString - */ - @action - addGrant(role, grantString) { - role.grant_strings = [grantString].concat(role.grant_strings); - } - - /** - * Removes a grant from the role. Grant removal is not immediately permanent; - * users may rollback the change via "cancel" or commit it via "save". - * @param {RoleModel} role - * @param {string} grantString - */ - @action - removeGrant(role, grantString) { - role.grant_strings = role.grant_strings.filter( - (str) => str !== grantString, - ); - } - - /** - * Save a role. - * @param {RoleModel} role - * @param {[string]} grantStrings - */ - @action - @loading - @notifyError(({ message }) => message, { catch: true }) - @notifySuccess('notifications.save-success') - async save(role, grantStrings) { - await role.saveGrantStrings(grantStrings); - } -} +export default class ScopesScopeRolesRoleGrantsRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/roles/role/principals.js b/ui/admin/app/routes/scopes/scope/roles/role/principals.js index ec1a60e30..b69dcc0d1 100644 --- a/ui/admin/app/routes/scopes/scope/roles/role/principals.js +++ b/ui/admin/app/routes/scopes/scope/roles/role/principals.js @@ -4,11 +4,7 @@ */ import Route from '@ember/routing/route'; -import { action } from '@ember/object'; import { inject as service } from '@ember/service'; -import { loading } from 'ember-loading'; -import { confirm } from 'core/decorators/confirm'; -import { notifySuccess, notifyError } from 'core/decorators/notify'; import { TYPE_AUTH_METHOD_OIDC, TYPE_AUTH_METHOD_LDAP, @@ -118,21 +114,4 @@ export default class ScopesScopeRolesRolePrincipalsRoute extends Route { } return managedGroups; } - - // =actions - - /** - * Remove a principal from the current role and redirect to principals index. - * @param {UserModel, GroupModel, ManagedGroupModel} principal - */ - @action - @loading - @confirm('questions.remove-confirm') - @notifyError(({ message }) => message, { catch: true }) - @notifySuccess('notifications.remove-success') - async removePrincipal(principal) { - const role = this.modelFor('scopes.scope.roles.role'); - await role.removePrincipal(principal.id); - this.refresh(); - } } diff --git a/ui/admin/app/templates/scopes/scope/roles/new.hbs b/ui/admin/app/templates/scopes/scope/roles/new.hbs index c89df5fa5..4bd963a39 100644 --- a/ui/admin/app/templates/scopes/scope/roles/new.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/new.hbs @@ -25,8 +25,8 @@ \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs b/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs index b9dd928da..3bd48fe31 100644 --- a/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs @@ -88,8 +88,8 @@ @users={{@model.users}} @groups={{@model.groups}} @managedGroups={{@model.managedGroups}} - @submit={{route-action 'addPrincipals' @model.role}} - @cancel={{route-action 'cancel'}} + @submit={{fn this.addPrincipals @model.role}} + @cancel={{this.cancel}} /> diff --git a/ui/admin/app/templates/scopes/scope/roles/role/grants.hbs b/ui/admin/app/templates/scopes/scope/roles/role/grants.hbs index dad5a01d4..d5e38775d 100644 --- a/ui/admin/app/templates/scopes/scope/roles/role/grants.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/role/grants.hbs @@ -25,7 +25,7 @@ - + @@ -35,10 +35,10 @@ diff --git a/ui/admin/app/templates/scopes/scope/roles/role/index.hbs b/ui/admin/app/templates/scopes/scope/roles/role/index.hbs index 893f81746..a2e0b25d3 100644 --- a/ui/admin/app/templates/scopes/scope/roles/role/index.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/role/index.hbs @@ -14,7 +14,7 @@ - + @@ -25,8 +25,8 @@ diff --git a/ui/admin/app/templates/scopes/scope/roles/role/principals.hbs b/ui/admin/app/templates/scopes/scope/roles/role/principals.hbs index 1326bd7d6..a37fbfbec 100644 --- a/ui/admin/app/templates/scopes/scope/roles/role/principals.hbs +++ b/ui/admin/app/templates/scopes/scope/roles/role/principals.hbs @@ -25,7 +25,10 @@ - + @@ -81,7 +84,10 @@ {{/if}} diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/index-test.js index 8efecba77..894339fad 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles/index-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/index-test.js @@ -5,13 +5,53 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -import { waitUntil } from '@ember/test-helpers'; +import { waitUntil, visit } from '@ember/test-helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { setupIndexedDb } from 'api/test-support/helpers/indexed-db'; +import { authenticateSession } from 'ember-simple-auth/test-support'; module('Unit | Controller | scopes/scope/roles/index', function (hooks) { setupTest(hooks); + setupMirage(hooks); + setupIndexedDb(hooks); + + let store; + let controller; + let getRoleCount; + + const instances = { + scopes: { + global: null, + }, + role: null, + user: null, + }; + + const urls = { + globalScope: null, + roles: null, + }; + + hooks.beforeEach(async function () { + authenticateSession({}); + store = this.owner.lookup('service:store'); + controller = this.owner.lookup('controller:scopes/scope/roles/index'); + + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.role = this.server.create('role', { + scopeId: 'global', + }); + instances.user = this.server.create('user', { + scopeId: 'global', + }); + + urls.globalScope = `/scopes/global`; + urls.roles = `${urls.globalScope}/roles`; + + getRoleCount = () => this.server.schema.roles.all().models.length; + }); test('it exists', function (assert) { - let controller = this.owner.lookup('controller:scopes/scope/roles/index'); assert.ok(controller); }); @@ -24,4 +64,48 @@ module('Unit | Controller | scopes/scope/roles/index', function (hooks) { assert.strictEqual(controller.page, 1); assert.strictEqual(controller.search, searchValue); }); + + test('cancel action rolls-back changes on the specified model', async function (assert) { + await visit(urls.roles); + const role = await store.findRecord('role', instances.role.id); + role.name = 'test'; + + assert.strictEqual(role.name, 'test'); + + await controller.cancel(role); + + assert.notEqual(role.name, 'test'); + }); + + test('save action saves changes on the specified model', async function (assert) { + await visit(urls.roles); + const role = await store.findRecord('role', instances.role.id); + role.name = 'test'; + + await controller.save(role); + + assert.strictEqual(role.name, 'test'); + }); + + test('delete action destroys specified model', async function (assert) { + const role = await store.findRecord('role', instances.role.id); + const roleCount = getRoleCount(); + + await controller.delete(role); + + assert.strictEqual(getRoleCount(), roleCount - 1); + }); + + test('removePrincipal action removes a principal from specified model', async function (assert) { + const role = await store.findRecord('role', instances.role.id); + await role.addPrincipals([instances.user.id]); + + assert.deepEqual(role.principals, [ + { id: instances.user.id, scope_id: instances.user.scopeId, type: 'user' }, + ]); + + await controller.removePrincipal(role, instances.user); + + assert.deepEqual(role.principals, []); + }); }); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js new file mode 100644 index 000000000..f42c4638e --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/roles/new', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup('controller:scopes/scope/roles/new'); + assert.ok(controller); + }); +}); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js index f1582419c..92ec82b53 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js @@ -5,17 +5,70 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import { visit } from '@ember/test-helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; module( 'Unit | Controller | scopes/scope/roles/role/add-principals', function (hooks) { setupTest(hooks); + setupMirage(hooks); - test('it exists', function (assert) { - let controller = this.owner.lookup( + let store; + let controller; + + const instances = { + scopes: { + global: null, + }, + role: null, + user: null, + }; + + const urls = { + globalScope: null, + addPrincipals: null, + }; + + hooks.beforeEach(async function () { + authenticateSession({}); + store = this.owner.lookup('service:store'); + controller = this.owner.lookup( 'controller:scopes/scope/roles/role/add-principals', ); + + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.role = this.server.create('role', { + scopeId: 'global', + }); + instances.user = this.server.create('user', { + scopeId: 'global', + }); + + urls.globalScope = `/scopes/global`; + urls.addPrincipals = `${urls.globalScope}/roles/${instances.role.id}/add-principals`; + }); + + test('it exists', function (assert) { assert.ok(controller); }); + + test('addPrincipals action adds principals to specified model', async function (assert) { + await visit(urls.addPrincipals); + const role = await store.findRecord('role', instances.role.id); + + assert.deepEqual(role.principals, []); + + await controller.addPrincipals(role, [instances.user.id]); + + assert.deepEqual(role.principals, [ + { + id: instances.user.id, + scope_id: instances.user.scopeId, + type: 'user', + }, + ]); + }); }, ); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/grants-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/grants-test.js new file mode 100644 index 000000000..8f3d5f6bd --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/grants-test.js @@ -0,0 +1,88 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { visit } from '@ember/test-helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Unit | Controller | scopes/scope/roles/role/grants', function (hooks) { + setupTest(hooks); + setupMirage(hooks); + + let store; + let controller; + + const instances = { + scopes: { + global: null, + }, + role: null, + }; + + const urls = { + globalScope: null, + grants: null, + }; + + hooks.beforeEach(async function () { + authenticateSession({}); + store = this.owner.lookup('service:store'); + controller = this.owner.lookup('controller:scopes/scope/roles/role/grants'); + + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.role = this.server.create('role', { + scopeId: 'global', + }); + + urls.globalScope = `/scopes/global`; + urls.grants = `${urls.globalScope}/roles/${instances.role.id}/grants`; + }); + + test('it exists', function (assert) { + assert.ok(controller); + }); + + test('cancel action rolls-back changes on the specified model', async function (assert) { + await visit(urls.grants); + const role = await store.findRecord('role', instances.role.id); + const grantStrings = role.grant_strings; + role.grant_strings = ['ids=*;type=*;actions=read']; + + assert.deepEqual(role.grant_strings, ['ids=*;type=*;actions=read']); + + await controller.cancel(role); + + assert.deepEqual(role.grant_strings, grantStrings); + }); + + test('save action saves grantStrings to specified model', async function (assert) { + await visit(urls.grants); + const role = await store.findRecord('role', instances.role.id); + const grantStrings = role.grant_strings; + const newGrantStrings = [...grantStrings, 'ids=*;type=*;actions=read']; + + await controller.save(role, newGrantStrings); + + assert.deepEqual(role.grant_strings, newGrantStrings); + }); + + test('removeGrant action removes a grant string from a role', async function (assert) { + await visit(urls.grants); + const role = await store.findRecord('role', instances.role.id); + const grantStrings = role.grant_strings; + + await controller.removeGrant(role, grantStrings[0]); + + assert.deepEqual(role.grant_strings, grantStrings.slice(1)); + }); + + test('addGrant action adds a grant string from a role', async function (assert) { + await visit(urls.grants); + const role = await store.findRecord('role', instances.role.id); + const grantStrings = role.grant_strings; + const grantString = 'ids=*;type=*;actions=read'; + + await controller.addGrant(role, grantString); + + assert.deepEqual(role.grant_strings, [grantString, ...grantStrings]); + }); +}); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/index-test.js new file mode 100644 index 000000000..4ece89b3f --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/index-test.js @@ -0,0 +1,13 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/roles/role/index', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/roles/role/index', + ); + assert.ok(controller); + }); +}); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/principals-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/principals-test.js new file mode 100644 index 000000000..96a216fb0 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/principals-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module( + 'Unit | Controller | scopes/scope/roles/role/principals', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/roles/role/principals', + ); + assert.ok(controller); + }); + }, +);