mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-12 08:06:59 +02:00
Backport UI: General settings Integration and Acceptance Tests. into ce/main (#9382)
* UI: General settings Integration and Acceptance Tests. (#9363) * General settings integration tests * Add page header integration tests * Add page header test for plugin settings as a tab too * More tests! * Acceptance tests! * Add more acceptnace tests * Add copywrite headers * Fix linting error * Fix accessibility errors * Remove unused vars * Put mock secret engine back into beforeHook * Add enterprise to key management test (#9392) --------- Co-authored-by: Kianna <30884335+kiannaquach@users.noreply.github.com>
This commit is contained in:
parent
8debe72733
commit
02dd079e91
@ -2,7 +2,13 @@
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
<Hds::Card::Container @level="mid" @hasBorder={{true}} class="has-padding-m has-top-bottom-margin" ...attributes>
|
||||
<Hds::Card::Container
|
||||
@level="mid"
|
||||
@hasBorder={{true}}
|
||||
class="has-padding-m has-top-bottom-margin"
|
||||
data-test-card-container="lease-duration"
|
||||
...attributes
|
||||
>
|
||||
<Hds::Text::Display @size="300" @tag="h2" class="has-bottom-margin-s hds-foreground-strong">Lease Duration</Hds::Text::Display>
|
||||
|
||||
<Hds::Layout::Flex @align="start" @gap="16" class="has-bottom-margin-m">
|
||||
|
||||
@ -2,7 +2,13 @@
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
<Hds::Card::Container @level="mid" @hasBorder={{true}} class="has-padding-m has-top-bottom-margin-12" ...attributes>
|
||||
<Hds::Card::Container
|
||||
@level="mid"
|
||||
@hasBorder={{true}}
|
||||
class="has-padding-m has-top-bottom-margin-12"
|
||||
data-test-card-container="metadata"
|
||||
...attributes
|
||||
>
|
||||
<Hds::Text::Display @size="300" @tag="h2" class="has-bottom-margin-s hds-foreground-strong">Metadata</Hds::Text::Display>
|
||||
|
||||
<div class="flex gap-16 is-flex-column has-top-padding-s">
|
||||
@ -13,6 +19,7 @@
|
||||
<Hds::Layout::Flex @gap="8">
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.secretsEngine.path}}
|
||||
aria-label="Secret engine path"
|
||||
autocomplete="off"
|
||||
disabled
|
||||
class="path-input-text"
|
||||
@ -31,6 +38,7 @@
|
||||
<Hds::Layout::Flex @gap="8">
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.secretsEngine.accessor}}
|
||||
aria-label="Secret engine accessor"
|
||||
autocomplete="off"
|
||||
disabled
|
||||
name="Accessor"
|
||||
|
||||
@ -2,7 +2,13 @@
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
<Hds::Card::Container @level="mid" @hasBorder={{true}} class="has-padding-m has-top-bottom-margin" ...attributes>
|
||||
<Hds::Card::Container
|
||||
@level="mid"
|
||||
@hasBorder={{true}}
|
||||
class="has-padding-m has-top-bottom-margin"
|
||||
data-test-card-container="security"
|
||||
...attributes
|
||||
>
|
||||
<Hds::Form::Toggle::Group as |G|>
|
||||
<G.Legend>
|
||||
<Hds::Text::Display
|
||||
@ -12,13 +18,13 @@
|
||||
>Security</Hds::Text::Display>
|
||||
</G.Legend>
|
||||
{{! TODO: Confirm with design to see if we want these two fields to be disabled }}
|
||||
<G.ToggleField name="local" checked={{@model.secretsEngine.local}} disabled as |F|>
|
||||
<F.Label>Local</F.Label>
|
||||
<F.HelperText>Secrets stay in one cluster and are not replicated.</F.HelperText>
|
||||
<G.ToggleField name="local" checked={{@model.secretsEngine.local}} disabled data-test-input="local" as |F|>
|
||||
<F.Label data-test-label="local">Local</F.Label>
|
||||
<F.HelperText data-test-helper-text="local">Secrets stay in one cluster and are not replicated.</F.HelperText>
|
||||
</G.ToggleField>
|
||||
<G.ToggleField name="seal-wrap" checked={{@model.secretsEngine.seal_wrap}} disabled as |F|>
|
||||
<F.Label>Seal wrap</F.Label>
|
||||
<F.HelperText>Wrap secrets with an additional encryption layer using a seal.</F.HelperText>
|
||||
<G.ToggleField name="seal-wrap" checked={{@model.secretsEngine.seal_wrap}} disabled data-test-input="seal_wrap" as |F|>
|
||||
<F.Label data-test-label="seal_wrap">Seal wrap</F.Label>
|
||||
<F.HelperText data-test-helper-text="seal_wrap">Wrap secrets with an additional encryption layer using a seal.</F.HelperText>
|
||||
</G.ToggleField>
|
||||
</Hds::Form::Toggle::Group>
|
||||
</Hds::Card::Container>
|
||||
@ -2,7 +2,13 @@
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
<Hds::Card::Container @level="mid" @hasBorder={{true}} class="has-padding-m has-top-bottom-margin" ...attributes>
|
||||
<Hds::Card::Container
|
||||
@level="mid"
|
||||
@hasBorder={{true}}
|
||||
class="has-padding-m has-top-bottom-margin"
|
||||
data-test-card-container="version"
|
||||
...attributes
|
||||
>
|
||||
<Hds::Text::Display @size="300" @tag="h2" class="has-bottom-margin-s hds-foreground-strong">Version</Hds::Text::Display>
|
||||
|
||||
<Hds::Layout::Grid @columnMinWidth="10%" @gap="12" {{style height="100%" grid-template-rows="min-content"}} as |LG|>
|
||||
@ -15,9 +21,13 @@
|
||||
<Hds::Text::Body
|
||||
@tag="p"
|
||||
class="hds-border-strong has-side-padding-8 border-radius-4 is-inline-block has-bottom-margin-s"
|
||||
data-test-engine-type
|
||||
>{{@model.secretsEngine.type}}</Hds::Text::Body>
|
||||
{{! TODO: Verify if we want to display the full version or chop down ie. v0.17.1 vs v0.17.1-0.230942309423094... }}
|
||||
<Hds::Text::Body @tag="p">{{@model.secretsEngine.running_plugin_version}}</Hds::Text::Body>
|
||||
<Hds::Text::Body
|
||||
@tag="p"
|
||||
data-test-engine-current-version
|
||||
>{{@model.secretsEngine.running_plugin_version}}</Hds::Text::Body>
|
||||
</LG.Item>
|
||||
</Hds::Layout::Grid>
|
||||
|
||||
@ -25,7 +35,7 @@
|
||||
<Hds::Separator />
|
||||
|
||||
<Hds::Layout::Flex @isInline="true">
|
||||
<Hds::Form::Select::Field name="plugin-version" as |F|>
|
||||
<Hds::Form::Select::Field name="plugin-version" data-test-versions-dropdown as |F|>
|
||||
<F.Label>Update version to:</F.Label>
|
||||
<F.Options>
|
||||
<option value="">Select version</option>
|
||||
|
||||
@ -26,14 +26,14 @@
|
||||
<div class="tabs-container box is-marginless is-fullwidth is-paddingless">
|
||||
<nav class="tabs" aria-label={{@model.secretsEngine.id}}>
|
||||
<ul>
|
||||
<li>
|
||||
<li data-test-tab="general-settings">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.configuration.general-settings" @model={{@model.secretsEngine.id}}>
|
||||
General settings
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{! If engine is not configurable, hide plugin settings link }}
|
||||
{{#if (get (engines-display-data @model.secretsEngine.type) "isConfigurable")}}
|
||||
<li>
|
||||
<li data-test-tab="plugin-settings">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.configuration.plugin-settings"
|
||||
@model={{@model.secretsEngine.id}}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<SecretEngine::PageHeader @model={{@model}} />
|
||||
|
||||
{{#if this.saveGeneralSettings.isRunning}}
|
||||
@ -46,11 +45,11 @@
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showUnsavedChangesModal}}
|
||||
<Hds::Modal id="unsavedChangesModal" @onClose={{this.closeUnsavedChangesModal}} as |M|>
|
||||
<M.Header>
|
||||
<Hds::Modal id="unsavedChangesModal" @onClose={{this.closeUnsavedChangesModal}} data-test-modal="unsaved-changes" as |M|>
|
||||
<M.Header data-test-modal-header="unsaved-changes">
|
||||
Unsaved changes
|
||||
</M.Header>
|
||||
<M.Body>
|
||||
<M.Body data-test-modal-body="unsaved-changes">
|
||||
<p class="hds-typography-body-300 hds-foreground-primary">You've made changes to the following
|
||||
<Hds::Text::Display>{{@model.secretsEngine.id}}</Hds::Text::Display>
|
||||
settings:</p>
|
||||
@ -64,8 +63,19 @@
|
||||
</M.Body>
|
||||
<M.Footer>
|
||||
<Hds::ButtonSet>
|
||||
<Hds::Button type="button" @text="Save changes" {{on "click" (perform this.saveGeneralSettings)}} />
|
||||
<Hds::Button type="button" @text="Discard changes" @color="secondary" {{on "click" this.discardChanges}} />
|
||||
<Hds::Button
|
||||
type="button"
|
||||
@text="Save changes"
|
||||
data-test-button="save"
|
||||
{{on "click" (perform this.saveGeneralSettings)}}
|
||||
/>
|
||||
<Hds::Button
|
||||
type="button"
|
||||
@text="Discard changes"
|
||||
@color="secondary"
|
||||
data-test-button="discard"
|
||||
{{on "click" this.discardChanges}}
|
||||
/>
|
||||
</Hds::ButtonSet>
|
||||
</M.Footer>
|
||||
</Hds::Modal>
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<Hds::Form::Field @layout="vertical" @isInvalid={{this.errorMessage}} as |F|>
|
||||
<F.Label>{{this.formField.label}}</F.Label>
|
||||
<F.HelperText>{{this.formField.helperText}}</F.HelperText>
|
||||
<Hds::Form::Field @layout="vertical" @isInvalid={{this.errorMessage}} data-test-ttl-picker-v2 as |F|>
|
||||
<F.Label data-test-form-field-label={{@ttlKey}}>{{this.formField.label}}</F.Label>
|
||||
<F.HelperText data-test-help-text={{@ttlKey}}>{{this.formField.helperText}}</F.HelperText>
|
||||
<F.Control>
|
||||
<Hds::SegmentedGroup as |SG|>
|
||||
<SG.TextInput
|
||||
@ -14,9 +14,18 @@
|
||||
@value={{this.time}}
|
||||
{{on "input" this.setTtlTime}}
|
||||
name="{{@ttlKey}}-time"
|
||||
aria-label={{concat this.formField.label "time"}}
|
||||
autocomplete="off"
|
||||
data-test-input={{@ttlKey}}
|
||||
/>
|
||||
<SG.Select @width="100px" name="{{@ttlKey}}-unit" {{on "input" this.setUnit}} as |S|>
|
||||
<SG.Select
|
||||
@width="100px"
|
||||
name="{{@ttlKey}}-unit"
|
||||
{{on "input" this.setUnit}}
|
||||
aria-label={{concat this.formField.label "unit"}}
|
||||
data-test-select={{@ttlKey}}
|
||||
as |S|
|
||||
>
|
||||
<S.Options>
|
||||
{{#each this.unitOptions as |unit|}}
|
||||
<option value={{unit.value}} selected={{eq unit.value this.selectedUnit}}>{{unit.label}}</option>
|
||||
@ -26,6 +35,6 @@
|
||||
</Hds::SegmentedGroup>
|
||||
</F.Control>
|
||||
{{#if this.errorMessage}}
|
||||
<F.Error>{{this.errorMessage}}</F.Error>
|
||||
<F.Error data-test-message-error>{{this.errorMessage}}</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::Field>
|
||||
@ -63,11 +63,16 @@
|
||||
{{! TODO: Hook dropdown actions to the appropriate routes & actions }}
|
||||
<Hds::Dropdown as |D|>
|
||||
<D.ToggleButton @text="Manage" @color="secondary" data-test-manage-dropdown />
|
||||
<D.Interactive @icon="settings" @route="vault.cluster.secrets.backend.configuration.index">Configure</D.Interactive>
|
||||
<D.Interactive
|
||||
@icon="settings"
|
||||
@route="vault.cluster.secrets.backend.configuration.index"
|
||||
data-test-manage-dropdown-item="Configure"
|
||||
>Configure</D.Interactive>
|
||||
<D.Interactive
|
||||
{{on "click" (fn (mut this.engineToDisable) this.backendModel)}}
|
||||
@color="critical"
|
||||
@icon="trash"
|
||||
data-test-manage-dropdown-item="Delete"
|
||||
>Delete</D.Interactive>
|
||||
</Hds::Dropdown>
|
||||
|
||||
|
||||
85
ui/tests/acceptance/secrets/backend/keymgmt/workflow-test.js
Normal file
85
ui/tests/acceptance/secrets/backend/keymgmt/workflow-test.js
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { settled, click, fillIn, visit, currentRouteName } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
|
||||
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
|
||||
import { login } from 'vault/tests/helpers/auth/auth-helpers';
|
||||
import { mountBackend } from 'vault/tests/helpers/components/mount-backend-form-helpers';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { SELECTORS } from 'vault/tests/helpers/secret-engine/general-settings-selectors';
|
||||
import { create } from 'ember-cli-page-object';
|
||||
import consoleClass from 'vault/tests/pages/components/console/ui-panel';
|
||||
|
||||
const consoleComponent = create(consoleClass);
|
||||
|
||||
module('Acceptance | Enterprise | keymgmt-configuration-workflow', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
return login();
|
||||
});
|
||||
|
||||
test('it should display keymgmt configuration and tune keymgmt in the general settings form', async function (assert) {
|
||||
await consoleComponent.runCommands([
|
||||
// delete any previous mount with same name
|
||||
'delete sys/mounts/keymgmt',
|
||||
]);
|
||||
const keymgmtType = 'keymgmt';
|
||||
await mountSecrets.visit();
|
||||
await settled();
|
||||
await mountBackend(keymgmtType, keymgmtType);
|
||||
await click(SELECTORS.manageDropdown);
|
||||
await click(SELECTORS.manageDropdownItem('Configure'));
|
||||
assert
|
||||
.dom(GENERAL.hdsPageHeaderTitle)
|
||||
.hasText(`${keymgmtType} configuration`, 'displays configuration title');
|
||||
assert.dom(GENERAL.tab('general-settings')).hasText(`General settings`);
|
||||
assert.dom(GENERAL.cardContainer('version')).exists('version card exists');
|
||||
assert.dom(SELECTORS.versionCard.engineType).hasText(keymgmtType, 'shows keymgmt engine type');
|
||||
assert.dom(GENERAL.cardContainer('metadata')).exists('metadata card exists');
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasValue(`${keymgmtType}/`, 'show path value');
|
||||
assert.dom(GENERAL.cardContainer('lease-duration')).exists('lease-duration card exists');
|
||||
assert.dom(GENERAL.cardContainer('security')).exists('security card exists');
|
||||
|
||||
// fill in values to tune
|
||||
await fillIn(GENERAL.inputByAttr('default_lease_ttl'), 10);
|
||||
await fillIn(GENERAL.selectByAttr('default_lease_ttl'), 'm');
|
||||
await fillIn(GENERAL.inputByAttr('max_lease_ttl'), 15);
|
||||
await fillIn(GENERAL.selectByAttr('max_lease_ttl'), 'd');
|
||||
await fillIn(GENERAL.textareaByAttr('description'), 'Some awesome description.');
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
// after submitting go to list and back to configuration
|
||||
await visit(`/vault/secrets/${keymgmtType}/list`);
|
||||
await visit(`/vault/secrets/${keymgmtType}/configuration`);
|
||||
|
||||
// confirm that submitted values were saved and prepopulated with those saved values
|
||||
assert
|
||||
.dom(GENERAL.textareaByAttr('description'))
|
||||
.hasValue('Some awesome description.', 'description was tuned');
|
||||
assert.dom(GENERAL.inputByAttr('default_lease_ttl')).hasValue('10', 'default ttl value was tuned');
|
||||
assert
|
||||
.dom(GENERAL.selectByAttr('default_lease_ttl'))
|
||||
.hasValue('m', 'default ttl value was tuned and shows correct unit');
|
||||
assert.dom(GENERAL.inputByAttr('max_lease_ttl')).hasValue('15', 'max ttl value was tuned');
|
||||
assert
|
||||
.dom(GENERAL.selectByAttr('max_lease_ttl'))
|
||||
.hasValue('d', 'max ttl value was tuned and shows correct unit');
|
||||
|
||||
// navigate back to keymgmt list view to delete the engine from the manage dropdown
|
||||
await visit(`/vault/secrets/${keymgmtType}/list`);
|
||||
await click(SELECTORS.manageDropdown);
|
||||
await click(SELECTORS.manageDropdownItem('Delete'));
|
||||
await click(GENERAL.confirmButton);
|
||||
assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.backends');
|
||||
await consoleComponent.runCommands([
|
||||
// cleanup after
|
||||
'delete sys/mounts/keymgmt',
|
||||
]);
|
||||
});
|
||||
});
|
||||
@ -13,6 +13,8 @@ export const GENERAL = {
|
||||
breadcrumbs: '[data-test-breadcrumbs]',
|
||||
headerContainer: 'header.page-header',
|
||||
title: '[data-test-page-title]',
|
||||
hdsPageHeaderTitle: '.hds-page-header__title',
|
||||
hdsPageHeaderDescription: '.hds-page-header__description',
|
||||
|
||||
/* ────── Tabs & Navigation ────── */
|
||||
tab: (name: string) => `[data-test-tab="${name}"]`,
|
||||
@ -73,6 +75,7 @@ export const GENERAL = {
|
||||
toggleInput: (attr: string) => `[data-test-toggle-input="${attr}"]`,
|
||||
textToggle: '[data-test-text-toggle]',
|
||||
filter: (name: string) => `[data-test-filter="${name}"]`,
|
||||
textareaByAttr: (attr: string) => `textarea[name="${attr}"]`,
|
||||
|
||||
/* ────── Code Blocks / Editor ────── */
|
||||
codemirror: `[data-test-component="code-mirror-modifier"]`,
|
||||
@ -159,6 +162,11 @@ export const GENERAL = {
|
||||
|
||||
/* ────── Modals & Flyouts ────── */
|
||||
flyout: '[data-test-flyout]',
|
||||
modal: {
|
||||
container: (title: string) => `[data-test-modal=${title}]`,
|
||||
header: (title: string) => `[data-test-modal-header=${title}]`,
|
||||
body: (title: string) => `[data-test-modal-body=${title}]`,
|
||||
},
|
||||
|
||||
/* ────── Misc ────── */
|
||||
icon: (name: string) => (name ? `[data-test-icon="${name}"]` : '[data-test-icon]'),
|
||||
|
||||
17
ui/tests/helpers/secret-engine/general-settings-selectors.ts
Normal file
17
ui/tests/helpers/secret-engine/general-settings-selectors.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export const SELECTORS = {
|
||||
manageDropdown: '[data-test-manage-dropdown]',
|
||||
manageDropdownItem: (name: string) => `[data-test-manage-dropdown-item="${name}"]`,
|
||||
label: (name: string) => `[data-test-label="${name}"]`,
|
||||
helperText: (name: string) => `[data-test-helper-text="${name}"]`,
|
||||
ttlPickerV2: '[data-test-ttl-picker-v2]',
|
||||
versionCard: {
|
||||
engineType: '[data-test-engine-type]',
|
||||
currentVersion: '[data-test-engine-current-version]',
|
||||
versionsDropdown: `[data-test-versions-dropdown]`,
|
||||
},
|
||||
};
|
||||
30
ui/tests/helpers/secret-engine/mocks.ts
Normal file
30
ui/tests/helpers/secret-engine/mocks.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export const keyMgmtMockModel = {
|
||||
secretsEngine: {
|
||||
accessor: 'keymgmt_accessor',
|
||||
config: {
|
||||
default_lease_ttl: 2073600,
|
||||
force_no_cache: false,
|
||||
listing_visibility: 'hidden',
|
||||
max_lease_ttl: 4320000,
|
||||
},
|
||||
description: 'hello',
|
||||
external_entropy_access: false,
|
||||
local: true,
|
||||
options: {},
|
||||
path: 'keymgmt/',
|
||||
plugin_version: '',
|
||||
running_plugin_version: 'v0.17.1+builtin',
|
||||
running_sha256: '',
|
||||
seal_wrap: false,
|
||||
type: 'keymgmt',
|
||||
uuid: '4ea92618-5b52-f89a-9cbe-b65dc7e65689',
|
||||
id: 'keymgmt',
|
||||
backendConfigurationLink: `vault.cluster.secrets.backend.configuration`,
|
||||
},
|
||||
versions: ['v0.17.1+builtin'],
|
||||
};
|
||||
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { SELECTORS } from 'vault/tests/helpers/secret-engine/general-settings-selectors';
|
||||
|
||||
module('Integration | Component | SecretEngine::Card::LeaseDuration', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows default and max ttl pickers', async function (assert) {
|
||||
assert.expect(5);
|
||||
await render(hbs`
|
||||
<SecretEngine::Card::LeaseDuration @model={{this.model}} />
|
||||
`);
|
||||
assert.dom(SELECTORS.ttlPickerV2).exists({ count: 2 });
|
||||
assert.dom(GENERAL.fieldLabelbyAttr('default_lease_ttl')).hasText('Time-to-live (TTL)');
|
||||
assert.dom(GENERAL.fieldLabelbyAttr('max_lease_ttl')).hasText('Maximum Time-to-live (TTL)');
|
||||
assert.dom(GENERAL.helpTextByAttr('default_lease_ttl')).hasText('Standard expiry deadline.');
|
||||
assert.dom(GENERAL.helpTextByAttr('max_lease_ttl')).hasText('Maximum possible extension for expiry.');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render, fillIn } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
|
||||
module('Integration | Component | SecretEngine::Card::Metadata', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows metadata card information', async function (assert) {
|
||||
assert.expect(4);
|
||||
await render(hbs`
|
||||
<SecretEngine::Card::Metadata @model={{this.model}} />
|
||||
`);
|
||||
assert.dom(`${GENERAL.cardContainer('metadata')} h2`).hasText('Metadata');
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasValue(this.model.secretsEngine.path);
|
||||
assert.dom(GENERAL.inputByAttr('accessor')).hasValue(this.model.secretsEngine.accessor);
|
||||
await fillIn(GENERAL.textareaByAttr('description'), 'Some awesome description');
|
||||
assert.dom(GENERAL.textareaByAttr('description')).hasValue('Some awesome description');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { SELECTORS } from 'vault/tests/helpers/secret-engine/general-settings-selectors';
|
||||
|
||||
module('Integration | Component | SecretEngine::Card::Security', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows security card information', async function (assert) {
|
||||
assert.expect(7);
|
||||
await render(hbs`
|
||||
<SecretEngine::Card::Security @model={{this.model}} />
|
||||
`);
|
||||
assert.dom(`${GENERAL.cardContainer('security')} h2`).hasText('Security');
|
||||
assert.dom(SELECTORS.label('local')).hasText('Local');
|
||||
assert.dom(SELECTORS.helperText('local')).hasText('Secrets stay in one cluster and are not replicated.');
|
||||
assert.dom(GENERAL.inputByAttr('local')).isChecked();
|
||||
assert.dom(SELECTORS.label('seal_wrap')).hasText('Seal wrap');
|
||||
assert
|
||||
.dom(SELECTORS.helperText('seal_wrap'))
|
||||
.hasText('Wrap secrets with an additional encryption layer using a seal.');
|
||||
assert.dom(GENERAL.inputByAttr('seal_wrap')).isNotChecked();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
import { SELECTORS } from 'vault/tests/helpers/secret-engine/general-settings-selectors';
|
||||
|
||||
module('Integration | Component | SecretEngine::Card::Version', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows version card information', async function (assert) {
|
||||
assert.expect(4);
|
||||
await render(hbs`
|
||||
<SecretEngine::Card::Version @model={{this.model}} />
|
||||
`);
|
||||
assert.dom(`${GENERAL.cardContainer('version')} h2`).hasText('Version');
|
||||
assert.dom(SELECTORS.engineType).hasAnyText(keyMgmtMockModel.secretsEngine.type);
|
||||
assert.dom(SELECTORS.currentVersion).hasAnyText(keyMgmtMockModel.secretsEngine.running_plugin_version);
|
||||
assert.dom(SELECTORS.versionCard.versionsDropdown).doesNotExist();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import engineDisplayData from 'vault/helpers/engines-display-data';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
|
||||
module('Integration | Component | SecretEngine::PageHeader', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows page header title, description, and general settings tab', async function (assert) {
|
||||
assert.expect(4);
|
||||
await render(hbs`
|
||||
<SecretEngine::PageHeader @model={{this.model}}/>
|
||||
`);
|
||||
assert.dom(GENERAL.tab('general-settings')).exists('contains general settings tab');
|
||||
assert.dom(GENERAL.tab('plugin-settings')).doesNotExist('does not contain plugin settings tab');
|
||||
assert
|
||||
.dom(GENERAL.hdsPageHeaderTitle)
|
||||
.hasText(`${this.model.secretsEngine.id} configuration`, 'displays page header title');
|
||||
assert
|
||||
.dom(GENERAL.hdsPageHeaderDescription)
|
||||
.hasText(
|
||||
engineDisplayData(this.model.secretsEngine.type).displayName,
|
||||
'displays page header description'
|
||||
);
|
||||
});
|
||||
|
||||
test('it shows page header title, description, and general and plugin settings tab for configurable secret engines', async function (assert) {
|
||||
assert.expect(4);
|
||||
this.model.secretsEngine = {
|
||||
type: 'aws',
|
||||
id: 'aws',
|
||||
config: {
|
||||
region: 'us-west-2',
|
||||
access_key: '123-key',
|
||||
iam_endpoint: 'iam-endpoint',
|
||||
sts_endpoint: 'sts-endpoint',
|
||||
max_retries: 1,
|
||||
},
|
||||
};
|
||||
|
||||
await render(hbs`
|
||||
<SecretEngine::PageHeader @model={{this.model}}/>
|
||||
`);
|
||||
assert.dom(GENERAL.tab('general-settings')).exists('contains general settings tab');
|
||||
assert.dom(GENERAL.tab('plugin-settings')).exists('contains plugin settings tab');
|
||||
assert
|
||||
.dom(GENERAL.hdsPageHeaderTitle)
|
||||
.hasText(`${this.model.secretsEngine.id} configuration`, 'displays page header title');
|
||||
assert
|
||||
.dom(GENERAL.hdsPageHeaderDescription)
|
||||
.hasText(
|
||||
engineDisplayData(this.model.secretsEngine.type).displayName,
|
||||
'displays page header description'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render, click, fillIn } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
|
||||
const keyManagementMockModel = {
|
||||
secretsEngine: {
|
||||
accessor: 'keymgmt_accessor',
|
||||
config: {
|
||||
default_lease_ttl: 2073600,
|
||||
force_no_cache: false,
|
||||
listing_visibility: 'hidden',
|
||||
max_lease_ttl: 4320000,
|
||||
},
|
||||
description: 'hello',
|
||||
external_entropy_access: false,
|
||||
local: true,
|
||||
options: {},
|
||||
path: 'keymgmt/',
|
||||
plugin_version: '',
|
||||
running_plugin_version: 'v0.17.1+builtin',
|
||||
running_sha256: '',
|
||||
seal_wrap: false,
|
||||
type: 'keymgmt',
|
||||
uuid: '4ea92618-5b52-f89a-9cbe-b65dc7e65689',
|
||||
id: 'keymgmt',
|
||||
backendConfigurationLink: `vault.cluster.secrets.backend.configuration`,
|
||||
},
|
||||
versions: ['v0.17.1+builtin'],
|
||||
};
|
||||
|
||||
module('Integration | Component | SecretEngine::Page::GeneralSettings', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyManagementMockModel;
|
||||
});
|
||||
|
||||
test('it shows general settings form', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
await render(hbs`
|
||||
<SecretEngine::Page::GeneralSettings @model={{this.model}} />
|
||||
`);
|
||||
assert.dom(GENERAL.cardContainer('lease-duration')).exists(`Lease duration card exists`);
|
||||
assert.dom(GENERAL.cardContainer('security')).exists(`Security card exists`);
|
||||
assert.dom(GENERAL.cardContainer('version')).exists(`Version card exists`);
|
||||
assert.dom(GENERAL.cardContainer('metadata')).exists(`Metadata card exists`);
|
||||
});
|
||||
|
||||
test('it shows unsaved changes modal', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
await render(hbs`
|
||||
<SecretEngine::Page::GeneralSettings @model={{this.model}} />
|
||||
`);
|
||||
await fillIn(GENERAL.textareaByAttr('description'), 'Some awesome description');
|
||||
await click(GENERAL.cancelButton);
|
||||
|
||||
assert.dom(GENERAL.modal.container('unsaved-changes')).exists('Unsaved changes exists');
|
||||
assert.dom(GENERAL.modal.header('unsaved-changes')).hasText('Unsaved changes');
|
||||
assert
|
||||
.dom(GENERAL.modal.body('unsaved-changes'))
|
||||
.hasText(
|
||||
`You've made changes to the following ${this.model.secretsEngine.id} settings: Description Would you like to apply them?`
|
||||
);
|
||||
});
|
||||
|
||||
test('it does not show unsaved changes modal when there are no unsaved changes', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
await render(hbs`
|
||||
<SecretEngine::Page::GeneralSettings @model={{this.model}} />
|
||||
`);
|
||||
await click(GENERAL.cancelButton);
|
||||
assert.dom(GENERAL.modal.container('unsaved-changes')).doesNotExist('Unsaved changes does not show');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render, fillIn } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { keyMgmtMockModel } from 'vault/tests/helpers/secret-engine/mocks';
|
||||
|
||||
module('Integration | Component | SecretEngine::TtlPickerV2', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = keyMgmtMockModel;
|
||||
});
|
||||
|
||||
test('it shows default ttl picker', async function (assert) {
|
||||
assert.expect(4);
|
||||
this.ttlKey = 'default_lease_ttl';
|
||||
await render(hbs`
|
||||
<SecretEngine::TtlPickerV2 @model={{this.model}} @ttlKey={{this.ttlKey}} />
|
||||
`);
|
||||
assert.dom(GENERAL.fieldLabelbyAttr(this.ttlKey)).hasText('Time-to-live (TTL)');
|
||||
assert.dom(GENERAL.helpTextByAttr(this.ttlKey)).hasText('Standard expiry deadline.');
|
||||
await fillIn(GENERAL.inputByAttr(this.ttlKey), 5);
|
||||
await fillIn(GENERAL.selectByAttr(this.ttlKey), 'm');
|
||||
assert.dom(GENERAL.inputByAttr(this.ttlKey)).hasValue('5');
|
||||
assert.dom(GENERAL.selectByAttr(this.ttlKey)).hasValue('m');
|
||||
});
|
||||
|
||||
test('it shows max ttl picker', async function (assert) {
|
||||
assert.expect(4);
|
||||
this.ttlKey = 'max_lease_duration';
|
||||
await render(hbs`
|
||||
<SecretEngine::TtlPickerV2 @model={{this.model}} @ttlKey={{this.ttlKey}} />
|
||||
`);
|
||||
assert.dom(GENERAL.fieldLabelbyAttr(this.ttlKey)).hasText('Maximum Time-to-live (TTL)');
|
||||
assert.dom(GENERAL.helpTextByAttr(this.ttlKey)).hasText('Maximum possible extension for expiry.');
|
||||
await fillIn(GENERAL.inputByAttr(this.ttlKey), 10);
|
||||
await fillIn(GENERAL.selectByAttr(this.ttlKey), 'm');
|
||||
assert.dom(GENERAL.inputByAttr(this.ttlKey)).hasValue('10');
|
||||
assert.dom(GENERAL.selectByAttr(this.ttlKey)).hasValue('m');
|
||||
});
|
||||
|
||||
test('it shows an error message if ttl picker time is not a number value', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.ttlKey = 'max_lease_duration';
|
||||
await render(hbs`
|
||||
<SecretEngine::TtlPickerV2 @model={{this.model}} @ttlKey={{this.ttlKey}} />
|
||||
`);
|
||||
await fillIn(GENERAL.inputByAttr(this.ttlKey), 'some text');
|
||||
await fillIn(GENERAL.selectByAttr(this.ttlKey), 'm');
|
||||
assert.dom(GENERAL.messageError).exists();
|
||||
assert.dom(GENERAL.messageError).hasText('Only use numbers for this setting.');
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user