fcf6467cbf
* cleanup infotableitemarray, add render name option to component * wait until items fetched before rendering child component * update test * finish tests for info table item array * remove unused capability checks * remove unnecessary path alias * fix info table row arg * fix wildcards getting info tooltip
350 lines
14 KiB
JavaScript
350 lines
14 KiB
JavaScript
import { module, test } from 'qunit';
|
||
import { visit, currentURL, click, fillIn, findAll, currentRouteName } from '@ember/test-helpers';
|
||
import { setupApplicationTest } from 'ember-qunit';
|
||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||
import ENV from 'vault/config/environment';
|
||
import authPage from 'vault/tests/pages/auth';
|
||
import logout from 'vault/tests/pages/logout';
|
||
import { create } from 'ember-cli-page-object';
|
||
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
||
import ss from 'vault/tests/pages/components/search-select';
|
||
import fm from 'vault/tests/pages/components/flash-message';
|
||
import {
|
||
OIDC_BASE_URL, // -> '/vault/access/oidc'
|
||
SELECTORS,
|
||
clearRecord,
|
||
overrideCapabilities,
|
||
overrideMirageResponse,
|
||
ASSIGNMENT_LIST_RESPONSE,
|
||
ASSIGNMENT_DATA_RESPONSE,
|
||
} from 'vault/tests/helpers/oidc-config';
|
||
const searchSelect = create(ss);
|
||
const flashMessage = create(fm);
|
||
|
||
module('Acceptance | oidc-config clients and assignments', function (hooks) {
|
||
setupApplicationTest(hooks);
|
||
setupMirage(hooks);
|
||
|
||
hooks.before(function () {
|
||
ENV['ember-cli-mirage'].handler = 'oidcConfig';
|
||
});
|
||
|
||
hooks.beforeEach(async function () {
|
||
this.store = await this.owner.lookup('service:store');
|
||
return authPage.login();
|
||
});
|
||
|
||
hooks.afterEach(function () {
|
||
return logout.visit();
|
||
});
|
||
|
||
hooks.after(function () {
|
||
ENV['ember-cli-mirage'].handler = null;
|
||
});
|
||
|
||
test('it renders only allow_all when no assignments are configured', async function (assert) {
|
||
assert.expect(3);
|
||
|
||
//* clear out test state
|
||
await clearRecord(this.store, 'oidc/assignment', 'test-assignment');
|
||
|
||
await visit(OIDC_BASE_URL + '/assignments');
|
||
assert.equal(currentURL(), '/vault/access/oidc/assignments');
|
||
assert.dom('[data-test-tab="assignments"]').hasClass('active', 'assignments tab is active');
|
||
assert
|
||
.dom('[data-test-oidc-assignment-linked-block="allow_all"]')
|
||
.hasClass('is-disabled', 'renders default allow all assignment and is disabled.');
|
||
});
|
||
|
||
test('it renders empty state when no clients are configured', async function (assert) {
|
||
assert.expect(5);
|
||
this.server.get('/identity/oidc/client', () => overrideMirageResponse(404));
|
||
|
||
await visit(OIDC_BASE_URL);
|
||
assert.equal(currentURL(), '/vault/access/oidc');
|
||
assert.dom('h1.title.is-3').hasText('OIDC Provider');
|
||
assert.dom(SELECTORS.oidcHeader).hasText(
|
||
`Configure Vault to act as an OIDC identity provider, and offer Vault’s various authentication
|
||
methods and source of identity to any client applications. Learn more Create your first app`,
|
||
'renders call to action header when no clients are configured'
|
||
);
|
||
assert.dom('[data-test-oidc-landing]').exists('landing page renders when no clients are configured');
|
||
assert
|
||
.dom(SELECTORS.oidcLandingImg)
|
||
.hasAttribute('src', '/ui/images/oidc-landing.png', 'image renders image when no clients configured');
|
||
});
|
||
|
||
test('it creates an assignment inline, creates a client, updates client to limit access, deletes client', async function (assert) {
|
||
assert.expect(22);
|
||
|
||
//* clear out test state
|
||
await clearRecord(this.store, 'oidc/client', 'test-app');
|
||
await clearRecord(this.store, 'oidc/client', 'my-webapp'); // created by oidc-provider-test
|
||
await clearRecord(this.store, 'oidc/assignment', 'assignment-inline');
|
||
|
||
// create a client with allow all access
|
||
await visit(OIDC_BASE_URL + '/clients/create');
|
||
assert.equal(currentRouteName(), 'vault.cluster.access.oidc.clients.create', 'navigates to create form');
|
||
await fillIn('[data-test-input="name"]', 'test-app');
|
||
await click('[data-test-toggle-group="More options"]');
|
||
// toggle ttls to false, testing it sets correct default duration
|
||
await click('[data-test-input="idTokenTtl"]');
|
||
await click('[data-test-input="accessTokenTtl"]');
|
||
await click(SELECTORS.clientSaveButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Successfully created the application test-app.',
|
||
'renders success flash upon client creation'
|
||
);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.clients.client.details',
|
||
'navigates to client details view after save'
|
||
);
|
||
// assert default values in details view are correct
|
||
assert.dom('[data-test-value-div="Assignment"]').hasText('allow_all', 'client allows all assignments');
|
||
assert.dom('[data-test-value-div="Type"]').hasText('confidential', 'type defaults to confidential');
|
||
assert
|
||
.dom('[data-test-value-div="Key"] a')
|
||
.hasText('default', 'client uses default key and renders a link');
|
||
assert
|
||
.dom('[data-test-value-div="Client ID"] [data-test-copy-button]')
|
||
.exists('client ID exists and has copy button');
|
||
assert
|
||
.dom('[data-test-value-div="Client Secret"] [data-test-copy-button]')
|
||
.exists('client secret exists and has copy button');
|
||
assert
|
||
.dom('[data-test-value-div="ID Token TTL"]')
|
||
.hasText('1 day', 'ID token ttl toggled off sets default of 24h');
|
||
assert
|
||
.dom('[data-test-value-div="Access Token TTL"]')
|
||
.hasText('1 day', 'access token ttl toggled off sets default of 24h');
|
||
|
||
// edit client
|
||
await click(SELECTORS.clientDetailsTab);
|
||
await click(SELECTORS.clientEditButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.clients.client.edit',
|
||
'navigates to edit page from details'
|
||
);
|
||
await fillIn('[data-test-input="redirectUris"] [data-test-string-list-input="0"]', 'some-url.com');
|
||
|
||
// limit access & create new assignment inline
|
||
await click('label[for=limited]');
|
||
await clickTrigger();
|
||
await fillIn('.ember-power-select-search input', 'assignment-inline');
|
||
await searchSelect.options.objectAt(0).click();
|
||
await click('[data-test-search-select="entities"] .ember-basic-dropdown-trigger');
|
||
await searchSelect.options.objectAt(0).click();
|
||
await click('[data-test-search-select="groups"] .ember-basic-dropdown-trigger');
|
||
await searchSelect.options.objectAt(0).click();
|
||
await click(SELECTORS.assignmentSaveButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Successfully created the assignment assignment-inline.',
|
||
'renders success flash upon assignment creating'
|
||
);
|
||
await click(SELECTORS.clientSaveButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Successfully updated the application test-app.',
|
||
'renders success flash upon client updating'
|
||
);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.clients.client.details',
|
||
'navigates back to details on update'
|
||
);
|
||
assert.dom('[data-test-value-div="Redirect URI"]').hasText('some-url.com', 'shows updated attribute');
|
||
assert
|
||
.dom('[data-test-value-div="Assignment"]')
|
||
.hasText('assignment-inline', 'updated to limited assignment');
|
||
|
||
// edit back to allow_all
|
||
await click(SELECTORS.clientEditButton);
|
||
assert.dom(SELECTORS.clientSaveButton).hasText('Update', 'form button renders correct text');
|
||
await click('label[for=allow-all]');
|
||
await click(SELECTORS.clientSaveButton);
|
||
assert
|
||
.dom('[data-test-value-div="Assignment"]')
|
||
.hasText('allow_all', 'client updated to allow all assignments');
|
||
|
||
// create another client
|
||
await visit(OIDC_BASE_URL + '/clients/create');
|
||
await fillIn('[data-test-input="name"]', 'app-to-delete');
|
||
await click(SELECTORS.clientSaveButton);
|
||
|
||
// immediately delete client, test transition
|
||
await click(SELECTORS.clientDeleteButton);
|
||
await click(SELECTORS.confirmActionButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Application deleted successfully',
|
||
'renders success flash upon deleting client'
|
||
);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.clients.index',
|
||
'navigates back to list view after delete'
|
||
);
|
||
// delete last client
|
||
await click('[data-test-oidc-client-linked-block]');
|
||
assert.equal(currentRouteName(), 'vault.cluster.access.oidc.clients.client.details');
|
||
await click(SELECTORS.clientDeleteButton);
|
||
await click(SELECTORS.confirmActionButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.index',
|
||
'redirects to call to action if only existing client is deleted'
|
||
);
|
||
//* clean up test state
|
||
await clearRecord(this.store, 'oidc/assignment', 'assignment-inline');
|
||
});
|
||
|
||
test('it creates, updates, and deletes an assignment', async function (assert) {
|
||
assert.expect(12);
|
||
await visit(OIDC_BASE_URL + '/assignments');
|
||
|
||
//* ensure clean test state
|
||
await clearRecord(this.store, 'oidc/assignment', 'test-assignment');
|
||
|
||
// create a new assignment
|
||
await click(SELECTORS.assignmentCreateButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.create',
|
||
'navigates to create form'
|
||
);
|
||
await fillIn('[data-test-input="name"]', 'test-assignment');
|
||
await click('[data-test-component="search-select"]#entities .ember-basic-dropdown-trigger');
|
||
await click('.ember-power-select-option');
|
||
await click(SELECTORS.assignmentSaveButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Successfully created the assignment test-assignment.',
|
||
'renders success flash upon creating the assignment'
|
||
);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.assignment.details',
|
||
'navigates to the assignments detail view after save'
|
||
);
|
||
|
||
// assert default values in assignment details view are correct
|
||
assert.dom('[data-test-value-div="Name"]').hasText('test-assignment');
|
||
assert.dom('[data-test-value-div="Entities"]').hasText('test-entity', 'shows the entity name.');
|
||
|
||
// edit assignment
|
||
await click(SELECTORS.assignmentEditButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.assignment.edit',
|
||
'navigates to the assignment edit page from details'
|
||
);
|
||
await click('[data-test-component="search-select"]#groups .ember-basic-dropdown-trigger');
|
||
await click('.ember-power-select-option');
|
||
assert.dom('[data-test-oidc-assignment-save]').hasText('Update');
|
||
await click(SELECTORS.assignmentSaveButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Successfully updated the assignment test-assignment.',
|
||
'renders success flash upon updating the assignment'
|
||
);
|
||
|
||
assert.dom('[data-test-value-div="Entities"]').hasText('test-entity', 'it still shows the entity name.');
|
||
assert.dom('[data-test-value-div="Groups"]').hasText('test-group', 'shows updated group name id.');
|
||
|
||
// delete the assignment
|
||
await click(SELECTORS.assignmentDeleteButton);
|
||
await click(SELECTORS.confirmActionButton);
|
||
assert.equal(
|
||
flashMessage.latestMessage,
|
||
'Assignment deleted successfully',
|
||
'renders success flash upon deleting assignment'
|
||
);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.index',
|
||
'navigates back to assignment list view after delete'
|
||
);
|
||
});
|
||
|
||
test('it navigates to and from an assignment from the list view', async function (assert) {
|
||
assert.expect(6);
|
||
this.server.get('/identity/oidc/assignment', () =>
|
||
overrideMirageResponse(null, ASSIGNMENT_LIST_RESPONSE)
|
||
);
|
||
this.server.get('/identity/oidc/assignment/test-assignment', () =>
|
||
overrideMirageResponse(null, ASSIGNMENT_DATA_RESPONSE)
|
||
);
|
||
await visit(OIDC_BASE_URL + '/assignments');
|
||
assert
|
||
.dom('[data-test-oidc-assignment-linked-block="test-assignment"]')
|
||
.exists('displays linked block for test-assignment');
|
||
|
||
await click(SELECTORS.assignmentCreateButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.create',
|
||
'assignments index toolbar navigates to create form'
|
||
);
|
||
await click(SELECTORS.assignmentCancelButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.index',
|
||
'create form navigates back to assignment index on cancel'
|
||
);
|
||
|
||
await click('[data-test-popup-menu-trigger]');
|
||
await click('[data-test-oidc-assignment-menu-link="edit"]');
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.assignment.edit',
|
||
'linked block popup menu navigates to edit'
|
||
);
|
||
await click(SELECTORS.assignmentCancelButton);
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.assignment.details',
|
||
'edit form navigates back to assignment details on cancel'
|
||
);
|
||
// navigate to details from index page
|
||
await visit('/vault/access/oidc/assignments');
|
||
await click('[data-test-popup-menu-trigger]');
|
||
await click('[data-test-oidc-assignment-menu-link="details"]');
|
||
assert.equal(
|
||
currentRouteName(),
|
||
'vault.cluster.access.oidc.assignments.assignment.details',
|
||
'popup menu navigates to assignment details'
|
||
);
|
||
});
|
||
|
||
test('it hides assignment delete and edit when no permission', async function (assert) {
|
||
assert.expect(5);
|
||
this.server.get('/identity/oidc/assignment', () =>
|
||
overrideMirageResponse(null, ASSIGNMENT_LIST_RESPONSE)
|
||
);
|
||
this.server.get('/identity/oidc/assignment/test-assignment', () =>
|
||
overrideMirageResponse(null, ASSIGNMENT_DATA_RESPONSE)
|
||
);
|
||
this.server.post('/sys/capabilities-self', () =>
|
||
overrideCapabilities(OIDC_BASE_URL + '/assignment/test-assignment', ['read'])
|
||
);
|
||
|
||
await visit(OIDC_BASE_URL + '/assignments');
|
||
await click('[data-test-oidc-assignment-linked-block="test-assignment"]');
|
||
assert
|
||
.dom('[data-test-oidc-assignment-title]')
|
||
.hasText('test-assignment', 'renders assignment name as title');
|
||
assert.dom(SELECTORS.assignmentDetailsTab).hasClass('active', 'details tab is active');
|
||
assert.dom(SELECTORS.assignmentDeleteButton).doesNotExist('delete option is hidden');
|
||
assert.dom(SELECTORS.assignmentEditButton).doesNotExist('edit button is hidden');
|
||
assert.equal(
|
||
findAll('[data-test-component="info-table-row"]').length,
|
||
3,
|
||
'renders all assignment info rows'
|
||
);
|
||
});
|
||
});
|