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);
+ });
+ },
+);