Skip to content

Commit

Permalink
MFA Login Enforcement Component Tests (hashicorp#15539)
Browse files Browse the repository at this point in the history
* adds tests for mfa-login-enforcement-header component

* adds tests for mfa-login-enforcement-form component
  • Loading branch information
zofskeez committed May 20, 2022
1 parent e248ddc commit cac3f67
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 26 deletions.
14 changes: 12 additions & 2 deletions ui/app/components/mfa-login-enforcement-header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

/**
* @module MfaLoginEnforcementHeader
Expand All @@ -25,7 +26,7 @@ export default class MfaLoginEnforcementHeaderComponent extends Component {

constructor() {
super(...arguments);
if (!this.args.heading) {
if (this.args.isInline) {
this.fetchEnforcements();
}
}
Expand All @@ -34,9 +35,18 @@ export default class MfaLoginEnforcementHeaderComponent extends Component {

async fetchEnforcements() {
try {
this.enforcements = (await this.store.query('mfa-login-enforcement', {})).toArray();
// cache initial values for lookup in select handler
this._enforcements = (await this.store.query('mfa-login-enforcement', {})).toArray();
this.enforcements = [...this._enforcements];
} catch (error) {
this.enforcements = [];
}
}

@action
onEnforcementSelect([name]) {
// search select returns array of strings, in this case enforcement name
// lookup model and pass to callback
this.args.onEnforcementSelect(this._enforcements.findBy('name', name));
}
}
42 changes: 36 additions & 6 deletions ui/app/templates/components/mfa-login-enforcement-form.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
for="name"
@label="Name"
@subText="The name for this enforcement. Giving it a name means that you can refer to it again later. This name will not be editable later."
data-test-mlef-label="name"
/>
<input
data-test-input="name"
autocomplete="off"
spellcheck="false"
value={{@model.name}}
disabled={{not @model.isNew}}
class="input field"
data-test-mlef-input="name"
{{on "input" (pipe (pick "target.value") (fn (mut @model.name)))}}
/>
{{#if this.errors.name.errors}}
Expand All @@ -19,7 +20,12 @@

{{#unless @isInline}}
<div class="field">
<FormFieldLabel for="methods" @label="MFA methods" @subText="The MFA method(s) that this enforcement will apply to." />
<FormFieldLabel
for="methods"
@label="MFA methods"
@subText="The MFA method(s) that this enforcement will apply to."
data-test-mlef-label="methods"
/>
{{! component only computes inputValue on init -- ensure Ember Data hasMany promise has resolved }}
{{#if @model.mfa_methods.isFulfilled}}
<SearchSelect
Expand All @@ -29,6 +35,7 @@
@disallowNewItems={{true}}
@models={{array "mfa-method"}}
@onChange={{this.onMethodChange}}
data-test-mlef-search="methods"
/>
{{/if}}
{{#if this.errors.mfa_methods.errors}}
Expand All @@ -42,9 +49,10 @@
for="targets"
@label="Targets"
@subText="The list of authentication types, authentication mounts, groups, and/or entities that will require this MFA configuration."
data-test-mlef-label="targets"
/>
{{#each this.targets as |target|}}
<div class="is-flex-center has-border-top-light">
<div class="is-flex-center has-border-top-light" data-test-mlef-target={{target.label}}>
<InfoTableRow @label={{target.label}} class="is-flex-1 has-no-shadow">
{{#if target.value.id}}
{{target.value.name}}
Expand All @@ -53,7 +61,12 @@
{{target.value}}
{{/if}}
</InfoTableRow>
<button type="button" class="button" {{on "click" (fn this.removeTarget target)}}>
<button
type="button"
class="button"
data-test-mlef-remove-target={{target.label}}
{{on "click" (fn this.removeTarget target)}}
>
<Icon @name="trash" />
</button>
</div>
Expand All @@ -65,10 +78,17 @@
@valueAttribute="type"
@selectedValue={{this.selectedTargetType}}
@onChange={{this.onTargetSelect}}
data-test-mlef-select="target-type"
/>
<div class="has-left-margin-s is-flex-1">
{{#if (eq this.selectedTargetType "accessor")}}
<MountAccessorSelect @showAccessor={{true}} @noDefault={{true}} @onChange={{this.setTargetValue}} />
<MountAccessorSelect
@value={{this.selectedTargetValue}}
@showAccessor={{true}}
@noDefault={{true}}
@onChange={{this.setTargetValue}}
data-test-mlef-select="accessor"
/>
{{else if (eq this.selectedTargetType "method")}}
<Select
@options={{this.authMethods}}
Expand All @@ -78,6 +98,7 @@
@noDefault={{true}}
@selectedValue={{this.selectedTargetValue}}
@onChange={{this.setTargetValue}}
data-test-mlef-select="auth-method"
/>
{{else}}
<SearchSelect
Expand All @@ -88,13 +109,15 @@
@shouldRenderName={{true}}
@selectLimit={{1}}
@onChange={{this.setTargetValue}}
data-test-mlef-search={{this.selectedTargetType}}
/>
{{/if}}
</div>
<button
type="button"
class="button has-left-margin-s"
disabled={{not this.selectedTargetValue}}
data-test-mlef-add-target
{{on "click" this.addTarget}}
>
Add
Expand All @@ -111,11 +134,18 @@
type="button"
class="button is-primary {{if this.save.isRunning 'is-loading'}}"
disabled={{this.save.isRunning}}
data-test-mlef-save
{{on "click" (perform this.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}}
data-test-mlef-cancel
{{on "click" this.cancel}}
>
Cancel
</button>
</div>
Expand Down
11 changes: 7 additions & 4 deletions ui/app/templates/components/mfa-login-enforcement-header.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{#if @isInline}}
<h3 class="title is-5">Enforcement</h3>
<h3 class="title is-5" data-test-mleh-title>Enforcement</h3>
{{else}}
<PageHeader as |p|>
<p.top>
Expand All @@ -15,15 +15,15 @@
</nav>
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<h1 class="title is-3" data-test-mleh-title>
<Icon @name="lock" @size="24" />
{{@heading}}
</h1>
</p.levelLeft>
</PageHeader>
{{/if}}
<div class="has-border-top-light">
<p class="has-top-margin-m">
<p class="has-top-margin-m" data-test-mleh-description>
{{#if @isInline}}
An enforcement includes the authentication types, authentication methods, groups, and entities that will require this
MFA method. This is optional and can be added later.
Expand All @@ -43,6 +43,7 @@
@value="new"
@groupValue={{@radioCardGroupValue}}
@onChange={{@onRadioCardSelect}}
data-test-mleh-radio="new"
/>
<RadioCard
@title="Use existing"
Expand All @@ -52,6 +53,7 @@
@groupValue={{@radioCardGroupValue}}
@disabled={{not this.enforcements.length}}
@onChange={{@onRadioCardSelect}}
data-test-mleh-radio="existing"
/>
<RadioCard
@title="Skip this step"
Expand All @@ -60,6 +62,7 @@
@value="skip"
@groupValue={{@radioCardGroupValue}}
@onChange={{@onRadioCardSelect}}
data-test-mleh-radio="skip"
/>
</div>
{{#if (eq @radioCardGroupValue "existing")}}
Expand All @@ -71,7 +74,7 @@
@options={{this.enforcements}}
@shouldRenderName={{true}}
@selectLimit={{1}}
@onChange={{@onEnforcementSelect}}
@onChange={{this.onEnforcementSelect}}
/>
{{/if}}
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<MfaLoginEnforcementHeader @heading="New enforcement" />
<MfaLoginEnforcementForm
@model={{this.model}}
@hasActions={{true}}
@onClose={{transition-to "vault.cluster.access.mfa.enforcements"}}
@onSave={{transition-to "vault.cluster.access.mfa.enforcements.enforcement" this.model.name}}
class="has-top-margin-l"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<MfaLoginEnforcementHeader @heading="Update enforcement" />
<MfaLoginEnforcementForm
@model={{this.model}}
@hasActions={{true}}
@onSave={{transition-to "vault.cluster.access.mfa.enforcements.enforcement" this.model.name}}
@onClose={{transition-to "vault.cluster.access.mfa.enforcements.enforcement" this.model.name}}
class="has-top-margin-l"
Expand Down
Loading

0 comments on commit cac3f67

Please sign in to comment.