Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/admin/app/templates/scopes/scope/roles/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<Hds::Button
@route='scopes.scope.roles.new'
@text={{t 'resources.role.titles.new'}}
data-test-new-role-button
/>
{{/if}}
{{/if}}
Expand Down
55 changes: 34 additions & 21 deletions ui/admin/tests/acceptance/roles/create-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@
*/

import { module, test } from 'qunit';
import { visit, currentURL, click, fillIn, find } from '@ember/test-helpers';
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
import { setupApplicationTest } from 'admin/tests/helpers';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import { Response } from 'miragejs';
import { authenticateSession } from 'ember-simple-auth/test-support';
import * as selectors from './selectors';
import * as commonSelectors from 'admin/tests/helpers/selectors';

module('Acceptance | roles | create', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
setupIndexedDb(hooks);

let getRolesCount;

const instances = {
scopes: {
global: null,
Expand All @@ -30,7 +33,6 @@ module('Acceptance | roles | create', function (hooks) {
roles: null,
role: null,
newRole: null,
orgScope: null,
};

hooks.beforeEach(async function () {
Expand Down Expand Up @@ -61,75 +63,86 @@ module('Acceptance | roles | create', function (hooks) {
urls.roles = `/scopes/${instances.scopes.org.id}/roles`;
urls.role = `${urls.roles}/${instances.role.id}`;
urls.newRole = `${urls.roles}/new`;
urls.orgScope = `/scopes/${instances.scopes.org.id}`;
getRolesCount = () => this.server.schema.roles.all().models.length;
});

test('can create new role', async function (assert) {
const rolesCount = this.server.db.roles.length;
const rolesCount = getRolesCount();
await visit(urls.newRole);
await fillIn('[name="name"]', 'role name');
await click('[type="submit"]');
assert.strictEqual(this.server.db.roles.length, rolesCount + 1);

await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE);
await click(commonSelectors.SAVE_BTN);

assert.strictEqual(getRolesCount(), rolesCount + 1);
});

test('Users can navigate to new roles route with proper authorization', async function (assert) {
await visit(urls.roles);

assert.ok(
instances.scopes.org.authorized_collection_actions.roles.includes(
'create',
),
);
assert.ok(find(`[href="${urls.newRole}"]`));
assert.dom(selectors.NEW_ROLE_BTN).isVisible();
assert.dom(commonSelectors.IAM_SIDEBAR_NAV_LINK(urls.roles)).isVisible();
assert.dom(commonSelectors.HREF(urls.newRole)).isVisible();
});

test('Users cannot navigate to new roles route without proper authorization', async function (assert) {
instances.scopes.org.authorized_collection_actions.roles = [];
await visit(urls.roles);

assert.notOk(
instances.scopes.org.authorized_collection_actions.roles.includes(
'create',
),
);
assert.notOk(find(`[href="${urls.newRole}"]`));
assert.dom(selectors.NEW_ROLE_BTN).doesNotExist();
assert.dom(commonSelectors.IAM_SIDEBAR_NAV_LINK(urls.roles)).doesNotExist();
assert.dom(commonSelectors.HREF(urls.newRole)).doesNotExist();
});

test('can cancel new role creation', async function (assert) {
const rolesCount = this.server.db.roles.length;
const rolesCount = getRolesCount();
await visit(urls.newRole);
await fillIn('[name="name"]', 'role name');
await click('.rose-form-actions [type="button"]');

await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE);
await click(commonSelectors.CANCEL_BTN);

assert.strictEqual(currentURL(), urls.roles);
assert.strictEqual(this.server.db.roles.length, rolesCount);
assert.strictEqual(getRolesCount(), rolesCount);
});

test('saving a new role with invalid fields displays error messages', async function (assert) {
const errorMsg =
'Invalid request. Request attempted to make second resource with the same field value that must be unique.';
this.server.post('/roles', () => {
return new Response(
400,
{},
{
status: 400,
code: 'invalid_argument',
message: 'The request was invalid.',
message: errorMsg,
details: {
request_fields: [
{
name: 'name',
description: 'Name is required.',
description: errorMsg,
},
],
},
},
);
});
await visit(urls.newRole);
await fillIn('[name="name"]', 'new target');
await click('form [type="submit"]');

await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE);
await click(commonSelectors.SAVE_BTN);
await a11yAudit();
assert
.dom(commonSelectors.ALERT_TOAST_BODY)
.hasText('The request was invalid.');
assert.ok(find('.hds-form-error__message'));

assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText(errorMsg);
});

test('users cannot directly navigate to new role route without proper authorization', async function (assert) {
Expand Down
6 changes: 6 additions & 0 deletions ui/admin/tests/acceptance/roles/selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

export const NEW_ROLE_BTN = '[data-test-new-role-button]';
1 change: 1 addition & 0 deletions ui/admin/tests/helpers/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const GENERAL_SIDEBAR_NAV_LINK = (url) =>
`[title="General"] a[href="${url}"]`;
export const RESOURCES_SIDEBAR_NAV_LINK = (url) =>
`[title="Resources"] a[href="${url}"]`;
export const IAM_SIDEBAR_NAV_LINK = (url) => `[title="IAM"] a[href="${url}"]`;

export const ALERT_TOAST = '[data-test-toast-notification]';
export const ALERT_TOAST_BODY =
Expand Down
Loading