mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
UI/pki key workflow tests (#18496)
* wip tests * fix links * Revert "wip tests" This reverts commit aed9bb9b8fffb1b4d52d9c27644033ff3d983fff. * wip tests * add policy generator * add workflow tests for key * change apostrophe -___- * fix workflow tests * add update to key form tests * fix capability check for read * finish tests * fix flash messages; * rename policy generator file, update tests
This commit is contained in:
@@ -51,7 +51,7 @@ export default class PkiKeyModel extends Model {
|
||||
* Default to show UI elements unless we know they can't access the given path
|
||||
*/
|
||||
|
||||
@lazyCapabilities(apiPath`${'backend'}/key/${'key_id'}`, 'backend', 'key_id') keyPath;
|
||||
@lazyCapabilities(apiPath`${'backend'}/key/${'keyId'}`, 'backend', 'keyId') keyPath;
|
||||
get canRead() {
|
||||
return this.keyPath.get('canRead') !== false;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @key.privateKey}}
|
||||
<DownloadButton class="toolbar-link" @filename={{this.model.name}} @data={{@key.privateKey}} @extension="pem">
|
||||
<DownloadButton
|
||||
class="toolbar-link"
|
||||
@filename="{{@key.backend}}-{{or @key.keyName 'private-key'}}"
|
||||
@data={{@key.privateKey}}
|
||||
@extension="pem"
|
||||
>
|
||||
Download private key
|
||||
<Chevron @isButton={{true}} />
|
||||
</DownloadButton>
|
||||
|
||||
@@ -22,7 +22,7 @@ export default class PkiKeyDetails extends Component<Args> {
|
||||
async deleteKey() {
|
||||
try {
|
||||
await this.args.key.destroyRecord();
|
||||
this.flashMessages.success('Key deleted successfully');
|
||||
this.flashMessages.success('Key deleted successfully.');
|
||||
this.router.transitionTo('vault.cluster.secrets.backend.pki.keys.index');
|
||||
} catch (error) {
|
||||
this.args.key.rollbackAttributes();
|
||||
|
||||
@@ -40,7 +40,9 @@ export default class PkiKeyForm extends Component {
|
||||
}
|
||||
if (!isValid && isNew) return;
|
||||
yield this.args.model.save({ adapterOptions: { import: false } });
|
||||
this.flashMessages.success(`Successfully ${isNew ? 'generated' : 'updated'} the key ${keyName}.`);
|
||||
this.flashMessages.success(
|
||||
`Successfully ${isNew ? 'generated' : 'updated'} key${keyName ? ` ${keyName}.` : '.'}`
|
||||
);
|
||||
this.args.onSave();
|
||||
} catch (error) {
|
||||
this.errorBanner = errorMessage(error);
|
||||
|
||||
@@ -35,7 +35,7 @@ export default class PkiKeyImport extends Component {
|
||||
try {
|
||||
const { keyName } = this.args.model;
|
||||
yield this.args.model.save({ adapterOptions: { import: true } });
|
||||
this.flashMessages.success(`Successfully imported key ${keyName}`);
|
||||
this.flashMessages.success(`Successfully imported key${keyName ? ` ${keyName}.` : '.'}`);
|
||||
this.args.onSave();
|
||||
} catch (error) {
|
||||
this.errorBanner = errorMessage(error);
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
</LinkedBlock>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn’t yet been configured with a certificate issuer.">
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn't yet been configured with a certificate issuer.">
|
||||
<LinkTo @route="configuration.create">
|
||||
Configure PKI
|
||||
</LinkTo>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/>
|
||||
{{else}}
|
||||
<Toolbar />
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn’t yet been configured with a certificate issuer.">
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn't yet been configured with a certificate issuer.">
|
||||
<LinkTo @route="configuration.create">
|
||||
Configure PKI
|
||||
</LinkTo>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{{#if this.model.hasConfig}}
|
||||
{{! TODO show overview items }}
|
||||
{{else}}
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn’t yet been configured with a certificate issuer.">
|
||||
<EmptyState @title="PKI not configured" @message="This PKI mount hasn't yet been configured with a certificate issuer.">
|
||||
<LinkTo @route="configuration.create" @model={{this.model.engine}}>
|
||||
Configure PKI
|
||||
</LinkTo>
|
||||
|
||||
@@ -5,8 +5,9 @@ import authPage from 'vault/tests/pages/auth';
|
||||
import logout from 'vault/tests/pages/logout';
|
||||
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
||||
import consoleClass from 'vault/tests/pages/components/console/ui-panel';
|
||||
import { click, currentURL, fillIn, visit } from '@ember/test-helpers';
|
||||
import { click, currentURL, fillIn, find, isSettled, visit } from '@ember/test-helpers';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/workflow';
|
||||
import { adminPolicy, readerPolicy, updatePolicy } from 'vault/tests/helpers/policy-generator/pki';
|
||||
|
||||
const consoleComponent = create(consoleClass);
|
||||
|
||||
@@ -50,15 +51,7 @@ module('Acceptance | pki workflow', function (hooks) {
|
||||
// Setup PKI engine
|
||||
const mountPath = `pki-workflow-${new Date().getTime()}`;
|
||||
await enablePage.enable('pki', mountPath);
|
||||
await runCommands([
|
||||
`write ${mountPath}/roles/some-role \
|
||||
issuer_ref="default" \
|
||||
allowed_domains="example.com" \
|
||||
allow_subdomains=true \
|
||||
max_ttl="720h"`,
|
||||
]);
|
||||
this.mountPath = mountPath;
|
||||
|
||||
await logout.visit();
|
||||
});
|
||||
|
||||
@@ -70,6 +63,41 @@ module('Acceptance | pki workflow', function (hooks) {
|
||||
await logout.visit();
|
||||
});
|
||||
|
||||
test('empty state messages are correct when PKI not configured', async function (assert) {
|
||||
assert.expect(10);
|
||||
const assertEmptyState = (assert, resource) => {
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/${resource}`);
|
||||
assert
|
||||
.dom(SELECTORS.emptyStateTitle)
|
||||
.hasText(
|
||||
'PKI not configured',
|
||||
`${resource} index renders correct empty state title when PKI not configured`
|
||||
);
|
||||
assert
|
||||
.dom(SELECTORS.emptyStateMessage)
|
||||
.hasText(
|
||||
`This PKI mount hasn't yet been configured with a certificate issuer.`,
|
||||
`${resource} index empty state message correct when PKI not configured`
|
||||
);
|
||||
};
|
||||
await authPage.login(this.pkiAdminToken);
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
|
||||
// TODO comment in when roles index empty state updated & update assert.expect() number
|
||||
// await click(SELECTORS.rolesTab);
|
||||
// assertEmptyState(assert, 'roles');
|
||||
|
||||
await click(SELECTORS.issuersTab);
|
||||
assertEmptyState(assert, 'issuers');
|
||||
|
||||
await click(SELECTORS.certsTab);
|
||||
assertEmptyState(assert, 'certificates');
|
||||
|
||||
await click(SELECTORS.keysTab);
|
||||
assertEmptyState(assert, 'keys');
|
||||
});
|
||||
|
||||
module('roles', function (hooks) {
|
||||
hooks.beforeEach(async function () {
|
||||
await authPage.login();
|
||||
@@ -81,33 +109,9 @@ module('Acceptance | pki workflow', function (hooks) {
|
||||
allow_subdomains=true \
|
||||
max_ttl="720h"`,
|
||||
]);
|
||||
const pki_admin_policy = `
|
||||
path "${this.mountPath}/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
},
|
||||
`;
|
||||
const pki_reader_policy = `
|
||||
path "${this.mountPath}/roles" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${this.mountPath}/roles/*" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
`;
|
||||
const pki_editor_policy = `
|
||||
path "${this.mountPath}/roles" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${this.mountPath}/roles/*" {
|
||||
capabilities = ["read", "update"]
|
||||
},
|
||||
path "${this.mountPath}/issue/*" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
path "${this.mountPath}/sign/*" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
`;
|
||||
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
|
||||
const pki_reader_policy = readerPolicy(this.mountPath, 'roles');
|
||||
const pki_editor_policy = updatePolicy(this.mountPath, 'roles');
|
||||
this.pkiRoleReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
|
||||
this.pkiRoleEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
|
||||
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
||||
@@ -231,6 +235,129 @@ module('Acceptance | pki workflow', function (hooks) {
|
||||
});
|
||||
});
|
||||
|
||||
module('keys', function (hooks) {
|
||||
hooks.beforeEach(async function () {
|
||||
await authPage.login();
|
||||
// base config pki so empty state doesn't show
|
||||
await runCommands([`write ${this.mountPath}/root/generate/internal common_name="Hashicorp Test"`]);
|
||||
const pki_admin_policy = adminPolicy(this.mountPath);
|
||||
const pki_reader_policy = readerPolicy(this.mountPath, 'keys', true);
|
||||
const pki_editor_policy = updatePolicy(this.mountPath, 'keys');
|
||||
this.pkiKeyReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
|
||||
this.pkiKeyEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
|
||||
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
||||
await logout.visit();
|
||||
});
|
||||
|
||||
test('shows correct items if user has all permissions', async function (assert) {
|
||||
await authPage.login(this.pkiAdminToken);
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
await click(SELECTORS.keysTab);
|
||||
// index page
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys`);
|
||||
assert
|
||||
.dom(SELECTORS.keyPages.importKey)
|
||||
.hasAttribute(
|
||||
'href',
|
||||
`/ui/vault/secrets/${this.mountPath}/pki/keys/import`,
|
||||
'import link renders with correct url'
|
||||
);
|
||||
let keyId = find(SELECTORS.keyPages.keyId).innerText;
|
||||
assert.dom('.linked-block').exists({ count: 1 }, 'One key is in list');
|
||||
await click('.linked-block');
|
||||
// details page
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`);
|
||||
assert.dom(SELECTORS.keyPages.downloadButton).doesNotExist('does not download button for private key');
|
||||
|
||||
// edit page
|
||||
await click(SELECTORS.keyPages.keyEditLink);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/edit`);
|
||||
await click(SELECTORS.keyForm.keyCancelButton);
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`,
|
||||
'navigates back to details on cancel'
|
||||
);
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/keys/${keyId}/edit`);
|
||||
await fillIn(SELECTORS.keyForm.keyNameInput, 'test-key');
|
||||
await click(SELECTORS.keyForm.keyCreateButton);
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`,
|
||||
'navigates to details after save'
|
||||
);
|
||||
await this.pauseTest;
|
||||
assert.dom(SELECTORS.keyPages.keyNameValue).hasText('test-key', 'updates key name');
|
||||
|
||||
// key generate and delete navigation
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/keys`);
|
||||
await click(SELECTORS.keyPages.generateKey);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/create`);
|
||||
await fillIn(SELECTORS.keyForm.typeInput, 'exported');
|
||||
await fillIn(SELECTORS.keyForm.keyTypeInput, 'rsa');
|
||||
await click(SELECTORS.keyForm.keyCreateButton);
|
||||
keyId = find(SELECTORS.keyPages.keyIdValue).innerText;
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`);
|
||||
|
||||
assert
|
||||
.dom(SELECTORS.alertBanner)
|
||||
.hasText(
|
||||
'Next steps This private key material will only be available once. Copy or download it now.',
|
||||
'renders banner to save private key'
|
||||
);
|
||||
assert.dom(SELECTORS.keyPages.downloadButton).exists('renders download button');
|
||||
await click(SELECTORS.keyPages.keyDeleteButton);
|
||||
await click(SELECTORS.keyPages.confirmDelete);
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${this.mountPath}/pki/keys`,
|
||||
'navigates back to key list view on delete'
|
||||
);
|
||||
});
|
||||
|
||||
test('it hide corrects actions for user with read policy', async function (assert) {
|
||||
await authPage.login(this.pkiKeyReader);
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
await click(SELECTORS.keysTab);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys`);
|
||||
await isSettled();
|
||||
assert.dom(SELECTORS.keyPages.importKey).doesNotExist();
|
||||
assert.dom(SELECTORS.keyPages.generateKey).doesNotExist();
|
||||
assert.dom('.linked-block').exists({ count: 1 }, 'One key is in list');
|
||||
const keyId = find(SELECTORS.keyPages.keyId).innerText;
|
||||
await click(SELECTORS.keyPages.popupMenuTrigger);
|
||||
assert.dom(SELECTORS.keyPages.popupMenuEdit).hasClass('disabled', 'popup menu edit link is disabled');
|
||||
await click(SELECTORS.keyPages.popupMenuDetails);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`);
|
||||
assert.dom(SELECTORS.keyPages.keyDeleteButton).doesNotExist('Delete key button is not shown');
|
||||
assert.dom(SELECTORS.keyPages.keyEditLink).doesNotExist('Edit key button does not render');
|
||||
});
|
||||
|
||||
test('it shows correct toolbar items for the user with update policy', async function (assert) {
|
||||
await authPage.login(this.pkiKeyEditor);
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||
await click(SELECTORS.keysTab);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys`);
|
||||
await isSettled();
|
||||
assert.dom(SELECTORS.keyPages.importKey).exists('import action exists');
|
||||
assert.dom(SELECTORS.keyPages.generateKey).exists('generate action exists');
|
||||
assert.dom('.linked-block').exists({ count: 1 }, 'One key is in list');
|
||||
const keyId = find(SELECTORS.keyPages.keyId).innerText;
|
||||
await click(SELECTORS.keyPages.popupMenuTrigger);
|
||||
assert
|
||||
.dom(SELECTORS.keyPages.popupMenuEdit)
|
||||
.doesNotHaveClass('disabled', 'popup menu edit link is not disabled');
|
||||
await click('.linked-block');
|
||||
assert.dom(SELECTORS.keyPages.keyDeleteButton).doesNotExist('Delete key button is not shown');
|
||||
await click(SELECTORS.keyPages.keyEditLink);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/edit`);
|
||||
assert.dom(SELECTORS.keyPages.title).hasText('Edit key');
|
||||
await click(SELECTORS.keyForm.keyCancelButton);
|
||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/keys/${keyId}/details`);
|
||||
});
|
||||
});
|
||||
|
||||
module('issuers', function (hooks) {
|
||||
hooks.beforeEach(async function () {
|
||||
await authPage.login();
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
export const SELECTORS = {
|
||||
importKey: '[data-test-pki-key-import]',
|
||||
generateKey: '[data-test-pki-key-generate]',
|
||||
keyId: '[data-test-key-id]',
|
||||
keyName: '[data-test-key-name]',
|
||||
popupMenuTrigger: '[data-test-popup-menu-trigger]',
|
||||
popupMenuDetails: '[data-test-key-menu-link="details"]',
|
||||
popupMenuEdit: '[data-test-key-menu-link="edit"]',
|
||||
};
|
||||
@@ -1,12 +1,20 @@
|
||||
export const SELECTORS = {
|
||||
breadcrumbContainer: '[data-test-breadcrumbs]',
|
||||
breadcrumbs: '[data-test-breadcrumbs] li',
|
||||
// key index
|
||||
importKey: '[data-test-pki-key-import]',
|
||||
generateKey: '[data-test-pki-key-generate]',
|
||||
keyId: '[data-test-key-id]',
|
||||
keyName: '[data-test-key-name]',
|
||||
popupMenuTrigger: '[data-test-popup-menu-trigger]',
|
||||
popupMenuDetails: '[data-test-key-menu-link="details"]',
|
||||
popupMenuEdit: '[data-test-key-menu-link="edit"]',
|
||||
// key details
|
||||
title: '[data-test-key-details-title]',
|
||||
keyIdValue: '[data-test-value-div="Key ID"]',
|
||||
keyNameValue: '[data-test-value-div="Key name"]',
|
||||
keyTypeValue: '[data-test-value-div="Key type"]',
|
||||
keyBitsValue: '[data-test-value-div="Key bits"]',
|
||||
keyDeleteButton: '[data-test-pki-key-delete] button',
|
||||
downloadButton: '[data-test-download-button]',
|
||||
keyEditLink: '[data-test-pki-key-edit]',
|
||||
confirmDelete: '[data-test-confirm-button]',
|
||||
};
|
||||
@@ -1,11 +1,16 @@
|
||||
import { SELECTORS as ROLEFORM } from './pki-role-form';
|
||||
import { SELECTORS as GENERATECERT } from './pki-role-generate';
|
||||
import { SELECTORS as KEYFORM } from './pki-key-form';
|
||||
import { SELECTORS as KEYPAGES } from './page/pki-keys';
|
||||
import { SELECTORS as ISSUERDETAILS } from './pki-issuer-details';
|
||||
|
||||
export const SELECTORS = {
|
||||
breadcrumbContainer: '[data-test-breadcrumbs]',
|
||||
breadcrumbs: '[data-test-breadcrumbs] li',
|
||||
pageTitle: '[data-test-pki-role-page-title]',
|
||||
alertBanner: '[data-test-alert-banner="alert"]',
|
||||
emptyStateTitle: '[data-test-empty-state-title]',
|
||||
emptyStateMessage: '[data-test-empty-state-message]',
|
||||
// TABS
|
||||
overviewTab: '[data-test-secret-list-tab="Overview"]',
|
||||
rolesTab: '[data-test-secret-list-tab="Roles"]',
|
||||
@@ -25,6 +30,14 @@ export const SELECTORS = {
|
||||
generateCertForm: {
|
||||
...GENERATECERT,
|
||||
},
|
||||
// KEYS
|
||||
keyForm: {
|
||||
...KEYFORM,
|
||||
},
|
||||
keyPages: {
|
||||
...KEYPAGES,
|
||||
},
|
||||
// ISSUERS
|
||||
issuerDetails: {
|
||||
title: '[data-test-pki-issuer-page-title]',
|
||||
...ISSUERDETAILS,
|
||||
|
||||
52
ui/tests/helpers/policy-generator/pki.js
Normal file
52
ui/tests/helpers/policy-generator/pki.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { singularize } from 'ember-inflector';
|
||||
|
||||
export const adminPolicy = (mountPath) => {
|
||||
return `
|
||||
path "${mountPath}/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
},
|
||||
`;
|
||||
};
|
||||
|
||||
// keys require singularized paths for GET
|
||||
export const readerPolicy = (mountPath, resource) => {
|
||||
return `
|
||||
path "${mountPath}/${resource}" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${mountPath}/${resource}/*" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${mountPath}/${singularize(resource)}" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${mountPath}/${singularize(resource)}/*" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
`;
|
||||
};
|
||||
export const updatePolicy = (mountPath, resource) => {
|
||||
return `
|
||||
path "${mountPath}/${resource}" {
|
||||
capabilities = ["read", "list"]
|
||||
},
|
||||
path "${mountPath}/${resource}/*" {
|
||||
capabilities = ["read", "update"]
|
||||
},
|
||||
path "${mountPath}/${singularize(resource)}/*" {
|
||||
capabilities = ["read", "update"]
|
||||
},
|
||||
path "${mountPath}/issue/*" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
path "${mountPath}/generate/*" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
path "${mountPath}/import" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
path "${mountPath}/sign/*" {
|
||||
capabilities = ["update"]
|
||||
},
|
||||
`;
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import { click, render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupEngine } from 'ember-engines/test-support';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-key-details';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-keys';
|
||||
|
||||
module('Integration | Component | pki key details page', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { click, render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupEngine } from 'ember-engines/test-support';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-key-list';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-keys';
|
||||
|
||||
module('Integration | Component | pki key list page', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
@@ -122,7 +122,7 @@ module('Integration | Component | pki key form', function (hooks) {
|
||||
});
|
||||
|
||||
test('it should rollback attributes or unload record on cancel', async function (assert) {
|
||||
assert.expect(2);
|
||||
assert.expect(5);
|
||||
this.onCancel = () => assert.ok(true, 'onCancel callback fires');
|
||||
await render(
|
||||
hbs`
|
||||
@@ -138,35 +138,32 @@ module('Integration | Component | pki key form', function (hooks) {
|
||||
await click(SELECTORS.keyCancelButton);
|
||||
assert.true(this.model.isDestroyed, 'new model is unloaded on cancel');
|
||||
|
||||
/* COMMENT IN WHEN EDIT IS COMPLETE
|
||||
this.store.pushPayload('pki/key', {
|
||||
modelName: this.modelName,
|
||||
keyName: 'test-key',
|
||||
this.store.pushPayload('pki/key', {
|
||||
modelName: 'pki/key',
|
||||
key_name: 'test-key',
|
||||
type: 'exported',
|
||||
keyId: 'some-key-id',
|
||||
keyType: 'rsa',
|
||||
keyBits: '2048',
|
||||
};);
|
||||
this.model = this.store.peekRecord('pki/key', this.data.keyId;
|
||||
key_id: 'some-key-id',
|
||||
key_type: 'rsa',
|
||||
key_bits: '2048',
|
||||
});
|
||||
this.model = this.store.peekRecord('pki/key', 'some-key-id');
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
await render(
|
||||
hbs`
|
||||
<PkiKeyForm
|
||||
@model={{this.model}}
|
||||
@onCancel={{this.onCancel}}
|
||||
@onSave={{this.onSave}}
|
||||
/>
|
||||
`,
|
||||
{ owner: this.engine }
|
||||
);
|
||||
{ owner: this.engine }
|
||||
);
|
||||
|
||||
await fillIn(SELECTORS.keyNameInput, 'new-name');
|
||||
await click(SELECTORS.keyCancelButton);
|
||||
assert.strictEqual(this.model.keyName, undefined, 'Model attributes rolled back on cancel');
|
||||
*/
|
||||
await fillIn(SELECTORS.keyNameInput, 'new-name');
|
||||
await click(SELECTORS.keyCancelButton);
|
||||
assert.strictEqual(this.model.keyName, 'test-key', 'Model name rolled back on cancel');
|
||||
await fillIn(SELECTORS.keyNameInput, 'new-name');
|
||||
await click(SELECTORS.keyCreateButton);
|
||||
assert.strictEqual(this.model.keyName, 'new-name', 'Model name correctly save on create');
|
||||
});
|
||||
|
||||
/* FUTURE TEST TODO:
|
||||
* it should update key
|
||||
*/
|
||||
});
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { click, render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupEngine } from 'ember-engines/test-support';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-key-list';
|
||||
|
||||
module('Integration | Component | pki key list page', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupEngine(hooks, 'pki');
|
||||
setupMirage(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
this.secretMountPath = this.owner.lookup('service:secret-mount-path');
|
||||
this.secretMountPath.currentPath = 'pki-test';
|
||||
this.store.pushPayload('pki/key', {
|
||||
modelName: 'pki/key',
|
||||
key_id: '724862ff-6438-bad0-b598-77a6c7f4e934',
|
||||
key_type: 'ec',
|
||||
key_name: 'test-key',
|
||||
});
|
||||
this.store.pushPayload('pki/key', {
|
||||
modelName: 'pki/key',
|
||||
key_id: '9fdddf12-9ce3-0268-6b34-dc1553b00175',
|
||||
key_type: 'rsa',
|
||||
key_name: 'another-key',
|
||||
});
|
||||
this.keyModels = this.store.peekAll('pki/key');
|
||||
});
|
||||
|
||||
test('it renders empty state when no keys exist', async function (assert) {
|
||||
assert.expect(3);
|
||||
this.keyModels = [];
|
||||
await render(
|
||||
hbs`
|
||||
<Page::PkiKeyList
|
||||
@keyModels={{this.keyModels}}
|
||||
@mountPoint="vault.cluster.secrets.backend.pki"
|
||||
@canImportKey={{true}}
|
||||
@canGenerateKey={{true}}
|
||||
/>,
|
||||
`,
|
||||
{ owner: this.engine }
|
||||
);
|
||||
assert
|
||||
.dom('[data-test-empty-state-title]')
|
||||
.hasText('No keys yet', 'renders empty state that no keys exist');
|
||||
assert.dom(SELECTORS.importKey).exists('renders toolbar with import action');
|
||||
assert.dom(SELECTORS.generateKey).exists('renders toolbar with generate action');
|
||||
});
|
||||
|
||||
test('it renders list of keys and actions when permission allowed', async function (assert) {
|
||||
assert.expect(6);
|
||||
await render(
|
||||
hbs`
|
||||
<Page::PkiKeyList
|
||||
@keyModels={{this.keyModels}}
|
||||
@mountPoint="vault.cluster.secrets.backend.pki"
|
||||
@canImportKey={{true}}
|
||||
@canGenerateKey={{true}}
|
||||
@canRead={{true}}
|
||||
@canEdit={{true}}
|
||||
/>,
|
||||
`,
|
||||
{ owner: this.engine }
|
||||
);
|
||||
assert
|
||||
.dom(SELECTORS.keyId)
|
||||
.hasText('724862ff-6438-bad0-b598-77a6c7f4e934', 'linked block renders key id');
|
||||
assert.dom(SELECTORS.keyName).hasText('test-key', 'linked block renders key name');
|
||||
assert.dom(SELECTORS.importKey).exists('renders import action');
|
||||
assert.dom(SELECTORS.generateKey).exists('renders generate action');
|
||||
await click(SELECTORS.popupMenuTrigger);
|
||||
assert.dom(SELECTORS.popupMenuDetails).exists('details link exists');
|
||||
assert.dom(SELECTORS.popupMenuEdit).exists('edit link exists');
|
||||
});
|
||||
|
||||
test('it hides or disables actions when permission denied', async function (assert) {
|
||||
assert.expect(4);
|
||||
await render(
|
||||
hbs`
|
||||
<Page::PkiKeyList
|
||||
@keyModels={{this.keyModels}}
|
||||
@mountPoint="vault.cluster.secrets.backend.pki"
|
||||
@canImportKey={{false}}
|
||||
@canGenerateKey={{false}}
|
||||
@canRead={{false}}
|
||||
@canEdit={{false}}
|
||||
/>,
|
||||
`,
|
||||
{ owner: this.engine }
|
||||
);
|
||||
assert.dom(SELECTORS.importKey).doesNotExist('renders import action');
|
||||
assert.dom(SELECTORS.generateKey).doesNotExist('renders generate action');
|
||||
await click(SELECTORS.popupMenuTrigger);
|
||||
assert.dom(SELECTORS.popupMenuDetails).hasClass('disabled', 'details link enabled');
|
||||
assert.dom(SELECTORS.popupMenuEdit).hasClass('disabled', 'edit link enabled');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user