27bb03bbc0
* adding copyright header * fix fmt and a test
396 lines
13 KiB
JavaScript
396 lines
13 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: MPL-2.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';
|
|
import selectors from 'vault/tests/helpers/components/ttl-picker';
|
|
|
|
module('Integration | Component | ttl-picker', function (hooks) {
|
|
setupRenderingTest(hooks);
|
|
|
|
hooks.beforeEach(function () {
|
|
this.set('onChange', sinon.spy());
|
|
this.set('label', 'Foobar');
|
|
});
|
|
|
|
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`<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@onChange={{this.onChange}} />`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@onChange={{this.onChange}}
|
|
@initialValue="30m" />
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@initialValue="3h"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@initialValue="foobar"
|
|
@onChange={{this.onChange}}
|
|
@changeOnInit={{true}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@initialValue="1h"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@initialValue="30s"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@initialValue="10m"
|
|
@changeOnInit={{true}}
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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'
|
|
);
|
|
});
|
|
|
|
test('it shows a label when passed', async function (assert) {
|
|
this.set('label', 'My Label');
|
|
await render(hbs`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@helperTextEnabled="Subtext"
|
|
@description="Description"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@hideToggle={{this.hideToggle}}
|
|
@helperTextEnabled="Subtext"
|
|
@description="Description"
|
|
@onChange={{this.onChange}}
|
|
>
|
|
<legend data-test-custom>Different Label</legend>
|
|
</TtlPicker>
|
|
`);
|
|
|
|
assert.dom('[data-test-custom]').hasText('Different Label', 'custom block is rendered');
|
|
assert.dom('[data-test-ttl-form-label]').doesNotExist('Label not rendered');
|
|
});
|
|
});
|
|
|
|
module('with toggle', function () {
|
|
test('it has toggle off by default', async function (assert) {
|
|
await render(hbs`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@onChange={{this.onChange}}
|
|
@initialEnabled={{true}}
|
|
@changeOnInit={{true}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@onChange={{this.onChange}}
|
|
@initialValue="2h"
|
|
@initialEnabled={{true}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="clicktest"
|
|
@initialValue="10m"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="inittest"
|
|
@onChange={{this.onChange}}
|
|
@initialValue="100m"
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="inittest"
|
|
@onChange={{this.onChange}}
|
|
@initialValue="100m"
|
|
@initialEnabled={{true}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="inittest"
|
|
@onChange={{this.onChange}}
|
|
@initialValue="100m"
|
|
@initialEnabled="100m"
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="clicktest"
|
|
@initialValue="2d"
|
|
@onChange={{this.onChange}}
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="convertunits"
|
|
@onChange={{this.onChange}}
|
|
@initialValue="60000s"
|
|
@initialEnabled="true"
|
|
/>
|
|
`);
|
|
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`
|
|
<TtlPicker
|
|
@label={{this.label}}
|
|
@label="convertunits"
|
|
@onChange={{this.onChange}}
|
|
@initialValue={{86400}}
|
|
@initialEnabled="true"
|
|
/>
|
|
`);
|
|
assert.dom(selectors.ttlValue).hasValue('1', 'time value is converted');
|
|
assert.dom(selectors.ttlUnit).hasValue('d', 'unit value is d (days)');
|
|
});
|
|
});
|
|
});
|