open-vault/ui/tests/acceptance/oidc-config/clients-assignments-test.js
claire bontempo fcf6467cbf
UI: OIDC config cleanup (#17105)
* 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
2022-09-13 09:06:19 -07:00

350 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 Vaults 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'
);
});
});