Skip to content

Commit

Permalink
UI/vault 9268/pki component tests (#17609)
Browse files Browse the repository at this point in the history
* wip

* work in progress

* pki-role-form-test

* clean up

* radio-select-ttl-or-string test

* clean up

* add yielded check

* 12 to 13

* add pki-key-usage test

* remove meep

* key-params test

* clean up

* clean up

* pr comments
  • Loading branch information
Monkeychip committed Oct 25, 2022
1 parent de848b0 commit bfde310
Show file tree
Hide file tree
Showing 13 changed files with 448 additions and 12 deletions.
3 changes: 1 addition & 2 deletions ui/app/models/pki/pki-role-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ export default class PkiRoleEngineModel extends Model {
@attr('string', {
label: 'Issuer reference',
defaultValue: 'default',
subText:
'Specifies the issuer that will be used to create certificates with this role. To find this, run [command]. By default, we will use the mounts default issuer.',
subText: `Specifies the issuer that will be used to create certificates with this role. To find this, run read -field=default pki_int/config/issuers in the console. By default, we will use the mounts default issuer.`,
})
issuerRef;

Expand Down
5 changes: 3 additions & 2 deletions ui/lib/core/addon/components/radio-select-ttl-or-string.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@value="ttl"
@onChange={{this.onRadioButtonChange}}
@groupValue={{this.groupValue}}
data-test-radio-button="ttl"
/>
<label class="has-left-margin-xs">
<TtlPicker2
Expand All @@ -26,6 +27,7 @@
@value="specificDate"
@onChange={{this.onRadioButtonChange}}
@groupValue={{this.groupValue}}
data-test-radio-button="not_after"
/>
<label class="has-left-margin-xs">
<span class="ttl-picker-label is-large">Specific date</span><br />
Expand All @@ -34,14 +36,13 @@
</p>
{{#if (eq this.groupValue "specificDate")}}
<input
data-test-input="not_after"
id="not_after"
autocomplete="off"
spellcheck="false"
value={{this.notAfter}}
{{on "input" this.setAndBroadcastInput}}
class="input"
maxLength="21"
data-test-input="not_after"
/>
{{/if}}
</label>
Expand Down
11 changes: 8 additions & 3 deletions ui/lib/core/addon/components/radio-select-ttl-or-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,21 @@ export default class RadioSelectTtlOrString extends Component {
// Clear the previous selection if they have clicked the other radio button.
if (selection === 'specificDate') {
this.args.model.set('ttl', '');
this.ttlTime = ''; //clear out the form field
this.ttlTime = '';
}
if (selection === 'tll') {
if (selection === 'ttl') {
this.args.model.set('notAfter', '');
this.notAfter = ''; //clear out the form field
this.notAfter = '';
this.args.model.set('ttl', this.ttlTime);
}
}

@action setAndBroadcastTtl(value) {
let valueToSet = value.enabled === true ? `${value.seconds}s` : 0;
if (this.groupValue === 'specificDate') {
// do not save ttl on the model until the ttl radio button is selected
return;
}
this.args.model.set('ttl', `${valueToSet}`);
}

Expand Down
2 changes: 1 addition & 1 deletion ui/lib/core/addon/helpers/is-active-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default Helper.extend({
const currentRoute = router.get('currentRouteName');
let currentURL = router.get('currentURL');
// if we have any query params we want to discard them
currentURL = currentURL.split('?')[0];
currentURL = currentURL?.split('?')[0];
const comparator = isExact ? exact : startsWith;
if (!currentRoute) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/pki/addon/components/pki-key-parameters.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
data-test-input={{attr.name}}
>
{{#each (path-or-array attr.options.possibleValues @model) as |val|}}
<option selected={{eq (get @model this.valuePath) (or val.value val)}} value={{or val.value val}}>
<option selected={{eq (get @model this.valuePath) (or val.value val)}} value={{val.value}}>
{{or val.displayName val}}
</option>
{{/each}}
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/pki/addon/components/pki-key-usage.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
data-test-toggle-group={{@group}}
/>
{{#if (get @model prop)}}
<div class="box is-tall is-marginless">
<div class="box is-tall is-marginless" data-test-surrounding-div={{@group}}>
<FormFieldLabel
for="keyUsageLabel"
@label="Key usage"
Expand Down
2 changes: 2 additions & 0 deletions ui/lib/pki/addon/components/pki-key-usage.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export default class PkiKeyUsage extends Component {
this.extKeyUsageFields = {};
Object.assign(this.keyUsageFields, KEY_USAGE_FIELDS);
Object.assign(this.extKeyUsageFields, EXT_KEY_USAGE_FIELDS);
// set default of key_usage to the three params that are true by default.
this.args.model.set('keyUsage', ['DigitalSignature', 'KeyAgreement', 'KeyEncipherment']);
}

@action onStringListChange(value) {
Expand Down
15 changes: 13 additions & 2 deletions ui/lib/pki/addon/components/pki-role-form.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,21 @@
{{/each}}
</div>
<div class="has-top-padding-s">
<button type="submit" class="button is-primary {{if this.save.isRunning 'is-loading'}}" disabled={{this.save.isRunning}}>
<button
type="submit"
class="button is-primary {{if this.save.isRunning 'is-loading'}}"
disabled={{this.save.isRunning}}
data-test-pki-role-save
>
{{if @model.isNew "Create" "Update"}}
</button>
<button type="button" class="button has-left-margin-s" disabled={{this.save.isRunning}} {{on "click" this.cancel}}>
<button
type="button"
class="button has-left-margin-s"
disabled={{this.save.isRunning}}
{{on "click" this.cancel}}
data-test-pki-role-cancel
>
Cancel
</button>
{{#if this.modelValidations.targets.errors}}
Expand Down
30 changes: 30 additions & 0 deletions ui/tests/helpers/pki-engine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const PKI_BASE_URL = `/vault/cluster/secrets/backend/pki/roles`;

export const SELECTORS = {
// Pki role
roleName: '[data-test-input="name"]',
issuerRef: '[data-test-input="issuerRef"]',
customTtl: '[data-test-field="customTtl"]',
backdateValidity: '[data-test-ttl-value="Backdate validity"]',
maxTtl: '[data-test-toggle-label="Max TTL"]',
generateLease: '[data-test-field="generateLease"]',
noStore: '[data-test-field="noStore"]',
addBasicConstraints: '[data-test-input="addBasicConstraints"]',
domainHandling: '[data-test-toggle-group="Domain handling"]',
keyParams: '[data-test-toggle-group="Key parameters"]',
keyType: '[data-test-input="keyType"]',
keyBits: '[data-test-input="keyBits"]',
signatureBits: '[data-test-input="signatureBits"]',
keyUsage: '[data-test-toggle-group="Key usage"]',
extKeyUsageOids: '[data-test-input="extKeyUsageOids"]',
digitalSignature: '[data-test-input="DigitalSignature"]',
keyAgreement: '[data-test-input="KeyAgreement"]',
keyEncipherment: '[data-test-input="KeyEncipherment"]',
any: '[data-test-input="Any"]',
serverAuth: '[data-test-input="ServerAuth"]',
policyIdentifiers: '[data-test-toggle-group="Policy identifiers"]',
san: '[data-test-toggle-group="Subject Alternative Name (SAN) Options"]',
additionalSubjectFields: '[data-test-toggle-group="Additional subject fields"]',
roleCreateButton: '[data-test-pki-role-save]',
roleCancelButton: '[data-test-pki-role-cancel]',
};
101 changes: 101 additions & 0 deletions ui/tests/integration/components/pki/pki-key-parameters-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, fillIn } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { setupEngine } from 'ember-engines/test-support';
import { SELECTORS } from 'vault/tests/helpers/pki-engine';

module('Integration | Component | pki-key-parameters', function (hooks) {
setupRenderingTest(hooks);
setupEngine(hooks, 'pki');

hooks.beforeEach(function () {
this.store = this.owner.lookup('service:store');
this.model = this.store.createRecord('pki/pki-role-engine');
this.model.backend = 'pki';
});

test('it should render the component and display the correct defaults', async function (assert) {
assert.expect(3);
await render(
hbs`
<div class="has-top-margin-xxl">
<PkiKeyParameters
@model={{this.model}}
@group="Key parameters"
/>
</div>
`,
{ owner: this.engine }
);
await click(SELECTORS.keyParams);
assert.dom(SELECTORS.keyType).hasValue('rsa');
assert.dom(SELECTORS.keyBits).hasValue('2048');
assert.dom(SELECTORS.signatureBits).hasValue('0');
});

test('it should set the model properties of key_type and key_bits when key_type changes', async function (assert) {
assert.expect(11);
await render(
hbs`
<div class="has-top-margin-xxl">
<PkiKeyParameters
@model={{this.model}}
@group="Key parameters"
/>
</div>
`,
{ owner: this.engine }
);
assert.strictEqual(this.model.keyType, 'rsa', 'sets the default value for key_type on the model.');
assert.strictEqual(this.model.keyBits, 2048, 'sets the default value for key_bits on the model.');
assert.strictEqual(
this.model.signatureBits,
0,
'sets the default value for signature_bits on the model.'
);
await click(SELECTORS.keyParams);
await fillIn(SELECTORS.keyType, 'ec');
assert.strictEqual(this.model.keyType, 'ec', 'sets the new selected value for key_type on the model.');
assert.strictEqual(
this.model.keyBits,
256,
'sets the new selected value for key_bits on the model based on the selection of key_type.'
);

await fillIn(SELECTORS.keyType, 'ed25519');
assert.strictEqual(
this.model.keyType,
'ed25519',
'sets the new selected value for key_type on the model.'
);
assert.strictEqual(
this.model.keyBits,
0,
'sets the new selected value for key_bits on the model based on the selection of key_type.'
);

await fillIn(SELECTORS.keyType, 'ec');
await fillIn(SELECTORS.keyBits, 384);
assert.strictEqual(this.model.keyType, 'ec', 'sets the new selected value for key_type on the model.');
assert.strictEqual(
this.model.keyBits,
384,
'sets the new selected value for key_bits on the model based on the selection of key_type.'
);

await fillIn(SELECTORS.signatureBits, '384');
assert.strictEqual(
this.model.signatureBits,
384,
'sets the new selected value for signature_bits on the model.'
);

await fillIn(SELECTORS.signatureBits, '0');
assert.strictEqual(
this.model.signatureBits,
0,
'sets the default value for signature_bits on the model.'
);
});
});
85 changes: 85 additions & 0 deletions ui/tests/integration/components/pki/pki-key-usage-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, findAll } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { setupEngine } from 'ember-engines/test-support';
import { SELECTORS } from 'vault/tests/helpers/pki-engine';

module('Integration | Component | pki-key-usage', function (hooks) {
setupRenderingTest(hooks);
setupEngine(hooks, 'pki');

hooks.beforeEach(function () {
this.store = this.owner.lookup('service:store');
this.model = this.store.createRecord('pki/pki-role-engine');
this.model.backend = 'pki';
});

test('it should render the component', async function (assert) {
assert.expect(7);
await render(
hbs`
<div class="has-top-margin-xxl">
<PkiKeyUsage
@model={{this.model}}
@group="Key usage"
/>
</div>
`,
{ owner: this.engine }
);
await click(SELECTORS.keyUsage);
assert.strictEqual(findAll('.b-checkbox').length, 19, 'it render 19 checkboxes');
assert.dom(SELECTORS.digitalSignature).isChecked('Digital Signature is true by default');
assert.dom(SELECTORS.keyAgreement).isChecked('Key Agreement is true by default');
assert.dom(SELECTORS.keyEncipherment).isChecked('Key Encipherment is true by default');
assert.dom(SELECTORS.any).isNotChecked('Any is false by default');
assert.dom(SELECTORS.extKeyUsageOids).exists('Extended Key usage oids renders');

// check is flexbox by checking the height of the box
let groupBoxHeight = document.querySelector('[data-test-surrounding-div="Key usage"]').clientHeight;
assert.strictEqual(
groupBoxHeight,
518,
'renders the correct height of the box element if the component is rending as a flexbox'
);
});

test('it should set the model properties of key_usage and ext_key_usage based on the checkbox selections', async function (assert) {
assert.expect(4);
await render(
hbs`
<div class="has-top-margin-xxl">
<PkiKeyUsage
@model={{this.model}}
@group="Key usage"
/>
</div>
`,
{ owner: this.engine }
);
// See PKI API docs https://developer.hashicorp.com/vault/api-docs/secret/pki#key_usage
assert.deepEqual(
this.model.keyUsage,
['DigitalSignature', 'KeyAgreement', 'KeyEncipherment'],
'sets the default values for key_usage on the model.'
);
assert.strictEqual(
this.model.extKeyUsage,
undefined,
'sets no default value set for ext_key_usage on load.'
);

await click(SELECTORS.keyUsage);
await click(SELECTORS.digitalSignature);
await click(SELECTORS.any);
await click(SELECTORS.serverAuth);

assert.deepEqual(
this.model.keyUsage,
['KeyAgreement', 'KeyEncipherment'],
'removes digitalSignature from the model when unchecked.'
);
assert.deepEqual(this.model.extKeyUsage, ['Any', 'ServerAuth'], 'adds new checkboxes to when checked');
});
});
Loading

0 comments on commit bfde310

Please sign in to comment.