diff --git a/changelog/18114.txt b/changelog/18114.txt
new file mode 100644
index 000000000000..3692b12c8a00
--- /dev/null
+++ b/changelog/18114.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+ui: update TTL picker for consistency
+```
diff --git a/ui/app/components/configure-aws-secret.js b/ui/app/components/configure-aws-secret.js
index b9d6e9b61bc0..9e1aee011ad9 100644
--- a/ui/app/components/configure-aws-secret.js
+++ b/ui/app/components/configure-aws-secret.js
@@ -6,9 +6,9 @@ import { action } from '@ember/object';
*
* @example
* ```js
- *
+
+
\ No newline at end of file
diff --git a/ui/app/components/wrap-ttl.js b/ui/app/components/wrap-ttl.js
index 19b5afb74aa0..8f40b688679a 100644
--- a/ui/app/components/wrap-ttl.js
+++ b/ui/app/components/wrap-ttl.js
@@ -1,49 +1,26 @@
import { assert } from '@ember/debug';
-import Component from '@ember/component';
-import { set, computed } from '@ember/object';
-import hbs from 'htmlbars-inline-precompile';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
+import { tracked } from '@glimmer/tracking';
-export default Component.extend({
- // passed from outside
- onChange: null,
- wrapResponse: true,
+export default class WrapTtlComponent extends Component {
+ @tracked
+ wrapResponse = true;
- ttl: '30m',
+ constructor() {
+ super(...arguments);
+ assert('`onChange` handler is a required attr in `' + this.toString() + '`.', this.args.onChange);
+ }
- wrapTTL: computed('wrapResponse', 'ttl', function () {
+ get wrapTTL() {
const { wrapResponse, ttl } = this;
return wrapResponse ? ttl : null;
- }),
+ }
- didRender() {
- this._super(...arguments);
- this.onChange(this.wrapTTL);
- },
-
- init() {
- this._super(...arguments);
- assert('`onChange` handler is a required attr in `' + this.toString() + '`.', this.onChange);
- },
-
- layout: hbs`
-
- {{ttl-picker2
- data-test-wrap-ttl-picker=true
- label='Wrap response'
- helperTextDisabled='Will not wrap response'
- helperTextEnabled='Will wrap response with a lease of'
- enableTTL=wrapResponse
- initialValue=ttl
- onChange=(action 'changedValue')
- }}
-
- `,
-
- actions: {
- changedValue(ttlObj) {
- set(this, 'wrapResponse', ttlObj.enabled);
- set(this, 'ttl', `${ttlObj.seconds}s`);
- this.onChange(this.wrapTTL);
- },
- },
-});
+ @action
+ changedValue(ttlObj) {
+ this.wrapResponse = ttlObj.enabled;
+ this.ttl = ttlObj.goSafeTimeString;
+ this.args.onChange(this.wrapTTL);
+ }
+}
diff --git a/ui/app/styles/app.scss b/ui/app/styles/app.scss
index 476acbdfe3a7..765038eaa9ed 100644
--- a/ui/app/styles/app.scss
+++ b/ui/app/styles/app.scss
@@ -13,3 +13,13 @@
// Font comes from npm package: https://www.npmjs.com/package/text-security
// We took the font we wanted and moved it into the ui/fonts folder
@include font-face('text-security-square');
+
+.sr-only {
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ overflow: hidden;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+}
diff --git a/ui/app/styles/components/ttl-picker2.scss b/ui/app/styles/components/ttl-picker.scss
similarity index 100%
rename from ui/app/styles/components/ttl-picker2.scss
rename to ui/app/styles/components/ttl-picker.scss
diff --git a/ui/app/styles/core.scss b/ui/app/styles/core.scss
index 21f8a188b767..6773a664c698 100644
--- a/ui/app/styles/core.scss
+++ b/ui/app/styles/core.scss
@@ -113,7 +113,7 @@
@import './components/tool-tip';
@import './components/transform-edit.scss';
@import './components/transit-card';
-@import './components/ttl-picker2';
+@import './components/ttl-picker';
@import './components/unseal-warning';
@import './components/ui-wizard';
@import './components/vault-loading';
diff --git a/ui/app/templates/components/configure-aws-secret.hbs b/ui/app/templates/components/configure-aws-secret.hbs
index 164f1dec3893..8c387497a077 100644
--- a/ui/app/templates/components/configure-aws-secret.hbs
+++ b/ui/app/templates/components/configure-aws-secret.hbs
@@ -30,8 +30,18 @@
If you do not supply lease settings, we will use the default values in AWS.
-
-
+
+
{{else if (eq @attr.options.editType "ttl")}}
-
-
-
- `[data-test-ttl-toggle="${label}"]`,
+ label: '[data-test-ttl-form-label]',
+ subtext: '[data-test-ttl-form-subtext]',
+ tooltipTrigger: `[data-test-tooltip-trigger]`,
+ ttlValue: '[data-test-ttl-value]',
+ ttlUnit: '[data-test-select="ttl-unit"]',
+ valueInputByLabel: (label) => `[data-test-ttl-value="${label}"]`,
+ unitInputByLabel: (label) => `[data-test-ttl-unit="${label}"] [data-test-select="ttl-unit"]`,
+};
+
+export default selectors;
diff --git a/ui/tests/integration/components/mfa/method-form-test.js b/ui/tests/integration/components/mfa/method-form-test.js
index 12353d268562..033343760438 100644
--- a/ui/tests/integration/components/mfa/method-form-test.js
+++ b/ui/tests/integration/components/mfa/method-form-test.js
@@ -63,7 +63,7 @@ module('Integration | Component | mfa-method-form', function (hooks) {
assert.expect(3);
this.model.issuer = 'Vault';
- this.model.period = '30';
+ this.model.period = '30s';
this.model.algorithm = 'SHA512';
await render(hbs`
diff --git a/ui/tests/integration/components/ttl-form-test.js b/ui/tests/integration/components/ttl-form-test.js
deleted file mode 100644
index 29f131c620f6..000000000000
--- a/ui/tests/integration/components/ttl-form-test.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import { module, test } from 'qunit';
-import { setupRenderingTest } from 'ember-qunit';
-import { render, fillIn } from '@ember/test-helpers';
-import hbs from 'htmlbars-inline-precompile';
-import sinon from 'sinon';
-
-module('Integration | Component | ttl-form', function (hooks) {
- setupRenderingTest(hooks);
-
- hooks.beforeEach(function () {
- this.changeSpy = sinon.spy();
- this.set('onChange', this.changeSpy);
- });
-
- test('it shows no initial time and initial unit of s when not time or unit passed in', async function (assert) {
- await render(hbs``);
- assert.dom('[data-test-ttlform-value]').hasValue('');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('s');
- });
-
- test('it calls the change fn with the correct values', async function (assert) {
- await render(hbs``);
-
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'unit value initially shows m (minutes)');
- await fillIn('[data-test-ttlform-value]', '10');
- await assert.ok(this.changeSpy.calledOnce, 'it calls the passed onChange');
- assert.ok(
- this.changeSpy.calledWith({
- seconds: 600,
- timeString: '10m',
- }),
- 'Passes the default values back to onChange'
- );
- });
-
- test('it correctly shows initial unit', async function (assert) {
- let changeSpy = sinon.spy();
- this.set('onChange', changeSpy);
- await render(hbs`
-
- `);
-
- assert.dom('[data-test-select="ttl-unit"]').hasValue('h', 'unit value initially shows as h (hours)');
- });
-});
diff --git a/ui/tests/integration/components/ttl-picker-test.js b/ui/tests/integration/components/ttl-picker-test.js
index 1142c0fc91df..ad3adb3ecaf9 100644
--- a/ui/tests/integration/components/ttl-picker-test.js
+++ b/ui/tests/integration/components/ttl-picker-test.js
@@ -1,30 +1,390 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
-import { render, fillIn } from '@ember/test-helpers';
-import hbs from 'htmlbars-inline-precompile';
+import { render, click, fillIn } from '@ember/test-helpers';
import sinon from 'sinon';
+import hbs from 'htmlbars-inline-precompile';
+import selectors from 'vault/tests/helpers/components/ttl-picker';
-module('Integration | Component | ttl picker', function (hooks) {
+module('Integration | Component | ttl-picker', function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
- this.changeSpy = sinon.spy();
- this.set('onChange', this.changeSpy);
+ this.set('onChange', sinon.spy());
+ this.set('label', 'Foobar');
});
- test('it renders error on non-number input', async function (assert) {
- await render(hbs``);
+ module('without toggle', function (hooks) {
+ hooks.beforeEach(function () {
+ this.set('hideToggle', true);
+ });
+
+ test('it shows correct time and value when no initialValue set', async function (assert) {
+ await render(hbs``);
+ assert.dom(selectors.ttlFormGroup).exists('TTL Form fields exist');
+ assert.dom(selectors.ttlValue).hasValue('');
+ assert.dom(selectors.ttlUnit).hasValue('s');
+ });
+
+ test('it calls the change fn with the correct values', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.ttlUnit).hasValue('m', 'unit value shows m (minutes)');
+ await fillIn(selectors.ttlValue, '10');
+ await assert.ok(changeSpy.calledOnce, 'it calls the passed onChange');
+ assert.ok(
+ changeSpy.calledWithExactly({
+ enabled: true,
+ seconds: 600,
+ timeString: '10m',
+ goSafeTimeString: '10m',
+ }),
+ 'Passes the values back to onChange'
+ );
+ });
+
+ test('it correctly shows initial time and unit', async function (assert) {
+ await render(hbs`
+
+ `);
+
+ assert.dom(selectors.ttlUnit).hasValue('h', 'unit value initially shows as h (hours)');
+ assert.dom(selectors.ttlValue).hasValue('3', 'time value initially shows as 3');
+ });
+
+ test('it fails gracefully when initialValue is not parseable', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+
+ assert.dom(selectors.ttlValue).hasValue('', 'time value initially shows as empty');
+ assert.dom(selectors.ttlUnit).hasValue('s', 'unit value initially shows as s (seconds)');
+ assert.ok(changeSpy.notCalled, 'onChange is not called on init');
+ });
+
+ test('it recalculates time when unit is changed', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+
+ assert.dom(selectors.ttlUnit).hasValue('h', 'unit value initially shows as h (hours)');
+ assert.dom(selectors.ttlValue).hasValue('1', 'time value initially shows as 1');
+ await fillIn(selectors.ttlUnit, 'm');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'unit value changed to m (minutes)');
+ assert.dom(selectors.ttlValue).hasValue('60', 'time value recalculates to fit unit');
+ assert.ok(
+ changeSpy.calledWithExactly({
+ enabled: true,
+ seconds: 3600,
+ timeString: '60m',
+ goSafeTimeString: '60m',
+ }),
+ 'Passes the values back to onChange'
+ );
+ });
+
+ test('it skips recalculating time when unit is changed if time is not whole number', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+
+ assert.dom(selectors.ttlUnit).hasValue('s', 'unit value starts as s (seconds)');
+ assert.dom(selectors.ttlValue).hasValue('30', 'time value starts as 30');
+ await fillIn(selectors.ttlUnit, 'm');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'unit value changed to m (minutes)');
+ assert.dom(selectors.ttlValue).hasValue('30', 'time value is still 30');
+ assert.ok(
+ changeSpy.calledWithExactly({
+ enabled: true,
+ seconds: 1800,
+ timeString: '30m',
+ goSafeTimeString: '30m',
+ }),
+ 'Passes the values back to onChange'
+ );
+ });
+
+ test('it calls onChange on init when changeOnInit is true', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+
+ assert.ok(changeSpy.calledOnce, 'it calls the passed onChange when rendered');
+ assert.ok(
+ changeSpy.calledWithExactly({
+ enabled: true,
+ seconds: 600,
+ timeString: '10m',
+ goSafeTimeString: '10m',
+ }),
+ 'Passes the values back to onChange'
+ );
+ });
- let callCount = this.changeSpy.callCount;
- await fillIn('[data-test-ttl-value]', 'foo');
- assert.equal(this.changeSpy.callCount, callCount, "it didn't call onChange again");
- assert.dom('[data-test-ttl-error]').includesText('Error', 'renders the error box');
- await fillIn('[data-test-ttl-value]', '33');
- assert.dom('[data-test-ttl-error]').doesNotExist('removes the error box');
+ test('it shows a label when passed', async function (assert) {
+ this.set('label', 'My Label');
+ await render(hbs`
+
+ `);
+
+ assert.dom('[data-test-ttl-form-label]').hasText('My Label', 'Renders label correctly');
+ assert.dom('[data-test-ttl-form-subtext]').doesNotExist('Subtext not rendered');
+ assert.dom('[data-test-tooltip-trigger]').doesNotExist('Description tooltip not rendered');
+ });
+
+ test('it shows subtext and description when passed', async function (assert) {
+ this.set('label', 'My Label');
+ await render(hbs`
+
+ `);
+
+ assert.dom('[data-test-ttl-form-label]').hasText('My Label', 'Renders label correctly');
+ assert.dom('[data-test-ttl-form-subtext]').hasText('Subtext', 'Renders subtext when present');
+ assert
+ .dom('[data-test-tooltip-trigger]')
+ .exists({ count: 1 }, 'Description tooltip icon shows when description present');
+ });
+
+ test('it yields in place of label if block is present', async function (assert) {
+ this.set('label', 'My Label');
+ await render(hbs`
+
+
+
+ `);
+
+ assert.dom('[data-test-custom]').hasText('Different Label', 'custom block is rendered');
+ assert.dom('[data-test-ttl-form-label]').doesNotExist('Label not rendered');
+ });
});
- test('it shows 30s for invalid duration initialValue input', async function (assert) {
- await render(hbs``);
- assert.dom('[data-test-ttl-value]').hasValue('30', 'sets 30 as the default');
+ module('with toggle', function () {
+ test('it has toggle off by default', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.toggle).isNotChecked('Toggle is unchecked by default');
+ assert.dom(selectors.ttlFormGroup).doesNotExist('TTL Form is not rendered');
+ });
+
+ test('it shows time and unit inputs when initialEnabled', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.toggle).isChecked('Toggle is checked when initialEnabled is true');
+ assert.dom(selectors.ttlFormGroup).exists('TTL Form is rendered');
+ assert.ok(changeSpy.notCalled, 'onChange not called because initialValue not parsed');
+ });
+
+ test('it sets initial value to initialValue', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.ttlValue).hasValue('2', 'time value is 2');
+ assert.dom(selectors.ttlUnit).hasValue('h', 'unit is hours');
+ assert.ok(
+ this.onChange.notCalled,
+ 'it does not call onChange after render when changeOnInit is not set'
+ );
+ });
+
+ test('it passes the appropriate data to onChange when toggled on', async function (assert) {
+ const changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+ await click(selectors.toggle);
+ assert.ok(changeSpy.calledOnce, 'it calls the passed onChange');
+ assert.ok(
+ changeSpy.calledWith({
+ enabled: true,
+ seconds: 600,
+ timeString: '10m',
+ goSafeTimeString: '10m',
+ }),
+ 'Passes the values back to onChange'
+ );
+ });
+
+ test('inputs reflect initial value when toggled on', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.toggle).isNotChecked('Toggle is off');
+ assert.dom(selectors.ttlFormGroup).doesNotExist('TTL Form not shown on mount');
+ await click(selectors.toggle);
+ assert.dom(selectors.ttlValue).hasValue('100', 'time after toggle is 100');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'Unit is minutes after toggle');
+ });
+
+ test('it is enabled on init if initialEnabled is true', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.toggle).isChecked('Toggle is on');
+ assert.dom(selectors.ttlFormGroup).exists();
+ assert.dom(selectors.ttlValue).hasValue('100', 'time is shown on mount');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'Unit is shown on mount');
+ await click(selectors.toggle);
+ assert.dom(selectors.toggle).isNotChecked('Toggle is off');
+ assert.dom(selectors.ttlFormGroup).doesNotExist('TTL Form no longer shows after toggle');
+ });
+
+ test('it is enabled on init if initialEnabled evals to truthy', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.toggle).isChecked('Toggle is enabled');
+ assert.dom(selectors.ttlValue).hasValue('100', 'time value is shown on mount');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'Unit matches what is passed in');
+ });
+
+ test('it converts days to go safe time', async function (assert) {
+ await render(hbs`
+
+ `);
+ await click(selectors.toggle);
+ assert.ok(this.onChange.calledOnce, 'it calls the passed onChange');
+ assert.ok(
+ this.onChange.calledWith({
+ enabled: true,
+ seconds: 172800,
+ timeString: '2d',
+ goSafeTimeString: '48h',
+ }),
+ 'Converts day unit to go safe time'
+ );
+ });
+
+ test('it converts to the largest round unit on init', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.ttlValue).hasValue('1000', 'time value is converted');
+ assert.dom(selectors.ttlUnit).hasValue('m', 'unit value is m (minutes)');
+ });
+
+ test('it converts to the largest round unit on init when no unit provided', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.dom(selectors.ttlValue).hasValue('1', 'time value is converted');
+ assert.dom(selectors.ttlUnit).hasValue('d', 'unit value is d (days)');
+ });
});
});
diff --git a/ui/tests/integration/components/ttl-picker2-test.js b/ui/tests/integration/components/ttl-picker2-test.js
deleted file mode 100644
index 63cb9548a35e..000000000000
--- a/ui/tests/integration/components/ttl-picker2-test.js
+++ /dev/null
@@ -1,248 +0,0 @@
-import { module, test } from 'qunit';
-import { setupRenderingTest } from 'ember-qunit';
-import { render, click, fillIn } from '@ember/test-helpers';
-import sinon from 'sinon';
-import hbs from 'htmlbars-inline-precompile';
-
-module('Integration | Component | ttl-picker2', function (hooks) {
- setupRenderingTest(hooks);
-
- hooks.beforeEach(function () {
- this.set('onChange', sinon.spy());
- });
-
- test('it renders time and unit inputs when TTL enabled', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').exists('TTL Picker time input exists');
- assert.dom('[data-test-ttl-unit]').exists('TTL Picker unit select exists');
- });
-
- test('it does not show time and unit inputs when TTL disabled', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').doesNotExist('TTL Picker time input exists');
- assert.dom('[data-test-ttl-unit]').doesNotExist('TTL Picker unit select exists');
- });
-
- test('it passes the appropriate data to onChange when toggled on', async function (assert) {
- await render(hbs`
-
- `);
- await click('[data-test-toggle-input="clicktest"]');
- assert.ok(this.onChange.calledOnce, 'it calls the passed onChange');
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 600,
- timeString: '10m',
- goSafeTimeString: '10m',
- }),
- 'Passes the default values back to onChange'
- );
- });
-
- test('it keeps seconds value when unit is changed', async function (assert) {
- await render(hbs`
-
- `);
- await click('[data-test-toggle-input="clicktest"]');
- assert.ok(this.onChange.calledOnce, 'it calls the passed onChange');
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 360,
- timeString: '360s',
- goSafeTimeString: '360s',
- }),
- 'Changes enabled to true on click'
- );
- await fillIn('[data-test-select="ttl-unit"]', 'm');
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 360,
- timeString: '6m',
- goSafeTimeString: '6m',
- }),
- 'Units and time update without changing seconds value'
- );
- assert.dom('[data-test-ttl-value]').hasValue('6', 'time value shows as 6');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'unit value shows as m (minutes)');
- });
-
- test('it recalculates seconds when unit is changed and recalculateSeconds is on', async function (assert) {
- await render(hbs`
-
- `);
- await fillIn('[data-test-select="ttl-unit"]', 'm');
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 7200,
- timeString: '120m',
- goSafeTimeString: '120m',
- }),
- 'Seconds value is recalculated based on time and unit'
- );
- });
-
- test('it sets default value to time and unit passed', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').hasValue('2', 'time value is 2');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('h', 'unit is hours');
- assert.ok(this.onChange.notCalled, 'it does not call onChange after render when changeOnInit is not set');
- });
-
- test('it is disabled on init if initialEnabled is false', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').doesNotExist('Value is not shown on mount');
- assert.dom('[data-test-ttl-unit]').doesNotExist('Unit is not shown on mount');
- await click('[data-test-toggle-input="inittest"]');
- assert.dom('[data-test-ttl-value]').hasValue('100', 'time after toggle is 100');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit is minutes after toggle');
- });
-
- test('it is enabled on init if initialEnabled is true', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').hasValue('100', 'time is shown on mount');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit is shown on mount');
- await click('[data-test-toggle-input="inittest"]');
- assert.dom('[data-test-ttl-value]').doesNotExist('Value no longer shows after toggle');
- assert.dom('[data-test-ttl-unit]').doesNotExist('Unit no longer shows after toggle');
- });
-
- test('it is enabled on init if initialEnabled evals to truthy', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').hasValue('100', 'time value is shown on mount');
- assert.dom('[data-test-ttl-unit]').exists('Unit is shown on mount');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit matches what is passed in');
- });
-
- test('it calls onChange', async function (assert) {
- await render(hbs`
-
- `);
- await click('[data-test-toggle-input="clicktest"]');
- assert.ok(this.onChange.calledOnce, 'it calls the passed onChange');
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 172800,
- timeString: '2d',
- goSafeTimeString: '48h',
- }),
- 'Converts day unit to go safe time'
- );
- });
-
- test('it calls onChange on init when rendered if changeOnInit is true', async function (assert) {
- await render(hbs`
-
- `);
- assert.ok(
- this.onChange.calledWith({
- enabled: true,
- seconds: 6000,
- timeString: '100m',
- goSafeTimeString: '100m',
- }),
- 'Seconds value is recalculated based on time and unit'
- );
- assert.ok(this.onChange.calledOnce, 'it calls the passed onChange after render');
- });
-
- test('it converts to the largest round unit on init', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').hasValue('1000', 'time value is converted');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'unit value is m (minutes)');
- });
-
- test('it converts to the largest round unit on init when no unit provided', async function (assert) {
- await render(hbs`
-
- `);
- assert.dom('[data-test-ttl-value]').hasValue('1', 'time value is converted');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('d', 'unit value is d (days)');
- });
-});
diff --git a/ui/tests/integration/components/wrap-ttl-test.js b/ui/tests/integration/components/wrap-ttl-test.js
index 1ca7dd48877e..20bc4700df79 100644
--- a/ui/tests/integration/components/wrap-ttl-test.js
+++ b/ui/tests/integration/components/wrap-ttl-test.js
@@ -1,4 +1,5 @@
import { module, test } from 'qunit';
+import Sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, fillIn } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
@@ -7,38 +8,37 @@ import waitForError from 'vault/tests/helpers/wait-for-error';
module('Integration | Component | wrap ttl', function (hooks) {
setupRenderingTest(hooks);
- hooks.beforeEach(function () {
- this.lastOnChangeCall = null;
- this.set('onChange', (val) => {
- this.lastOnChangeCall = val;
- });
- });
-
test('it requires `onChange`', async function (assert) {
- let promise = waitForError();
- render(hbs`{{wrap-ttl}}`);
- let err = await promise;
+ const promise = waitForError();
+ render(hbs``);
+ const err = await promise;
assert.ok(err.message.includes('`onChange` handler is a required attr in'), 'asserts without onChange');
});
test('it renders', async function (assert) {
- await render(hbs`{{wrap-ttl onChange=(action onChange)}}`);
- assert.equal(this.lastOnChangeCall, '30m', 'calls onChange with 30m default on first render');
- assert.dom('label[for="toggle-Wrapresponse"] .ttl-picker-label').hasText('Wrap response');
+ const changeSpy = Sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs``);
+ assert.ok(changeSpy.calledWithExactly('30m'), 'calls onChange with 30m default on render');
+ assert.dom('[data-test-ttl-form-label]').hasText('Wrap response');
});
test('it nulls out value when you uncheck wrapResponse', async function (assert) {
- await render(hbs`{{wrap-ttl onChange=(action onChange)}}`);
- await click('[data-test-toggle-label="Wrap response"]');
- assert.equal(this.lastOnChangeCall, null, 'calls onChange with null');
+ const changeSpy = Sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs``);
+ await click('[data-test-ttl-form-label]');
+ assert.ok(changeSpy.calledWithExactly(null), 'calls onChange with null');
});
test('it sends value changes to onChange handler', async function (assert) {
- await render(hbs`{{wrap-ttl onChange=(action onChange)}}`);
+ const changeSpy = Sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs``);
// for testing purposes we need to input unit first because it keeps seconds value
await fillIn('[data-test-select="ttl-unit"]', 'h');
- assert.equal(this.lastOnChangeCall, '1800s', 'calls onChange correctly on time input');
- await fillIn('[data-test-ttl-value="Wrap response"]', '20');
- assert.equal(this.lastOnChangeCall, '72000s', 'calls onChange correctly on unit change');
+ assert.ok(changeSpy.calledWithExactly('30h'), 'calls onChange correctly on time input');
+ await fillIn('[data-test-ttl-value]', '20');
+ assert.ok(changeSpy.calledWithExactly('20h'), 'calls onChange correctly on unit change');
});
});