UI: Fix flaky time-related tests (#19521)

This commit is contained in:
Chelsea Shaw
2023-03-22 13:19:11 -05:00
committed by GitHub
parent 3dbe94678f
commit bf2f1a88d6
65 changed files with 643 additions and 525 deletions

View File

@@ -8,6 +8,7 @@ import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { ARRAY_OF_MONTHS, parseAPITimestamp } from 'core/utils/date-formatters';
import { addYears, isSameYear, subYears } from 'date-fns';
import timestamp from 'core/utils/timestamp';
/**
* @module CalendarWidget
* CalendarWidget component is used in the client counts dashboard to select a month/year to query the /activity endpoint.
@@ -24,7 +25,7 @@ import { addYears, isSameYear, subYears } from 'date-fns';
* ```
*/
export default class CalendarWidget extends Component {
currentDate = new Date();
currentDate = timestamp.now();
@tracked calendarDisplayDate = this.currentDate; // init to current date, updates when user clicks on calendar chevrons
@tracked showCalendar = false;
@tracked tooltipTarget = null;

View File

@@ -7,6 +7,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
import timestamp from 'core/utils/timestamp';
/**
* @module DateDropdown
* DateDropdown components are used to display a dropdown of months and years to handle date selection. Future dates are disabled (current month and year are selectable).
@@ -23,7 +24,7 @@ import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
* @param {function} [validateDate] - parent function to validate date selection, receives date object and returns an error message that's passed to the inline alert
*/
export default class DateDropdown extends Component {
currentDate = new Date();
currentDate = timestamp.now();
currentYear = this.currentDate.getFullYear(); // integer of year
currentMonthIdx = this.currentDate.getMonth(); // integer of month, 0 indexed
dropdownMonths = ARRAY_OF_MONTHS.map((m, i) => ({ name: m, index: i }));

View File

@@ -10,6 +10,7 @@ import { inject as service } from '@ember/service';
import isAfter from 'date-fns/isAfter';
import differenceInDays from 'date-fns/differenceInDays';
import localStorage from 'vault/lib/local-storage';
import timestamp from 'core/utils/timestamp';
/**
* @module LicenseBanners
@@ -41,13 +42,13 @@ export default class LicenseBanners extends Component {
get licenseExpired() {
if (!this.args.expiry) return false;
return isAfter(new Date(), new Date(this.args.expiry));
return isAfter(timestamp.now(), new Date(this.args.expiry));
}
get licenseExpiringInDays() {
// Anything more than 30 does not render a warning
if (!this.args.expiry) return 99;
return differenceInDays(new Date(this.args.expiry), new Date());
return differenceInDays(new Date(this.args.expiry), timestamp.now());
}
@action

View File

@@ -4,6 +4,7 @@
*/
import { belongsTo, attr } from '@ember-data/model';
import timestamp from 'core/utils/timestamp';
import SecretModel from './secret';
export default class SecretV2VersionModel extends SecretModel {
@@ -20,7 +21,7 @@ export default class SecretV2VersionModel extends SecretModel {
get deleted() {
const deletionTime = new Date(this.deletionTime);
const now = new Date();
const now = timestamp.now();
return deletionTime <= now;
}
}

View File

@@ -6,10 +6,11 @@
import Route from '@ember/routing/route';
import getStorage from 'vault/lib/token-storage';
import { inject as service } from '@ember/service';
import timestamp from 'core/utils/timestamp';
export default class DashboardRoute extends Route {
@service store;
currentDate = new Date().toISOString();
currentDate = timestamp.now().toISOString();
async getActivity(start_time) {
// on init ONLY make network request if we have a start_time

View File

@@ -6,12 +6,13 @@
import ApplicationSerializer from '../application';
import { formatISO } from 'date-fns';
import { formatByMonths, formatByNamespace, homogenizeClientNaming } from 'core/utils/client-count-utils';
import timestamp from 'core/utils/timestamp';
export default class ActivitySerializer extends ApplicationSerializer {
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
if (payload.id === 'no-data') {
return super.normalizeResponse(store, primaryModelClass, payload, id, requestType);
}
const response_timestamp = formatISO(new Date());
const response_timestamp = formatISO(timestamp.now());
const transformedPayload = {
...payload,
response_timestamp,
@@ -25,7 +26,7 @@ export default class ActivitySerializer extends ApplicationSerializer {
return super.normalizeResponse(store, primaryModelClass, transformedPayload, id, requestType);
}
}
/*
/*
SAMPLE PAYLOAD BEFORE/AFTER:
payload.data.by_namespace = [

View File

@@ -4,6 +4,7 @@
*/
import Service from '@ember/service';
import timestamp from 'core/utils/timestamp';
interface Extensions {
csv: string;
@@ -29,7 +30,7 @@ export default class DownloadService extends Service {
// replace spaces with hyphens, append extension to filename
const formattedFilename =
`${filename?.replace(/\s+/g, '-')}.${extension}` ||
`vault-data-${new Date().toISOString()}.${extension}`;
`vault-data-${timestamp.now().toISOString()}.${extension}`;
// map extension to MIME type or use default
const mimetype = EXTENSION_TO_MIME[extension as keyof Extensions] || 'text/plain';

View File

@@ -7,6 +7,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import errorMessage from 'vault/utils/error-message';
import timestamp from 'vault/utils/timestamp';
/**
* @module DownloadButton
* DownloadButton components are an action button used to download data. Both the action text and icon are yielded.
@@ -37,8 +38,8 @@ export default class DownloadButton extends Component {
@service flashMessages;
get filename() {
const timestamp = new Date().toISOString();
return this.args.filename ? this.args.filename + '-' + timestamp : timestamp;
const ts = timestamp.now().toISOString();
return this.args.filename ? this.args.filename + '-' + ts : ts;
}
get content() {

View File

@@ -0,0 +1,15 @@
/**
* Use this instead of new Date() throughout the app so that time-related logic is easier to test.
*/
const timestamp = {
// Method defined within an object so it can be stubbed
/**
* * Use timestamp.now to create a date for the current moment. In testing context, stub this method so it returns an expected value
* @returns Date object
*/
now: () => {
return new Date();
},
};
export default timestamp;

View File

@@ -0,0 +1 @@
export { default } from 'core/utils/timestamp';

View File

@@ -11,7 +11,7 @@ import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';
import { add } from 'date-fns';
import errorMessage from 'vault/utils/error-message';
import timestamp from 'vault/utils/timestamp';
/**
* @module Credentials
* CredentialsPage component is a child component to show the generate and view
@@ -33,7 +33,7 @@ export default class CredentialsPageComponent extends Component {
@tracked credentials;
get leaseExpiry() {
return add(new Date(), { seconds: this.credentials.lease_duration });
return add(timestamp.now(), { seconds: this.credentials.lease_duration });
}
@action

View File

@@ -16,7 +16,8 @@ import {
} from 'date-fns';
import { parseAPITimestamp } from 'core/utils/date-formatters';
const CURRENT_DATE = new Date();
// Matches mocked date in client-dashboard-test file
const CURRENT_DATE = new Date('2023-01-13T14:15:00');
const COUNTS_START = subMonths(CURRENT_DATE, 12); // pretend vault user started cluster 6 months ago
// for testing, we're in the middle of a license/billing period
const LICENSE_START = startOfMonth(subMonths(CURRENT_DATE, 6));

View File

@@ -16,6 +16,8 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/auth/enable';
@@ -107,14 +109,14 @@ module('Acceptance | auth backend list', function (hooks) {
test('auth methods are linkable and link to correct view', async function (assert) {
assert.expect(16);
const timestamp = new Date().getTime();
const uid = uuidv4();
await visit('/vault/access');
const supportManaged = supportedManagedAuthBackends();
const backends = supportedAuthBackends();
for (const backend of backends) {
const { type } = backend;
const path = `${type}-${timestamp}`;
const path = `auth-list-${type}-${uid}`;
if (type !== 'token') {
await enablePage.enable(type, path);
}

View File

@@ -6,6 +6,8 @@
import { click, fillIn, findAll, currentURL, find, settled, waitUntil } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -14,6 +16,7 @@ module('Acceptance | aws secret backend', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
@@ -33,8 +36,7 @@ module('Acceptance | aws secret backend', function (hooks) {
};
test('aws backend', async function (assert) {
assert.expect(12);
const now = new Date().getTime();
const path = `aws-${now}`;
const path = `aws-${this.uid}`;
const roleName = 'awsrole';
await enablePage.enable('aws', path);

View File

@@ -4,10 +4,11 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { visit, currentURL, click, findAll, find, settled } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import authPage from 'vault/tests/pages/auth';
import { addMonths, format, formatRFC3339, startOfMonth, subMonths } from 'date-fns';
import { addMonths, formatRFC3339, startOfMonth, subMonths } from 'date-fns';
import { setupMirage } from 'ember-cli-mirage/test-support';
import ENV from 'vault/config/environment';
import { SELECTORS, overrideResponse } from '../helpers/clients';
@@ -16,23 +17,22 @@ import ss from 'vault/tests/pages/components/search-select';
import { clickTrigger } from 'ember-power-select/test-support/helpers';
import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
import { formatNumber } from 'core/helpers/format-number';
import timestamp from 'core/utils/timestamp';
const searchSelect = create(ss);
const CURRENT_DATE = new Date();
const LAST_MONTH = startOfMonth(subMonths(CURRENT_DATE, 1));
const COUNTS_START = subMonths(CURRENT_DATE, 12); // pretend vault user started cluster 1 year ago
const STATIC_NOW = new Date('2023-01-13T14:15:00');
// for testing, we're in the middle of a license/billing period
const LICENSE_START = startOfMonth(subMonths(CURRENT_DATE, 6));
const LICENSE_START = startOfMonth(subMonths(STATIC_NOW, 6)); // 2022-07-01
// upgrade happened 1 month after license start
const UPGRADE_DATE = addMonths(LICENSE_START, 1);
const UPGRADE_DATE = addMonths(LICENSE_START, 1); // 2022-08-01
module('Acceptance | client counts dashboard tab', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => STATIC_NOW);
ENV['ember-cli-mirage'].handler = 'clients';
});
@@ -41,6 +41,7 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
});
hooks.after(function () {
timestamp.now.restore();
ENV['ember-cli-mirage'].handler = null;
});
@@ -95,13 +96,10 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
assert.strictEqual(currentURL(), '/vault/clients/dashboard');
assert
.dom(SELECTORS.dateDisplay)
.hasText(format(LICENSE_START, 'MMMM yyyy'), 'billing start month is correctly parsed from license');
.hasText('July 2022', 'billing start month is correctly parsed from license');
assert
.dom(SELECTORS.rangeDropdown)
.hasText(
`${format(LICENSE_START, 'MMM yyyy')} - ${format(CURRENT_DATE, 'MMM yyyy')}`,
'Date range shows dates correctly parsed activity response'
);
.hasText(`Jul 2022 - Jan 2023`, 'Date range shows dates correctly parsed activity response');
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
assert.dom(SELECTORS.monthlyUsageBlock).exists('Shows monthly usage block');
assert
@@ -109,7 +107,7 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
.exists('Shows running totals with monthly breakdown charts');
assert
.dom(find('[data-test-line-chart="x-axis-labels"] g.tick text'))
.hasText(`${format(LICENSE_START, 'M/yy')}`, 'x-axis labels start with billing start date');
.hasText(`7/22`, 'x-axis labels start with billing start date');
assert.strictEqual(
findAll('[data-test-line-chart="plot-point"]').length,
6,
@@ -118,7 +116,7 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
});
test('updates correctly when querying date ranges', async function (assert) {
assert.expect(26);
assert.expect(27);
await visit('/vault/clients/dashboard');
assert.strictEqual(currentURL(), '/vault/clients/dashboard');
// query for single, historical month with no new counts
@@ -163,21 +161,18 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
.exists('Shows running totals with monthly breakdown charts');
assert
.dom(find('[data-test-line-chart="x-axis-labels"] g.tick text'))
.hasText(`${format(UPGRADE_DATE, 'M/yy')}`, 'x-axis labels start with updated billing start month');
.hasText(`8/22`, 'x-axis labels start with updated billing start month');
assert.strictEqual(
findAll('[data-test-line-chart="plot-point"]').length,
6,
`line chart plots 6 points to match query`
);
// query three months ago
const customEndDate = subMonths(CURRENT_DATE, 3);
// query three months ago (Oct 2022)
await click(SELECTORS.rangeDropdown);
await click('[data-test-show-calendar]');
if (parseInt(find('[data-test-display-year]').innerText) !== customEndDate.getFullYear()) {
await click('[data-test-previous-year]');
}
await click(find(`[data-test-calendar-month=${ARRAY_OF_MONTHS[customEndDate.getMonth()]}]`));
await click('[data-test-previous-year]');
await click(find(`[data-test-calendar-month="October"]`));
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
assert.dom(SELECTORS.monthlyUsageBlock).exists('Shows monthly usage block');
@@ -192,15 +187,13 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
const xAxisLabels = findAll('[data-test-line-chart="x-axis-labels"] g.tick text');
assert
.dom(xAxisLabels[xAxisLabels.length - 1])
.hasText(`${format(subMonths(LAST_MONTH, 2), 'M/yy')}`, 'x-axis labels end with queried end month');
.hasText(`10/22`, 'x-axis labels end with queried end month');
// query for single, historical month (upgrade month)
await click(SELECTORS.rangeDropdown);
await click('[data-test-show-calendar]');
if (parseInt(find('[data-test-display-year]').innerText) !== UPGRADE_DATE.getFullYear()) {
await click('[data-test-previous-year]');
}
await click(find(`[data-test-calendar-month=${ARRAY_OF_MONTHS[UPGRADE_DATE.getMonth()]}]`));
assert.dom('[data-test-display-year]').hasText('2022');
await click(find(`[data-test-calendar-month="August"]`));
assert.dom(SELECTORS.runningTotalMonthStats).exists('running total single month stat boxes show');
assert
@@ -224,7 +217,7 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
assert
.dom('[data-test-alert-banner="alert"]')
.hasTextContaining(
`We only have data from ${format(COUNTS_START, 'MMMM yyyy')}`,
`We only have data from January 2022`,
'warning banner displays that date queried was prior to count start date'
);
});
@@ -341,17 +334,14 @@ module('Acceptance | client counts dashboard tab', function (hooks) {
assert
.dom('[data-test-alert-banner="alert"]')
.hasTextContaining(
`Warning Vault was upgraded to 1.10.1 on ${format(
UPGRADE_DATE,
'MMM d, yyyy'
)}. We added monthly breakdowns and mount level attribution starting in 1.10, so keep that in mind when looking at the data. Learn more here.`
`Warning Vault was upgraded to 1.10.1 on Aug 1, 2022. We added monthly breakdowns and mount level attribution starting in 1.10, so keep that in mind when looking at the data. Learn more here.`
);
});
test('Shows empty if license start date is current month', async function (assert) {
// TODO cmb update to reflect new behavior
const licenseStart = CURRENT_DATE;
const licenseEnd = addMonths(CURRENT_DATE, 12);
const licenseStart = STATIC_NOW;
const licenseEnd = addMonths(licenseStart, 12);
this.server.get('sys/license/status', function () {
return {
request_id: 'my-license-request-id',

View File

@@ -7,6 +7,8 @@ import { create } from 'ember-cli-page-object';
import { settled, click } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/auth/enable';
@@ -31,8 +33,8 @@ const authAccessor = async function (path) {
await consoleComponent.runCommands([`write auth/${path}/users/end-user password="${PASSWORD}"`]);
};
const setupUser = async function () {
const authMethodPath = `userpass-${new Date().getTime()}`;
const setupUser = async function (uid) {
const authMethodPath = `cluster-userpass-${uid}`;
await authAccessor(authMethodPath);
};
@@ -40,6 +42,7 @@ module('Acceptance | cluster', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async function () {
this.uid = uuidv4();
await logout.visit();
return authPage.login();
});
@@ -60,7 +63,7 @@ module('Acceptance | cluster', function (hooks) {
});
test('it hides mfa setup if user has not entityId (ex: is a root user)', async function (assert) {
await setupUser();
await setupUser(this.uid);
await logout.visit();
await settled();

View File

@@ -26,15 +26,23 @@ module('Acceptance | console', function (hooks) {
const numEngines = enginesPage.rows.length;
await consoleComponent.toggle();
await settled();
const now = Date.now();
for (const num of [1, 2, 3]) {
const inputString = `write sys/mounts/${now + num} type=kv`;
const inputString = `write sys/mounts/console-route-${num} type=kv`;
await consoleComponent.runCommands(inputString);
await settled();
}
await consoleComponent.runCommands('refresh');
await settled();
assert.strictEqual(enginesPage.rows.length, numEngines + 3, 'new engines were added to the page');
// Clean up
for (const num of [1, 2, 3]) {
const inputString = `delete sys/mounts/console-route-${num}`;
await consoleComponent.runCommands(inputString);
await settled();
}
await consoleComponent.runCommands('refresh');
await settled();
assert.strictEqual(enginesPage.rows.length, numEngines, 'engines were removed from the page');
});
test('fullscreen command expands the cli panel', async function (assert) {

View File

@@ -4,23 +4,25 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { visit } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import Pretender from 'pretender';
import formatRFC3339 from 'date-fns/formatRFC3339';
import { addDays, subDays } from 'date-fns';
import timestamp from 'core/utils/timestamp';
const generateHealthResponse = (state) => {
const generateHealthResponse = (now, state) => {
let expiry;
switch (state) {
case 'expired':
expiry = subDays(new Date(), 2);
expiry = subDays(now, 2);
break;
case 'expiring':
expiry = addDays(new Date(), 10);
expiry = addDays(now, 10);
break;
default:
expiry = addDays(new Date(), 33);
expiry = addDays(now, 33);
break;
}
return {
@@ -45,12 +47,21 @@ const generateHealthResponse = (state) => {
module('Acceptance | Enterprise | License banner warnings', function (hooks) {
setupApplicationTest(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.now = timestamp.now();
});
hooks.afterEach(function () {
this.server.shutdown();
});
hooks.after(function () {
timestamp.now.restore();
});
test('it shows no license banner if license expires in > 30 days', async function (assert) {
const healthResp = generateHealthResponse();
const healthResp = generateHealthResponse(this.now);
this.server = new Pretender(function () {
this.get('/v1/sys/health', (response) => {
return [response, { 'Content-Type': 'application/json' }, JSON.stringify(healthResp)];
@@ -65,7 +76,7 @@ module('Acceptance | Enterprise | License banner warnings', function (hooks) {
this.server.shutdown();
});
test('it shows license banner warning if license expires within 30 days', async function (assert) {
const healthResp = generateHealthResponse('expiring');
const healthResp = generateHealthResponse(this.now, 'expiring');
this.server = new Pretender(function () {
this.get('/v1/sys/health', (response) => {
return [response, { 'Content-Type': 'application/json' }, JSON.stringify(healthResp)];
@@ -81,7 +92,7 @@ module('Acceptance | Enterprise | License banner warnings', function (hooks) {
});
test('it shows license banner alert if license has already expired', async function (assert) {
const healthResp = generateHealthResponse('expired');
const healthResp = generateHealthResponse(this.now, 'expired');
this.server = new Pretender(function () {
this.get('/v1/sys/health', (response) => {
return [response, { 'Content-Type': 'application/json' }, JSON.stringify(healthResp)];

View File

@@ -12,6 +12,7 @@ import { click, currentRouteName, visit } from '@ember/test-helpers';
import { module, skip } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import secretList from 'vault/tests/pages/secrets/backend/list';
import secretEdit from 'vault/tests/pages/secrets/backend/kv/edit-secret';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
@@ -23,7 +24,7 @@ module('Acceptance | leases', function (hooks) {
hooks.beforeEach(async function () {
await authPage.login();
this.enginePath = `kv-for-lease-${new Date().getTime()}`;
this.enginePath = `kv-for-lease-${uuidv4()}`;
// need a version 1 mount for leased secrets here
return mountSecrets.visit().path(this.enginePath).type('kv').version(1).submit();
});
@@ -33,7 +34,7 @@ module('Acceptance | leases', function (hooks) {
});
const createSecret = async (context, isRenewable) => {
context.name = `secret-${new Date().getTime()}`;
context.name = `secret-${uuidv4()}`;
await secretList.visitRoot({ backend: context.enginePath });
await secretList.create();
if (isRenewable) {

View File

@@ -5,6 +5,7 @@
import { module, test } from 'qunit';
import { create } from 'ember-cli-page-object';
import { v4 as uuidv4 } from 'uuid';
import { setupApplicationTest } from 'ember-qunit';
import { click, fillIn } from '@ember/test-helpers';
import authPage from 'vault/tests/pages/auth';
@@ -35,7 +36,7 @@ const writeUserWithPolicy = async function (path) {
};
const setupUser = async function () {
const path = `userpass-${new Date().getTime()}`;
const path = `userpass-${uuidv4()}`;
await writePolicy(path);
await writeUserWithPolicy(path);
await click('[data-test-save-config="true"]');

View File

@@ -18,6 +18,7 @@ module('Acceptance | oidc auth method', function (hooks) {
hooks.beforeEach(function () {
this.openStub = sinon.stub(window, 'open').callsFake(() => fakeWindow.create());
// OIDC test fails when using fake timestamps, we use the real timestamp.now here
this.server.post('/auth/oidc/oidc/auth_url', () => ({
data: { auth_url: 'http://example.com' },
}));

View File

@@ -6,6 +6,8 @@
import { create } from 'ember-cli-page-object';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import authForm from 'vault/tests/pages/components/auth-form';
@@ -33,7 +35,7 @@ const GROUP_TOKEN_TEMPLATE = `{
}`;
const oidcEntity = async function (name, policy) {
await consoleComponent.runCommands([
`write sys/policies/acl/${name} policy=${btoa(policy)}`,
`write sys/policies/acl/${name} policy=${window.btoa(policy)}`,
`write identity/entity name="${OIDC_USER}" policies="${name}" metadata="email=vault@hashicorp.com" metadata="phone_number=123-456-7890"`,
`read -field=id identity/entity/name/${OIDC_USER}`,
]);
@@ -109,11 +111,11 @@ const getAuthzUrl = (providerName, redirect, clientId, params) => {
return `/vault/identity/oidc/provider/${providerName}/authorize${queryString}`;
};
const setupOidc = async function () {
const setupOidc = async function (uid) {
const callback = 'http://127.0.0.1:8251/callback';
const entityId = await oidcEntity('oidc', OIDC_POLICY);
const groupId = await oidcGroup(entityId);
const authMethodPath = `userpass-${new Date().getTime()}`;
const authMethodPath = `oidc-userpass-${uid}`;
const accessor = await authAccessor(authMethodPath);
await entityAlias(entityId, accessor, groupId);
const clientId = await setupWebapp(callback);
@@ -130,13 +132,14 @@ module('Acceptance | oidc provider', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async function () {
this.uid = uuidv4();
this.store = await this.owner.lookup('service:store');
await logout.visit();
return authPage.login();
});
test('OIDC Provider logs in and redirects correctly', async function (assert) {
const { providerName, callback, clientId, authMethodPath } = await setupOidc();
const { providerName, callback, clientId, authMethodPath } = await setupOidc(this.uid);
await logout.visit();
await settled();
@@ -172,7 +175,7 @@ module('Acceptance | oidc provider', function (hooks) {
});
test('OIDC Provider redirects to auth if current token and prompt = login', async function (assert) {
const { providerName, callback, clientId, authMethodPath } = await setupOidc();
const { providerName, callback, clientId, authMethodPath } = await setupOidc(this.uid);
await settled();
const url = getAuthzUrl(providerName, callback, clientId, { prompt: 'login' });
await visit(url);
@@ -197,7 +200,7 @@ module('Acceptance | oidc provider', function (hooks) {
});
test('OIDC Provider shows consent form when prompt = consent', async function (assert) {
const { providerName, callback, clientId, authMethodPath } = await setupOidc();
const { providerName, callback, clientId, authMethodPath } = await setupOidc(this.uid);
const url = getAuthzUrl(providerName, callback, clientId, { prompt: 'consent' });
await logout.visit();
await authFormComponent.selectMethod(authMethodPath);

View File

@@ -5,6 +5,8 @@
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -22,7 +24,7 @@ module('Acceptance | pki engine route cleanup test', function (hooks) {
this.store = this.owner.lookup('service:store');
await authPage.login();
// Setup PKI engine
const mountPath = `pki-workflow-${new Date().getTime()}`;
const mountPath = `pki-workflow-${uuidv4()}`;
await enablePage.enable('pki', mountPath);
this.mountPath = mountPath;
await logout.visit();

View File

@@ -5,6 +5,8 @@
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -25,7 +27,7 @@ module('Acceptance | pki workflow', function (hooks) {
hooks.beforeEach(async function () {
await authPage.login();
// Setup PKI engine
const mountPath = `pki-workflow-${new Date().getTime()}`;
const mountPath = `pki-workflow-${uuidv4()}`;
await enablePage.enable('pki', mountPath);
this.mountPath = mountPath;
await logout.visit();

View File

@@ -6,6 +6,8 @@
import { click, fillIn, find, currentURL, waitUntil } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/policies/index';
import authPage from 'vault/tests/pages/auth';
@@ -13,13 +15,13 @@ module('Acceptance | policies (old)', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('policies', async function (assert) {
const now = new Date().getTime();
const policyString = 'path "*" { capabilities = ["update"]}';
const policyName = `Policy test ${now}`;
const policyName = `Policy test ${this.uid}`;
const policyLower = policyName.toLowerCase();
await page.visit({ type: 'acl' });
@@ -69,9 +71,8 @@ module('Acceptance | policies (old)', function (hooks) {
// https://github.com/hashicorp/vault/issues/4395
test('it properly fetches policies when the name ends in a ,', async function (assert) {
const now = new Date().getTime();
const policyString = 'path "*" { capabilities = ["update"]}';
const policyName = `${now}-symbol,.`;
const policyName = `${this.uid}-policy-symbol,.`;
await page.visit({ type: 'acl' });
// new policy creation

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MPL-2.0
*/
import { currentURL, currentRouteName, settled } from '@ember/test-helpers';
import { currentURL, currentRouteName, settled, find, findAll, click } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { create } from 'ember-cli-page-object';
@@ -25,8 +25,13 @@ module('Acceptance | policies/acl', function (hooks) {
await page.visit({ type: 'acl' });
await settled();
assert.strictEqual(currentURL(), '/vault/policies/acl');
assert.ok(page.findPolicyByName('root'), 'root policy shown in the list');
assert.ok(page.findPolicyByName('default'), 'default policy shown in the list');
if (find('nav.pagination')) {
// Root ACL is always last in the list
const paginationLinks = findAll('.pagination-link');
await click(paginationLinks[paginationLinks.length - 1]);
}
assert.ok(page.findPolicyByName('root'), 'root policy shown in the list');
});
test('it navigates to show when clicking on the link', async function (assert) {

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
import backendsPage from 'vault/tests/pages/secrets/backends';
import authPage from 'vault/tests/pages/auth';
@@ -14,11 +16,12 @@ module('Acceptance | alicloud/enable', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('enable alicloud', async function (assert) {
const enginePath = `alicloud-${new Date().getTime()}`;
const enginePath = `alicloud-${this.uid}`;
await mountSecrets.visit();
await settled();
await mountSecrets.selectType('alicloud');

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret';
import showPage from 'vault/tests/pages/secrets/backend/kv/show';
import listPage from 'vault/tests/pages/secrets/backend/list';
@@ -16,6 +18,7 @@ module('Acceptance | secrets/cubbyhole/create', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
this.server = apiStub({ usePassthrough: true });
return authPage.login();
});
@@ -25,7 +28,7 @@ module('Acceptance | secrets/cubbyhole/create', function (hooks) {
});
test('it creates and can view a secret with the cubbyhole backend', async function (assert) {
const kvPath = `cubbyhole-kv-${new Date().getTime()}`;
const kvPath = `cubbyhole-kv-${this.uid}`;
await listPage.visitRoot({ backend: 'cubbyhole' });
await settled();
assert.strictEqual(

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
import backendsPage from 'vault/tests/pages/secrets/backends';
import authPage from 'vault/tests/pages/auth';
@@ -14,12 +16,13 @@ module('Acceptance | engine/disable', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('disable engine', async function (assert) {
// first mount an engine so we can disable it.
const enginePath = `alicloud-${new Date().getTime()}`;
const enginePath = `alicloud-disable-${this.uid}`;
await mountSecrets.enable('alicloud', enginePath);
await settled();
assert.ok(backendsPage.rows.filterBy('path', `${enginePath}/`)[0], 'shows the mounted engine');

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
import backendsPage from 'vault/tests/pages/secrets/backends';
import authPage from 'vault/tests/pages/auth';
@@ -14,12 +16,13 @@ module('Acceptance | gcpkms/enable', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('enable gcpkms', async function (assert) {
// Error: Cannot call `visit` without having first called `setupApplicationContext`.
const enginePath = `gcpkms-${new Date().getTime()}`;
const enginePath = `gcpkms-${this.uid}`;
await mountSecrets.visit();
await settled();
await mountSecrets.selectType('gcpkms');

View File

@@ -6,6 +6,8 @@
import { currentRouteName } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret';
import showPage from 'vault/tests/pages/secrets/backend/kv/show';
import listPage from 'vault/tests/pages/secrets/backend/list';
@@ -22,6 +24,7 @@ module('Acceptance | secrets/generic/create', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
this.server = apiStub({ usePassthrough: true });
return authPage.login();
});
@@ -31,8 +34,8 @@ module('Acceptance | secrets/generic/create', function (hooks) {
});
test('it creates and can view a secret with the generic backend', async function (assert) {
const path = `generic-${new Date().getTime()}`;
const kvPath = `generic-kv-${new Date().getTime()}`;
const path = `generic-${this.uid}`;
const kvPath = `generic-kv-${this.uid}`;
await cli.runCommands([`write sys/mounts/${path} type=generic`, `write ${path}/foo bar=baz`]);
await listPage.visitRoot({ backend: path });
assert.strictEqual(
@@ -53,8 +56,8 @@ module('Acceptance | secrets/generic/create', function (hooks) {
});
test('upgrading generic to version 2 lists all existing secrets, and CRUD continues to work', async function (assert) {
const path = `generic-${new Date().getTime()}`;
const kvPath = `generic-kv-${new Date().getTime()}`;
const path = `generic-${this.uid}`;
const kvPath = `generic-kv-${this.uid}`;
await cli.runCommands([
`write sys/mounts/${path} type=generic`,
`write ${path}/foo bar=baz`,

View File

@@ -16,6 +16,8 @@ import {
import { create } from 'ember-cli-page-object';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret';
import showPage from 'vault/tests/pages/secrets/backend/kv/show';
import listPage from 'vault/tests/pages/secrets/backend/list';
@@ -64,6 +66,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async function () {
this.uid = uuidv4();
this.server = apiStub({ usePassthrough: true });
return authPage.login();
});
@@ -73,7 +76,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it creates a secret and redirects', async function (assert) {
const secretPath = `kv-path-${new Date().getTime()}`;
const secretPath = `kv-path-${this.uid}`;
await listPage.visitRoot({ backend: 'secret' });
await settled();
assert.strictEqual(
@@ -99,7 +102,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it can create a secret when check-and-set is required', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'foo/bar';
await mountSecrets.visit();
await mountSecrets.enable('kv', enginePath);
@@ -114,7 +117,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it can create a secret with a non default max version and add metadata', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'maxVersions';
const maxVersions = 101;
await mountSecrets.visit();
@@ -150,7 +153,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it can handle validation on custom metadata', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'customMetadataValidations';
await mountSecrets.visit();
@@ -177,7 +180,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it can mount a KV 2 secret engine with config metadata', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const maxVersion = '101';
await mountSecrets.visit();
await click('[data-test-mount-type="kv"]');
@@ -216,7 +219,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it can create a secret and metadata can be created and edited', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'metadata';
const maxVersions = 101;
await mountSecrets.visit();
@@ -241,7 +244,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it disables save when validation errors occur', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'not-duplicate';
await mountSecrets.visit();
await mountSecrets.enable('kv', enginePath);
@@ -275,10 +278,8 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it navigates to version history and to a specific version', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = `specific-version`;
const today = new Date();
const month = today.toString().split(' ')[1];
await mountSecrets.visit();
await mountSecrets.enable('kv', enginePath);
await settled();
@@ -289,7 +290,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
await editPage.createSecret(secretPath, 'foo', 'bar');
await click('[data-test-popup-menu-trigger="version"]');
assert.dom('[ data-test-created-time]').includesText(month, 'created time shows todays month');
assert.dom('[ data-test-created-time]').includesText('Version created ', 'shows version created time');
await click('[data-test-version-history]');
@@ -309,7 +310,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('version 1 performs the correct capabilities lookup and does not show metadata tab', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'foo/bar';
// mount version 1 engine
await mountSecrets.visit();
@@ -329,7 +330,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
// https://github.com/hashicorp/vault/issues/5960
test('version 1: nested paths creation maintains ability to navigate the tree', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = '1/2/3/4';
// mount version 1 engine
await mountSecrets.visit();
@@ -380,7 +381,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('first level secrets redirect properly upon deletion', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-secret-${this.uid}`;
const secretPath = 'test';
// mount version 1 engine
await mountSecrets.visit();
@@ -408,7 +409,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('it redirects to the path ending in / for list pages', async function (assert) {
const secretPath = `foo/bar/kv-path-${new Date().getTime()}`;
const secretPath = `foo/bar/kv-path-${this.uid}`;
await listPage.visitRoot({ backend: 'secret' });
await listPage.create();
await editPage.createSecret(secretPath, 'foo', 'bar');
@@ -421,7 +422,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
test('it can edit via the JSON input', async function (assert) {
const content = JSON.stringify({ foo: 'fa', bar: 'boo' });
const secretPath = `kv-path-${new Date().getTime()}`;
const secretPath = `kv-path-${this.uid}`;
await listPage.visitRoot({ backend: 'secret' });
await listPage.create();
await editPage.path(secretPath).toggleJSON();
@@ -484,7 +485,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
});
test('create secret with space shows version data and shows space warning', async function (assert) {
const enginePath = `kv-${new Date().getTime()}`;
const enginePath = `kv-engine-${this.uid}`;
const secretPath = 'space space';
// mount version 2
await mountSecrets.visit();

View File

@@ -14,6 +14,7 @@ import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
import authPage from 'vault/tests/pages/auth';
import { SELECTORS } from 'vault/tests/helpers/pki';
import { csr } from 'vault/tests/helpers/pki/values';
import { v4 as uuidv4 } from 'uuid';
module('Acceptance | secrets/pki/list?tab=cert', function (hooks) {
setupApplicationTest(hooks);
@@ -27,7 +28,7 @@ module('Acceptance | secrets/pki/list?tab=cert', function (hooks) {
// mount, generate CA, nav to create role page
const setup = async (assert, action = 'issue') => {
const path = `pki-${new Date().getTime()}`;
const path = `pki-${uuidv4()}`;
const roleName = 'role';
await enablePage.enable('pki', path);
await settled();

View File

@@ -6,6 +6,8 @@
import { click, currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/secrets/backend/list';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -14,18 +16,19 @@ module('Acceptance | secrets/pki/list', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
const mountAndNav = async () => {
const path = `pki-${new Date().getTime()}`;
const mountAndNav = async (uid) => {
const path = `pki-${uid}`;
await enablePage.enable('pki', path);
await page.visitRoot({ backend: path });
};
test('it renders an empty list', async function (assert) {
assert.expect(5);
await mountAndNav(assert);
await mountAndNav(this.uid);
assert.strictEqual(
currentRouteName(),
'vault.cluster.secrets.backend.list-root',
@@ -40,7 +43,7 @@ module('Acceptance | secrets/pki/list', function (hooks) {
test('it navigates to the create page', async function (assert) {
assert.expect(1);
await mountAndNav(assert);
await mountAndNav(this.uid);
await page.create();
assert.strictEqual(
currentRouteName(),
@@ -51,7 +54,7 @@ module('Acceptance | secrets/pki/list', function (hooks) {
test('it navigates to the configure page', async function (assert) {
assert.expect(1);
await mountAndNav(assert);
await mountAndNav(this.uid);
await click('[data-test-configuration-tab]');
await page.configure();
await settled();

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled, visit, waitUntil } from '@ember/test-helpers';
import { module, test, skip } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role';
import showPage from 'vault/tests/pages/secrets/backend/pki/show';
import listPage from 'vault/tests/pages/secrets/backend/list';
@@ -16,11 +18,12 @@ module('Acceptance | secrets/pki/create', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
skip('it creates a role and redirects', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-create-${this.uid}`;
await enablePage.enable('pki', path);
await settled();
await editPage.visitRoot({ backend: path });
@@ -66,7 +69,7 @@ module('Acceptance | secrets/pki/create', function (hooks) {
});
test('it deletes a role', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-delete-${this.uid}`;
await enablePage.enable('pki', path);
await settled();
await editPage.visitRoot({ backend: path });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import editPage from 'vault/tests/pages/secrets/backend/ssh/edit-role';
import showPage from 'vault/tests/pages/secrets/backend/ssh/show';
import generatePage from 'vault/tests/pages/secrets/backend/ssh/generate-otp';
@@ -17,11 +19,12 @@ module('Acceptance | secrets/ssh', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
const mountAndNav = async () => {
const path = `ssh-${new Date().getTime()}`;
const mountAndNav = async (uid) => {
const path = `ssh-${uid}`;
await enablePage.enable('ssh', path);
await settled();
await editPage.visitRoot({ backend: path });
@@ -31,7 +34,7 @@ module('Acceptance | secrets/ssh', function (hooks) {
test('it creates a role and redirects', async function (assert) {
assert.expect(5);
const path = await mountAndNav(assert);
const path = await mountAndNav(this.uid);
await editPage.createOTPRole('role');
await settled();
assert.strictEqual(
@@ -61,7 +64,7 @@ module('Acceptance | secrets/ssh', function (hooks) {
test('it deletes a role', async function (assert) {
assert.expect(2);
const path = await mountAndNav(assert);
const path = await mountAndNav(this.uid);
await editPage.createOTPRole('role');
await settled();
await showPage.visit({ backend: path, id: 'role' });
@@ -78,7 +81,7 @@ module('Acceptance | secrets/ssh', function (hooks) {
test('it generates an OTP', async function (assert) {
assert.expect(6);
const path = await mountAndNav(assert);
const path = await mountAndNav(this.uid);
await editPage.createOTPRole('role');
await settled();
assert.strictEqual(

View File

@@ -6,6 +6,8 @@
import { currentURL, find, visit, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import backendListPage from 'vault/tests/pages/secrets/backends';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend';
import authPage from 'vault/tests/pages/auth';
@@ -15,6 +17,7 @@ module('Acceptance | settings', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
@@ -23,9 +26,8 @@ module('Acceptance | settings', function (hooks) {
});
test('settings', async function (assert) {
const now = new Date().getTime();
const type = 'consul';
const path = `path-${now}`;
const path = `settings-path-${this.uid}`;
// mount unsupported backend
await visit('/vault/settings/mount-secret-backend');

View File

@@ -6,6 +6,8 @@
import { currentURL, currentRouteName } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import enablePage from 'vault/tests/pages/settings/auth/enable';
import page from 'vault/tests/pages/settings/auth/configure/index';
import authPage from 'vault/tests/pages/auth';
@@ -14,11 +16,12 @@ module('Acceptance | settings/auth/configure', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it redirects to section options when there are no other sections', async function (assert) {
const path = `approle-${new Date().getTime()}`;
const path = `approle-config-${this.uid}`;
const type = 'approle';
await enablePage.enable(type, path);
await page.visit({ path });
@@ -31,7 +34,7 @@ module('Acceptance | settings/auth/configure', function (hooks) {
});
test('it redirects to the first section', async function (assert) {
const path = `aws-${new Date().getTime()}`;
const path = `aws-redirect-${this.uid}`;
const type = 'aws';
await enablePage.enable(type, path);
await page.visit({ path });

View File

@@ -7,6 +7,8 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { create } from 'ember-cli-page-object';
import { fillIn } from '@ember/test-helpers';
import { v4 as uuidv4 } from 'uuid';
import enablePage from 'vault/tests/pages/settings/auth/enable';
import page from 'vault/tests/pages/settings/auth/configure/section';
import indexPage from 'vault/tests/pages/settings/auth/configure/index';
@@ -20,6 +22,7 @@ module('Acceptance | settings/auth/configure/section', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
this.server = apiStub({ usePassthrough: true });
return authPage.login();
});
@@ -29,7 +32,7 @@ module('Acceptance | settings/auth/configure/section', function (hooks) {
});
test('it can save options', async function (assert) {
const path = `approle-${new Date().getTime()}`;
const path = `approle-save-${this.uid}`;
const type = 'approle';
const section = 'options';
await enablePage.enable(type, path);
@@ -59,7 +62,7 @@ module('Acceptance | settings/auth/configure/section', function (hooks) {
for (const type of ['aws', 'azure', 'gcp', 'github', 'kubernetes']) {
test(`it shows tabs for auth method: ${type}`, async function (assert) {
const path = `${type}-${Date.now()}`;
const path = `${type}-showtab-${this.uid}`;
await cli.consoleInput(`write sys/auth/${path} type=${type}`);
await cli.enter();
await indexPage.visit({ path });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/auth/enable';
import listPage from 'vault/tests/pages/access/methods';
import authPage from 'vault/tests/pages/auth';
@@ -14,12 +16,13 @@ module('Acceptance | settings/auth/enable', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it mounts and redirects', async function (assert) {
// always force the new mount to the top of the list
const path = `approle-${new Date().getTime()}`;
const path = `aaa-approle-${this.uid}`;
const type = 'approle';
await page.visit();
assert.strictEqual(currentRouteName(), 'vault.cluster.settings.auth.enable');

View File

@@ -6,6 +6,8 @@
import { click, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/index';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -21,11 +23,12 @@ module('Acceptance | settings/configure/secrets/ssh', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it configures ssh ca', async function (assert) {
const path = `ssh-${new Date().getTime()}`;
const path = `ssh-configure-${this.uid}`;
await enablePage.enable('ssh', path);
await settled();
await page.visit({ backend: path });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/index';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -14,11 +16,12 @@ module('Acceptance | settings/configure/secrets/pki', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it redirects to the cert section', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-cert-${this.uid}`;
await enablePage.enable('pki', path);
await settled();
await page.visit({ backend: path });

View File

@@ -10,6 +10,7 @@ import page from 'vault/tests/pages/settings/configure-secret-backends/pki/secti
import { SELECTORS } from 'vault/tests/helpers/pki';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
import { v4 as uuidv4 } from 'uuid';
module('Acceptance | settings/configure/secrets/pki/cert', function (hooks) {
setupApplicationTest(hooks);
@@ -67,7 +68,7 @@ BXUV2Uwtxf+QCphnlht9muX2fsLIzDJea0JipWj1uf2H8OZsjE8=
-----END RSA PRIVATE KEY-----`;
const mountAndNav = async (assert, prefix) => {
const path = `${prefix}pki-${new Date().getTime()}`;
const path = `${prefix}pki-${uuidv4()}`;
await enablePage.enable('pki', path);
await settled();
await page.visit({ backend: path });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -14,11 +16,12 @@ module('Acceptance | settings/configure/secrets/pki/crl', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it saves crl config', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-crl-${this.uid}`;
await enablePage.enable('pki', path);
await settled();
await page.visit({ backend: path, section: 'crl' });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -18,7 +20,7 @@ module('Acceptance | settings/configure/secrets/pki/tidy', function (hooks) {
});
test('it saves tidy config', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-tidy-${uuidv4()}`;
await enablePage.enable('pki', path);
await settled();
await page.visit({ backend: path, section: 'tidy' });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, settled, find, waitUntil } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -14,11 +16,12 @@ module('Acceptance | settings/configure/secrets/pki/urls', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it saves urls config', async function (assert) {
const path = `pki-${new Date().getTime()}`;
const path = `pki-config-urls-${this.uid}`;
await enablePage.enable('pki', path);
await settled();
await page.visit({ backend: path, section: 'urls' });

View File

@@ -6,6 +6,8 @@
import { currentRouteName, currentURL, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import { create } from 'ember-cli-page-object';
import page from 'vault/tests/pages/settings/mount-secret-backend';
import configPage from 'vault/tests/pages/secrets/backend/configuration';
@@ -21,12 +23,13 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
test('it sets the ttl correctly when mounting', async function (assert) {
// always force the new mount to the top of the list
const path = `kv-${new Date().getTime()}`;
const path = `mount-kv-${this.uid}`;
const defaultTTLHours = 100;
const maxTTLHours = 300;
const defaultTTLSeconds = (defaultTTLHours * 60 * 60).toString();
@@ -54,7 +57,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
test('it sets the ttl when enabled then disabled', async function (assert) {
// always force the new mount to the top of the list
const path = `kv-${new Date().getTime()}`;
const path = `mount-kv-${this.uid}`;
const maxTTLHours = 300;
const maxTTLSeconds = (maxTTLHours * 60 * 60).toString();
@@ -106,7 +109,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
});
test('version 2 with no update to config endpoint still allows mount of secret engine', async function (assert) {
const enginePath = `kv-noUpdate-${new Date().getTime()}`;
const enginePath = `kv-noUpdate-${this.uid}`;
const V2_POLICY = `
path "${enginePath}/*" {
capabilities = ["list","create","read","sudo","delete"]

View File

@@ -6,6 +6,8 @@
import { click, fillIn, findAll, currentURL, find, settled, waitUntil } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -13,6 +15,7 @@ module('Acceptance | ssh secret backend', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
this.uid = uuidv4();
return authPage.login();
});
@@ -81,8 +84,7 @@ module('Acceptance | ssh secret backend', function (hooks) {
];
test('ssh backend', async function (assert) {
assert.expect(28);
const now = new Date().getTime();
const sshPath = `ssh-${now}`;
const sshPath = `ssh-${this.uid}`;
await enablePage.enable('ssh', sshPath);
await settled();

View File

@@ -6,6 +6,8 @@
import { click, fillIn, find, currentURL, settled, visit, waitUntil, findAll } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
import { encodeString } from 'vault/utils/b64';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
@@ -287,21 +289,20 @@ const testConvergentEncryption = async function (assert, keyName) {
};
module('Acceptance | transit', function (hooks) {
setupApplicationTest(hooks);
let path;
let now;
hooks.beforeEach(async function () {
const uid = uuidv4();
await authPage.login();
await settled();
now = new Date().getTime();
path = `transit-${now}`;
this.uid = uid;
this.path = `transit-${uid}`;
await enablePage.enable('transit', path);
await enablePage.enable('transit', `transit-${uid}`);
await settled();
});
test(`transit backend: list menu`, async function (assert) {
await generateTransitKey(keyTypes[0], now);
await generateTransitKey(keyTypes[0], this.uid);
await secretListPage.secrets.objectAt(0).menuToggle();
await settled();
assert.strictEqual(secretListPage.menuItems.length, 2, 'shows 2 items in the menu');
@@ -309,8 +310,8 @@ module('Acceptance | transit', function (hooks) {
for (const key of keyTypes) {
test(`transit backend: ${key.type}`, async function (assert) {
assert.expect(key.convergent ? 43 : 7);
const name = await generateTransitKey(key, now);
await visit(`vault/secrets/${path}/show/${name}`);
const name = await generateTransitKey(key, this.uid);
await visit(`vault/secrets/${this.path}/show/${name}`);
const expectedRotateValue = key.autoRotate ? '30 days' : 'Key will not be automatically rotated';
assert
@@ -333,7 +334,7 @@ module('Acceptance | transit', function (hooks) {
await click('[data-test-transit-key-actions-link]');
assert.ok(
currentURL().startsWith(`/vault/secrets/${path}/show/${name}?tab=actions`),
currentURL().startsWith(`/vault/secrets/${this.path}/show/${name}?tab=actions`),
`${name}: navigates to transit actions`
);

View File

@@ -5,23 +5,22 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, findAll, find } from '@ember/test-helpers';
import { render, click } from '@ember/test-helpers';
import sinon from 'sinon';
import hbs from 'htmlbars-inline-precompile';
import calendarDropdown from 'vault/tests/pages/components/calendar-widget';
import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
import { subMonths, subYears } from 'date-fns';
import format from 'date-fns/format';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | calendar-widget', function (hooks) {
setupRenderingTest(hooks);
const isDisplayingSameYear = (comparisonDate, calendarYear) => {
return comparisonDate.getFullYear() === parseInt(calendarYear);
};
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
const CURRENT_DATE = new Date();
const CURRENT_DATE = timestamp.now();
this.set('currentDate', CURRENT_DATE);
this.set('calendarStartDate', subMonths(CURRENT_DATE, 12));
this.set('calendarEndDate', CURRENT_DATE);
@@ -29,6 +28,9 @@ module('Integration | Component | calendar-widget', function (hooks) {
this.set('endTimestamp', CURRENT_DATE.toISOString());
this.set('handleClientActivityQuery', sinon.spy());
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders and disables correct months when start date is 12 months ago', async function (assert) {
assert.expect(14);
@@ -40,40 +42,21 @@ module('Integration | Component | calendar-widget', function (hooks) {
/>
`);
assert.dom(calendarDropdown.dateRangeTrigger).hasText(
`${format(this.calendarStartDate, 'MMM yyyy')} -
${format(this.calendarEndDate, 'MMM yyyy')}`,
'renders and formats start and end dates'
);
assert
.dom(calendarDropdown.dateRangeTrigger)
.hasText(`Apr 2017 - Apr 2018`, 'renders and formats start and end dates');
await calendarDropdown.openCalendar();
assert.ok(calendarDropdown.showsCalendar, 'renders the calendar component');
// assert months in current year are disabled/enabled correctly
const monthButtons = findAll('[data-test-calendar-month]');
const enabledMonths = [],
disabledMonths = [];
for (let monthIdx = 0; monthIdx < 12; monthIdx++) {
if (monthIdx > this.calendarEndDate.getMonth()) {
disabledMonths.push(monthButtons[monthIdx]);
const enabledMonths = ['January', 'February', 'March', 'April'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (enabledMonths.includes(month)) {
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
} else {
enabledMonths.push(monthButtons[monthIdx]);
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
}
}
enabledMonths.forEach((btn) => {
assert
.dom(btn)
.doesNotHaveClass(
'is-readOnly',
`${ARRAY_OF_MONTHS[btn.id] + this.calendarEndDate.getFullYear()} is enabled`
);
});
disabledMonths.forEach((btn) => {
assert
.dom(btn)
.hasClass(
'is-readOnly',
`${ARRAY_OF_MONTHS[btn.id] + this.calendarEndDate.getFullYear()} is read only`
);
});
});
@@ -95,31 +78,15 @@ module('Integration | Component | calendar-widget', function (hooks) {
assert.dom('[data-test-previous-year]').isDisabled('disables previous year');
// assert months in previous year are disabled/enabled correctly
const monthButtons = findAll('[data-test-calendar-month]');
const enabledMonths = [],
disabledMonths = [];
for (let monthIdx = 0; monthIdx < 12; monthIdx++) {
if (monthIdx < this.calendarStartDate.getMonth()) {
disabledMonths.push(monthButtons[monthIdx]);
const disabledMonths = ['January', 'February', 'March'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (disabledMonths.includes(month)) {
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
} else {
enabledMonths.push(monthButtons[monthIdx]);
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
}
}
disabledMonths.forEach((btn) => {
assert
.dom(btn)
.hasClass(
'is-readOnly',
`${ARRAY_OF_MONTHS[btn.id] + this.calendarEndDate.getFullYear()} is read only`
);
});
enabledMonths.forEach((btn) => {
assert
.dom(btn)
.doesNotHaveClass(
'is-readOnly',
`${ARRAY_OF_MONTHS[btn.id] + this.calendarEndDate.getFullYear()} is enabled`
);
});
});
@@ -166,35 +133,35 @@ module('Integration | Component | calendar-widget', function (hooks) {
/>
`);
await calendarDropdown.openCalendar();
await click(`[data-test-calendar-month="${ARRAY_OF_MONTHS[this.calendarEndDate.getMonth()]}"]`);
await click(`[data-test-calendar-month="April"`);
assert.propEqual(
this.handleClientActivityQuery.lastCall.lastArg,
{
dateType: 'endDate',
monthIdx: this.currentDate.getMonth(),
monthName: ARRAY_OF_MONTHS[this.currentDate.getMonth()],
year: this.currentDate.getFullYear(),
monthIdx: 3,
monthName: 'April',
year: 2018,
},
'it calls parent function with end date (current) month/year'
);
await calendarDropdown.openCalendar();
await calendarDropdown.clickPreviousYear();
await click(`[data-test-calendar-month="${ARRAY_OF_MONTHS[this.calendarStartDate.getMonth()]}"]`);
await click(`[data-test-calendar-month="March"]`);
assert.propEqual(
this.handleClientActivityQuery.lastCall.lastArg,
{
dateType: 'endDate',
monthIdx: this.currentDate.getMonth(),
monthName: ARRAY_OF_MONTHS[this.currentDate.getMonth()],
year: this.currentDate.getFullYear() - 1,
monthIdx: 2,
monthName: 'March',
year: 2017,
},
'it calls parent function with start date month/year'
'it calls parent function with selected start date month/year'
);
});
test('it disables correct months when start date 6 months ago', async function (assert) {
this.set('calendarStartDate', subMonths(this.currentDate, 6));
this.set('calendarStartDate', subMonths(this.currentDate, 6)); // Nov 3, 2017
this.set('startTimestamp', subMonths(this.currentDate, 6).toISOString());
await render(hbs`
<CalendarWidget
@@ -207,52 +174,36 @@ module('Integration | Component | calendar-widget', function (hooks) {
await calendarDropdown.openCalendar();
assert.dom('[data-test-next-year]').isDisabled('Future year is disabled');
const displayYear = find('[data-test-display-year]').innerText;
const isRangeSameYear = isDisplayingSameYear(this.calendarStartDate, displayYear);
// only click previous year if 6 months ago was last year
if (!isRangeSameYear) {
await calendarDropdown.clickPreviousYear();
}
// Check start year disables correct months
await calendarDropdown.clickPreviousYear();
assert.dom('[data-test-previous-year]').isDisabled('previous year is disabled');
// DOM calendar is viewing start date year
findAll('[data-test-calendar-month]').forEach((m) => {
// months before start month should always be disabled
if (m.id < this.calendarStartDate.getMonth()) {
assert.dom(m).hasClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is read only`);
}
// if start/end dates are in the same year, DOM is also showing end date
if (isRangeSameYear) {
// months after end date should be disabled
if (m.id > this.calendarEndDate.getMonth()) {
assert.dom(m).hasClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is read only`);
}
// months between including start/end month should be enabled
if (m.id >= this.calendarStartDate.getMonth() && m.id <= this.calendarEndDate.getMonth()) {
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
}
const prevYearEnabled = ['October', 'November', 'December'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (prevYearEnabled.includes(month)) {
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
} else {
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
}
});
// click back to current year if duration spans multiple years
if (!isRangeSameYear) {
await click('[data-test-next-year]');
findAll('[data-test-calendar-month]').forEach((m) => {
// DOM is no longer showing start month, all months before current date should be enabled
if (m.id <= this.currentDate.getMonth()) {
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
}
// future months should be disabled
if (m.id > this.currentDate.getMonth()) {
assert.dom(m).hasClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is read only`);
}
});
}
// Check end year disables correct months
await click('[data-test-next-year]');
const currYearEnabled = ['January', 'February', 'March', 'April'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (currYearEnabled.includes(month)) {
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
} else {
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
}
});
});
test('it disables correct months when start date 36 months ago', async function (assert) {
this.set('calendarStartDate', subMonths(this.currentDate, 36));
this.set('calendarStartDate', subMonths(this.currentDate, 36)); // April 3 2015
this.set('startTimestamp', subMonths(this.currentDate, 36).toISOString());
await render(hbs`
<CalendarWidget
@@ -265,62 +216,43 @@ module('Integration | Component | calendar-widget', function (hooks) {
await calendarDropdown.openCalendar();
assert.dom('[data-test-next-year]').isDisabled('Future year is disabled');
let displayYear = find('[data-test-display-year]').innerText;
while (!isDisplayingSameYear(this.calendarStartDate, displayYear)) {
for (const year of [2017, 2016, 2015]) {
await calendarDropdown.clickPreviousYear();
displayYear = find('[data-test-display-year]').innerText;
assert.dom('[data-test-display-year]').hasText(year.toString());
}
assert.dom('[data-test-previous-year]').isDisabled('previous year is disabled');
assert.dom('[data-test-next-year]').isEnabled('next year is enabled');
// DOM calendar is viewing start date year (3 years ago)
findAll('[data-test-calendar-month]').forEach((m) => {
// months before start month should always be disabled
if (m.id < this.calendarStartDate.getMonth()) {
assert.dom(m).hasClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is read only`);
}
if (m.id >= this.calendarStartDate.getMonth()) {
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
assert.dom('.calendar-widget .is-readOnly').exists('Some months disabled');
const disabledMonths = ['January', 'February', 'March'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (disabledMonths.includes(month)) {
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
} else {
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
}
});
await click('[data-test-next-year]');
displayYear = await find('[data-test-display-year]').innerText;
if (!isDisplayingSameYear(this.currentDate, displayYear)) {
await findAll('[data-test-calendar-month]').forEach((m) => {
// years between should have all months enabled
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
});
}
assert.dom('.calendar-widget .is-readOnly').doesNotExist('All months enabled for 2016');
await click('[data-test-next-year]');
displayYear = await find('[data-test-display-year]').innerText;
if (!isDisplayingSameYear(this.currentDate, displayYear)) {
await findAll('[data-test-calendar-month]').forEach((m) => {
// years between should have all months enabled
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
});
}
assert.dom('.calendar-widget .is-readOnly').doesNotExist('All months enabled for 2017');
await click('[data-test-next-year]');
displayYear = await find('[data-test-display-year]').innerText;
// now DOM is showing current year
assert.dom('[data-test-next-year]').isDisabled('Future year is disabled');
if (isDisplayingSameYear(this.currentDate, displayYear)) {
findAll('[data-test-calendar-month]').forEach((m) => {
// all months before current month should be enabled
if (m.id <= this.currentDate.getMonth()) {
assert.dom(m).doesNotHaveClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is enabled`);
}
// future months should be disabled
if (m.id > this.currentDate.getMonth()) {
assert.dom(m).hasClass('is-readOnly', `${ARRAY_OF_MONTHS[m.id] + displayYear} is read only`);
}
});
}
assert.dom('.calendar-widget .is-readOnly').exists('Some months disabled for 2018');
const enabledMonths = ['January', 'February', 'March', 'April'];
ARRAY_OF_MONTHS.forEach(function (month) {
if (enabledMonths.includes(month)) {
assert
.dom(`[data-test-calendar-month="${month}"]`)
.doesNotHaveClass('is-readOnly', `${month} is enabled`);
} else {
assert.dom(`[data-test-calendar-month="${month}"]`).hasClass('is-readOnly', `${month} is read only`);
}
});
});
});

View File

@@ -4,19 +4,26 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { endOfMonth, formatRFC3339 } from 'date-fns';
import { click } from '@ember/test-helpers';
import subMonths from 'date-fns/subMonths';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | clients/attribution', function (hooks) {
setupRenderingTest(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.set('startTimestamp', formatRFC3339(subMonths(new Date(), 6)));
this.set('timestamp', formatRFC3339(new Date()));
const mockNow = timestamp.now();
this.mockNow = mockNow;
this.set('startTimestamp', formatRFC3339(subMonths(mockNow, 6)));
this.set('timestamp', formatRFC3339(mockNow));
this.set('selectedNamespace', null);
this.set('chartLegend', [
{ label: 'entity clients', key: 'entity_clients' },
@@ -33,6 +40,9 @@ module('Integration | Component | clients/attribution', function (hooks) {
{ label: 'auth2/', clients: 2, entity_clients: 1, non_entity_clients: 1 },
]);
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders empty state with no data', async function (assert) {
await render(hbs`
@@ -50,13 +60,13 @@ module('Integration | Component | clients/attribution', function (hooks) {
test('it renders with data for namespaces', async function (assert) {
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.startTimestamp}}
@endTimestamp={{this.timestamp}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.startTimestamp}}
@endTimestamp={{this.timestamp}}
@selectedNamespace={{this.selectedNamespace}}
@isHistoricalMonth={{false}}
/>
@@ -80,17 +90,17 @@ module('Integration | Component | clients/attribution', function (hooks) {
});
test('it renders two charts and correct text for single, historical month', async function (assert) {
this.start = formatRFC3339(subMonths(new Date(), 1));
this.end = formatRFC3339(subMonths(endOfMonth(new Date()), 1));
this.start = formatRFC3339(subMonths(this.mockNow, 1));
this.end = formatRFC3339(subMonths(endOfMonth(this.mockNow), 1));
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.start}}
@endTimestamp={{this.end}}
@endTimestamp={{this.end}}
@selectedNamespace={{this.selectedNamespace}}
@isHistoricalMonth={{true}}
/>
@@ -138,13 +148,13 @@ module('Integration | Component | clients/attribution', function (hooks) {
test('it renders single chart for current month', async function (assert) {
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.timestamp}}
@endTimestamp={{this.timestamp}}
@endTimestamp={{this.timestamp}}
@selectedNamespace={{this.selectedNamespace}}
@isHistoricalMonth={{false}}
/>
@@ -160,13 +170,13 @@ module('Integration | Component | clients/attribution', function (hooks) {
test('it renders single chart and correct text for for date range', async function (assert) {
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@totalClientAttribution={{this.totalClientAttribution}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.startTimestamp}}
@endTimestamp={{this.timestamp}}
@endTimestamp={{this.timestamp}}
@selectedNamespace={{this.selectedNamespace}}
@isHistoricalMonth={{false}}
/>
@@ -184,13 +194,13 @@ module('Integration | Component | clients/attribution', function (hooks) {
this.set('selectedNamespace', 'second');
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.namespaceMountsData}}
@totalUsageCounts={{this.totalUsageCounts}}
@totalClientAttribution={{this.namespaceMountsData}}
@totalUsageCounts={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@startTimestamp={{this.startTimestamp}}
@endTimestamp={{this.timestamp}}
@endTimestamp={{this.timestamp}}
@selectedNamespace={{this.selectedNamespace}}
@isHistoricalMonth={{this.isHistoricalMonth}}
/>
@@ -216,9 +226,9 @@ module('Integration | Component | clients/attribution', function (hooks) {
test('it renders modal', async function (assert) {
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::Attribution
<Clients::Attribution
@chartLegend={{this.chartLegend}}
@totalClientAttribution={{this.namespaceMountsData}}
@totalClientAttribution={{this.namespaceMountsData}}
@responseTimestamp={{this.timestamp}}
@startTimestamp="2022-06-01T23:00:11.050Z"
@endTimestamp="2022-12-01T23:00:11.050Z"

View File

@@ -4,14 +4,19 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { find, render, findAll, triggerEvent } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { format, formatRFC3339, subMonths } from 'date-fns';
import { formatChartDate } from 'core/utils/date-formatters';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | clients/line-chart', function (hooks) {
setupRenderingTest(hooks);
const CURRENT_DATE = new Date();
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.set('xKey', 'foo');
this.set('yKey', 'bar');
@@ -34,6 +39,9 @@ module('Integration | Component | clients/line-chart', function (hooks) {
},
]);
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders', async function (assert) {
await render(hbs`
@@ -56,21 +64,22 @@ module('Integration | Component | clients/line-chart', function (hooks) {
});
test('it renders upgrade data', async function (assert) {
const now = timestamp.now();
this.set('dataset', [
{
foo: format(subMonths(CURRENT_DATE, 4), 'M/yy'),
foo: format(subMonths(now, 4), 'M/yy'),
bar: 4,
},
{
foo: format(subMonths(CURRENT_DATE, 3), 'M/yy'),
foo: format(subMonths(now, 3), 'M/yy'),
bar: 8,
},
{
foo: format(subMonths(CURRENT_DATE, 2), 'M/yy'),
foo: format(subMonths(now, 2), 'M/yy'),
bar: 14,
},
{
foo: format(subMonths(CURRENT_DATE, 1), 'M/yy'),
foo: format(subMonths(now, 1), 'M/yy'),
bar: 10,
},
]);
@@ -78,16 +87,16 @@ module('Integration | Component | clients/line-chart', function (hooks) {
{
id: '1.10.1',
previousVersion: '1.9.2',
timestampInstalled: formatRFC3339(subMonths(CURRENT_DATE, 2)),
timestampInstalled: formatRFC3339(subMonths(now, 2)),
},
]);
await render(hbs`
<div class="chart-container-wide">
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
/>
</div>
`);
@@ -101,30 +110,31 @@ module('Integration | Component | clients/line-chart', function (hooks) {
});
test('it renders tooltip', async function (assert) {
const now = timestamp.now();
const tooltipData = [
{
month: format(subMonths(CURRENT_DATE, 4), 'M/yy'),
month: format(subMonths(now, 4), 'M/yy'),
clients: 4,
new_clients: {
clients: 0,
},
},
{
month: format(subMonths(CURRENT_DATE, 3), 'M/yy'),
month: format(subMonths(now, 3), 'M/yy'),
clients: 8,
new_clients: {
clients: 4,
},
},
{
month: format(subMonths(CURRENT_DATE, 2), 'M/yy'),
month: format(subMonths(now, 2), 'M/yy'),
clients: 14,
new_clients: {
clients: 6,
},
},
{
month: format(subMonths(CURRENT_DATE, 1), 'M/yy'),
month: format(subMonths(now, 1), 'M/yy'),
clients: 20,
new_clients: {
clients: 4,
@@ -136,13 +146,13 @@ module('Integration | Component | clients/line-chart', function (hooks) {
{
id: '1.10.1',
previousVersion: '1.9.2',
timestampInstalled: formatRFC3339(subMonths(CURRENT_DATE, 2)),
timestampInstalled: formatRFC3339(subMonths(now, 2)),
},
]);
await render(hbs`
<div class="chart-container-wide">
<Clients::LineChart
@dataset={{this.dataset}}
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
/>
</div>
@@ -166,11 +176,11 @@ module('Integration | Component | clients/line-chart', function (hooks) {
this.set('upgradeData', { some: 'object' });
await render(hbs`
<div class="chart-container-wide">
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
/>
</div>
`);
@@ -184,11 +194,11 @@ module('Integration | Component | clients/line-chart', function (hooks) {
this.set('upgradeData', [{ incorrect: 'key names' }]);
await render(hbs`
<div class="chart-container-wide">
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
<Clients::LineChart
@dataset={{this.dataset}}
@upgradeData={{this.upgradeData}}
@xKey={{this.xKey}}
@yKey={{this.yKey}}
/>
</div>
`);

View File

@@ -4,6 +4,7 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
@@ -11,6 +12,7 @@ import { formatRFC3339 } from 'date-fns';
import { findAll } from '@ember/test-helpers';
import { calculateAverage } from 'vault/utils/chart-helpers';
import { formatNumber } from 'core/helpers/format-number';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | clients/monthly-usage', function (hooks) {
setupRenderingTest(hooks);
@@ -1413,8 +1415,11 @@ module('Integration | Component | clients/monthly-usage', function (hooks) {
},
},
];
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.set('timestamp', formatRFC3339(new Date()));
this.set('timestamp', formatRFC3339(timestamp.now()));
this.set('isDateRange', true);
this.set('chartLegend', [
{ label: 'entity clients', key: 'entity_clients' },
@@ -1422,6 +1427,9 @@ module('Integration | Component | clients/monthly-usage', function (hooks) {
]);
this.set('byMonthActivityData', DATASET);
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders empty state with no data', async function (assert) {
await render(hbs`
@@ -1448,9 +1456,9 @@ module('Integration | Component | clients/monthly-usage', function (hooks) {
]);
await render(hbs`
<div id="modal-wormhole"></div>
<Clients::MonthlyUsage
<Clients::MonthlyUsage
@chartLegend={{this.chartLegend}}
@verticalBarChartData={{this.byMonthActivityData}}
@verticalBarChartData={{this.byMonthActivityData}}
@responseTimestamp={{this.timestamp}}
/>
`);

View File

@@ -4,6 +4,7 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
@@ -11,6 +12,7 @@ import { formatRFC3339 } from 'date-fns';
import { findAll } from '@ember/test-helpers';
import { calculateAverage } from 'vault/utils/chart-helpers';
import { formatNumber } from 'core/helpers/format-number';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | clients/running-total', function (hooks) {
setupRenderingTest(hooks);
@@ -1419,13 +1421,19 @@ module('Integration | Component | clients/running-total', function (hooks) {
entity_clients: 20818,
non_entity_clients: 17850,
};
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.set('timestamp', formatRFC3339(new Date()));
this.set('timestamp', formatRFC3339(timestamp.now()));
this.set('chartLegend', [
{ label: 'entity clients', key: 'entity_clients' },
{ label: 'non-entity clients', key: 'non_entity_clients' },
]);
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders with full monthly activity data', async function (assert) {
this.set('byMonthActivityData', MONTHLY_ACTIVITY);
@@ -1444,7 +1452,7 @@ module('Integration | Component | clients/running-total', function (hooks) {
@runningTotals={{this.totalUsageCounts}}
@upgradeData={{this.upgradeDuringActivity}}
@responseTimestamp={{this.timestamp}}
@isHistoricalMonth={{false}}
@isHistoricalMonth={{false}}
/>
`);
@@ -1514,7 +1522,7 @@ module('Integration | Component | clients/running-total', function (hooks) {
@byMonthActivityData={{this.byMonthActivityData}}
@runningTotals={{this.totalUsageCounts}}
@responseTimestamp={{this.timestamp}}
@isHistoricalMonth={{false}}
@isHistoricalMonth={{false}}
/>
`);
assert.dom('[data-test-running-total]').exists('running total component renders');

View File

@@ -4,18 +4,32 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { click, find, findAll, render } from '@ember/test-helpers';
import { click, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
import timestamp from 'core/utils/timestamp';
const SELECTORS = {
monthDropdown: '[data-test-popup-menu-trigger="month"]',
specificMonth: (m) => `[data-test-dropdown-month="${m}"]`,
yearDropdown: '[data-test-popup-menu-trigger="year"]',
specificYear: (y) => `[data-test-dropdown-year="${y}"]`,
submitButton: '[data-test-date-dropdown-submit]',
cancelButton: '[data-test-date-dropdown-cancel]',
monthOptions: '[data-test-month-list] button',
};
module('Integration | Component | date-dropdown', function (hooks) {
setupRenderingTest(hooks);
hooks.before(function () {
const currentDate = new Date();
this.currentYear = currentDate.getFullYear(); // integer of year
this.currentMonth = currentDate.getMonth(); // index of month
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.after(function () {
timestamp.now.restore();
});
test('it renders dropdown', async function (assert) {
@@ -24,10 +38,8 @@ module('Integration | Component | date-dropdown', function (hooks) {
<DateDropdown/>
</div>
`);
assert.dom('[data-test-date-dropdown-submit]').hasText('Submit', 'button renders default text');
assert
.dom('[data-test-date-dropdown-cancel]')
.doesNotExist('it does not render cancel button by default');
assert.dom(SELECTORS.submitButton).hasText('Submit', 'button renders default text');
assert.dom(SELECTORS.cancelButton).doesNotExist('it does not render cancel button by default');
});
test('it fires off cancel callback', async function (assert) {
@@ -41,8 +53,8 @@ module('Integration | Component | date-dropdown', function (hooks) {
<DateDropdown @handleCancel={{this.onCancel}} @submitText="Save"/>
</div>
`);
assert.dom('[data-test-date-dropdown-submit]').hasText('Save', 'button renders passed in text');
await click(find('[data-test-date-dropdown-cancel]'));
assert.dom(SELECTORS.submitButton).hasText('Save', 'button renders passed in text');
await click(SELECTORS.cancelButton);
});
test('it renders dropdown and selects month and year', async function (assert) {
@@ -52,9 +64,9 @@ module('Integration | Component | date-dropdown', function (hooks) {
args,
{
dateType: 'start',
monthIdx: 0,
monthName: 'January',
year: this.currentYear,
monthIdx: 1,
monthName: 'February',
year: 2016,
},
'sends correct args to parent'
);
@@ -63,98 +75,74 @@ module('Integration | Component | date-dropdown', function (hooks) {
await render(hbs`
<div class="is-flex-align-baseline">
<DateDropdown
@handleSubmit={{this.parentAction}}
<DateDropdown
@handleSubmit={{this.parentAction}}
@dateType="start"
/>
</div>
`);
assert.dom(SELECTORS.submitButton).isDisabled('button is disabled when no month or year selected');
const monthDropdown = find('[data-test-popup-menu-trigger="month"]');
const yearDropdown = find('[data-test-popup-menu-trigger="year"]');
const submitButton = find('[data-test-date-dropdown-submit]');
await click(SELECTORS.monthDropdown);
assert.true(submitButton.disabled, 'button is disabled when no month or year selected');
assert.dom(SELECTORS.monthOptions).exists({ count: 12 }, 'dropdown has 12 months');
ARRAY_OF_MONTHS.forEach((month) => {
assert.dom(SELECTORS.specificMonth(month)).hasText(`${month}`, `dropdown includes ${month}`);
});
await click(monthDropdown);
const dropdownListMonths = findAll('[data-test-month-list] button');
assert.strictEqual(dropdownListMonths.length, 12, 'dropdown has 12 months');
for (const [index, month] of ARRAY_OF_MONTHS.entries()) {
assert.dom(dropdownListMonths[index]).hasText(`${month}`, `dropdown includes ${month}`);
}
await click(dropdownListMonths[0]);
assert.dom(monthDropdown).hasText('January', 'dropdown selects January');
await click(SELECTORS.specificMonth('February'));
assert.dom(SELECTORS.monthDropdown).hasText('February', 'dropdown shows selected month');
assert.dom('.ember-basic-dropdown-content').doesNotExist('dropdown closes after selecting month');
await click(yearDropdown);
const dropdownListYears = findAll('[data-test-year-list] button');
assert.strictEqual(dropdownListYears.length, 5, 'dropdown has 5 years');
await click(SELECTORS.yearDropdown);
for (const [index, year] of dropdownListYears.entries()) {
const comparisonYear = this.currentYear - index;
assert.dom(year).hasText(`${comparisonYear}`, `dropdown includes ${comparisonYear}`);
assert.dom('[data-test-dropdown-year]').exists({ count: 5 }, 'dropdown has 5 years');
for (const year of [2018, 2017, 2016, 2015, 2014]) {
assert.dom(SELECTORS.specificYear(year)).exists();
}
await click(dropdownListYears[0]);
assert.dom(yearDropdown).hasText(`${this.currentYear}`, `dropdown selects ${this.currentYear}`);
await click('[data-test-dropdown-year="2016"]');
assert.dom(SELECTORS.yearDropdown).hasText(`2016`, `dropdown shows selected year`);
assert.dom('.ember-basic-dropdown-content').doesNotExist('dropdown closes after selecting year');
assert.false(submitButton.disabled, 'button enabled when month and year selected');
assert.dom(SELECTORS.submitButton).isNotDisabled('button enabled when month and year selected');
await click(submitButton);
await click(SELECTORS.submitButton);
});
test('selecting month first: it enables current year when selecting valid months', async function (assert) {
// the date dropdown displays 5 years, multiply by month to calculate how many assertions to expect
const datesEnabled = (this.currentMonth + 1) * 5;
assert.expect(datesEnabled);
test('selecting month first: current year enabled when current month selected', async function (assert) {
assert.expect(5);
await render(hbs`
<div class="is-flex-align-baseline">
<DateDropdown/>
</div>
`);
const monthDropdown = find('[data-test-popup-menu-trigger="month"]');
const yearDropdown = find('[data-test-popup-menu-trigger="year"]');
// select months before or equal to current month and assert year is enabled
for (let monthIdx = 0; monthIdx < this.currentMonth + 1; monthIdx++) {
await click(monthDropdown);
const dropdownListMonths = findAll('[data-test-month-list] button');
await click(dropdownListMonths[monthIdx]);
await click(yearDropdown);
const dropdownListYears = findAll('[data-test-year-list] button');
for (const year of dropdownListYears) {
assert.false(year.disabled, `${ARRAY_OF_MONTHS[monthIdx]} ${year.innerText} enabled`);
}
await click(yearDropdown);
// select current month
await click(SELECTORS.monthDropdown);
await click(SELECTORS.specificMonth('January'));
await click(SELECTORS.yearDropdown);
// all years should be selectable
for (const year of [2018, 2017, 2016, 2015, 2014]) {
assert.dom(SELECTORS.specificYear(year)).isNotDisabled(`year ${year} is selectable`);
}
});
test('selecting month first: it disables current year when selecting future months', async function (assert) {
// assertions only run for future months
const yearsDisabled = 11 - this.currentMonth; // ex: in December, current year is enabled for all months, so 0 assertions will run
assert.expect(yearsDisabled);
test('selecting month first: it disables current year when future months selected', async function (assert) {
assert.expect(5);
await render(hbs`
<div class="is-flex-align-baseline">
<DateDropdown/>
</div>
`);
const monthDropdown = find('[data-test-popup-menu-trigger="month"]');
const yearDropdown = find('[data-test-popup-menu-trigger="year"]');
// select future month
await click(SELECTORS.monthDropdown);
await click(SELECTORS.specificMonth('June'));
await click(SELECTORS.yearDropdown);
// select future months and assert current year is disabled
for (let monthIdx = this.currentMonth + 1; monthIdx < 12; monthIdx++) {
await click(monthDropdown);
const dropdownListMonths = findAll('[data-test-month-list] button');
await click(dropdownListMonths[monthIdx]);
await click(yearDropdown);
const dropdownListYears = findAll('[data-test-year-list] button');
const currentYear = dropdownListYears[0];
assert.true(currentYear.disabled, `${ARRAY_OF_MONTHS[monthIdx]} ${currentYear.innerText} disabled`);
await click(yearDropdown);
assert.dom(SELECTORS.specificYear(2018)).isDisabled(`current year is disabled`);
// previous years should be selectable
for (const year of [2017, 2016, 2015, 2014]) {
assert.dom(SELECTORS.specificYear(year)).isNotDisabled(`year ${year} is selectable`);
}
});
@@ -165,47 +153,34 @@ module('Integration | Component | date-dropdown', function (hooks) {
<DateDropdown/>
</div>
`);
const monthDropdown = find('[data-test-popup-menu-trigger="month"]');
const yearDropdown = find('[data-test-popup-menu-trigger="year"]');
await click(yearDropdown);
await click(`[data-test-dropdown-year="${this.currentYear}"]`);
await click(monthDropdown);
const dropdownListMonths = findAll('[data-test-month-list] button');
const enabledMonths = dropdownListMonths.slice(0, this.currentMonth + 1);
const disabledMonths = dropdownListMonths.slice(this.currentMonth + 1);
for (const [monthIndex, month] of enabledMonths.entries()) {
assert.false(month.disabled, `${ARRAY_OF_MONTHS[monthIndex]} ${this.currentYear} enabled`);
}
for (const [monthIndex, month] of disabledMonths.entries()) {
assert.true(month.disabled, `${ARRAY_OF_MONTHS[monthIndex]} ${this.currentYear} disabled`);
}
await click(SELECTORS.yearDropdown);
await click(SELECTORS.specificYear(2018));
await click(SELECTORS.monthDropdown);
const expectedSelectable = ['January', 'February', 'March', 'April'];
ARRAY_OF_MONTHS.forEach((month) => {
if (expectedSelectable.includes(month)) {
assert.dom(SELECTORS.specificMonth(month)).isNotDisabled(`${month} is selectable for current year`);
} else {
assert.dom(SELECTORS.specificMonth(month)).isDisabled(`${month} is disabled for current year`);
}
});
});
test('selecting year first: it enables all months when past year is selected', async function (assert) {
assert.expect(48);
assert.expect(12);
await render(hbs`
<div class="is-flex-align-baseline">
<DateDropdown/>
</div>
`);
const monthDropdown = find('[data-test-popup-menu-trigger="month"]');
const yearDropdown = find('[data-test-popup-menu-trigger="year"]');
await click(SELECTORS.yearDropdown);
await click(SELECTORS.specificYear(2017));
await click(SELECTORS.monthDropdown);
// start at 1 because current year (index=0) is accounted for in previous test
for (let yearIdx = 1; yearIdx < 5; yearIdx++) {
await click(yearDropdown);
const dropdownListYears = findAll('[data-test-year-list] button');
await click(dropdownListYears[yearIdx]);
await click(monthDropdown);
const dropdownListMonths = findAll('[data-test-month-list] button');
for (const [monthIndex, month] of dropdownListMonths.entries()) {
assert.false(
month.disabled,
`${ARRAY_OF_MONTHS[monthIndex]} ${dropdownListYears[yearIdx].innerText.trim()} enabled`
);
}
await click(monthDropdown);
}
ARRAY_OF_MONTHS.forEach((month) => {
assert.dom(SELECTORS.specificMonth(month)).isNotDisabled(`${month} is selectable for previous year`);
});
});
});

View File

@@ -259,15 +259,14 @@ module('Integration | Component | InfoTableRow', function (hooks) {
});
test('Formats the value as date when formatDate present', async function (assert) {
const yearString = new Date().getFullYear().toString();
this.set('value', new Date());
this.set('value', new Date('2018-04-03T14:15:30'));
await render(hbs`<InfoTableRow
@label={{this.label}}
@value={{this.value}}
@formatDate={{'yyyy'}}
/>`);
assert.dom('[data-test-value-div]').hasText(yearString, 'Renders date with passed format');
assert.dom('[data-test-value-div]').hasText('2018', 'Renders date with passed format');
});
test('Formats the value as TTL when formatTtl present', async function (assert) {

View File

@@ -4,16 +4,21 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import EmberObject from '@ember/object';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | keymgmt/key-edit', function (hooks) {
setupRenderingTest(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
const now = new Date().toString();
const now = timestamp.now();
const model = EmberObject.create({
name: 'Unicorns',
id: 'Unicorns',
@@ -21,11 +26,11 @@ module('Integration | Component | keymgmt/key-edit', function (hooks) {
versions: [
{
id: 1,
creation_time: now,
creation_time: now.toString(),
},
{
id: 2,
creation_time: now,
creation_time: now.toString(),
},
],
canDelete: true,
@@ -33,6 +38,9 @@ module('Integration | Component | keymgmt/key-edit', function (hooks) {
this.model = model;
this.tab = '';
});
hooks.after(function () {
timestamp.now.restore();
});
// TODO: Add capabilities tests
test('it renders show view as default', async function (assert) {

View File

@@ -4,18 +4,23 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { setupEngine } from 'ember-engines/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { render, click, fillIn } from '@ember/test-helpers';
import { Response } from 'miragejs';
import hbs from 'htmlbars-inline-precompile';
import timestamp from 'core/utils/timestamp';
module('Integration | Component | kubernetes | Page::Credentials', function (hooks) {
setupRenderingTest(hooks);
setupEngine(hooks, 'kubernetes');
setupMirage(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
this.backend = 'kubernetes-test';
this.roleName = 'role-0';
@@ -48,6 +53,9 @@ module('Integration | Component | kubernetes | Page::Credentials', function (hoo
);
};
});
hooks.after(function () {
timestamp.now.restore();
});
test('it should display generate credentials form', async function (assert) {
await this.renderComponent();
@@ -129,7 +137,7 @@ module('Integration | Component | kubernetes | Page::Credentials', function (hoo
assert.dom('[data-test-value-div="Service account name"]').exists();
assert.dom('[data-test-row-label="Lease expiry"]').hasText('Lease expiry');
assert.dom('[data-test-value-div="Lease expiry"]').exists();
assert.dom('[data-test-value-div="Lease expiry"]').hasText('April 3rd 2018, 3:15:30 PM');
assert.dom('[data-test-row-label="lease_id"]').hasText('lease_id');
assert
.dom('[data-test-value-div="lease_id"] [data-test-row-value="lease_id"]')

View File

@@ -4,23 +4,33 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render, click } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import subDays from 'date-fns/subDays';
import addDays from 'date-fns/addDays';
import formatRFC3339 from 'date-fns/formatRFC3339';
const YESTERDAY = subDays(new Date(), 1);
const NEXT_MONTH = addDays(new Date(), 30);
import timestamp from 'core/utils/timestamp';
module('Integration | Component | license-banners', function (hooks) {
setupRenderingTest(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.beforeEach(function () {
const mockNow = timestamp.now();
this.now = mockNow;
this.yesterday = subDays(mockNow, 1);
this.nextMonth = addDays(mockNow, 30);
this.outside30 = addDays(mockNow, 32);
this.version = this.owner.lookup('service:version');
this.version.version = '1.13.1+ent';
});
hooks.after(function () {
timestamp.now.restore();
});
test('it does not render if no expiry', async function (assert) {
assert.expect(1);
@@ -30,7 +40,7 @@ module('Integration | Component | license-banners', function (hooks) {
test('it renders an error if expiry is before now', async function (assert) {
assert.expect(2);
this.set('expiry', formatRFC3339(YESTERDAY));
this.set('expiry', formatRFC3339(this.yesterday));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
assert.dom('[data-test-license-banner-expired]').exists('Expired license banner renders');
assert.dom('.message-title').hasText('License expired', 'Shows correct title on alert');
@@ -38,7 +48,7 @@ module('Integration | Component | license-banners', function (hooks) {
test('it renders a warning if expiry is within 30 days', async function (assert) {
assert.expect(2);
this.set('expiry', formatRFC3339(NEXT_MONTH));
this.set('expiry', formatRFC3339(this.nextMonth));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
assert.dom('[data-test-license-banner-warning]').exists('Warning license banner renders');
assert.dom('.message-title').hasText('Vault license expiring', 'Shows correct title on alert');
@@ -46,15 +56,14 @@ module('Integration | Component | license-banners', function (hooks) {
test('it does not render a banner if expiry is outside 30 days', async function (assert) {
assert.expect(1);
const outside30 = addDays(new Date(), 32);
this.set('expiry', formatRFC3339(outside30));
this.set('expiry', formatRFC3339(this.outside30));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
assert.dom('[data-test-license-banner]').doesNotExist('License banner does not render');
});
test('it does not render the expired banner if it has been dismissed', async function (assert) {
assert.expect(3);
this.set('expiry', formatRFC3339(YESTERDAY));
this.set('expiry', formatRFC3339(this.yesterday));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
await click('[data-test-dismiss-expired]');
assert.dom('[data-test-license-banner-expired]').doesNotExist('Expired license banner does not render');
@@ -70,7 +79,7 @@ module('Integration | Component | license-banners', function (hooks) {
test('it does not render the warning banner if it has been dismissed', async function (assert) {
assert.expect(3);
this.set('expiry', formatRFC3339(NEXT_MONTH));
this.set('expiry', formatRFC3339(this.nextMonth));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
await click('[data-test-dismiss-warning]');
assert.dom('[data-test-license-banner-warning]').doesNotExist('Warning license banner does not render');
@@ -87,7 +96,7 @@ module('Integration | Component | license-banners', function (hooks) {
test('it renders a banner if the vault license has changed', async function (assert) {
assert.expect(3);
this.version.version = '1.12.1+ent';
this.set('expiry', formatRFC3339(NEXT_MONTH));
this.set('expiry', formatRFC3339(this.nextMonth));
await render(hbs`<LicenseBanners @expiry={{this.expiry}} />`);
await click('[data-test-dismiss-warning]');
this.version.version = '1.13.1+ent';

View File

@@ -198,12 +198,10 @@ module('Integration | Component | mfa-form', function (hooks) {
await fillIn('[data-test-mfa-passcode]', code);
later(() => cancelTimers(), 50);
await click('[data-test-mfa-validate]');
const expectedTime = code === 'used' ? '45' : '15';
assert
.dom('[data-test-mfa-countdown]')
.hasText(
code === 'used' ? '45' : '15',
'countdown renders with correct initial value from error response'
);
.includesText(expectedTime, 'countdown renders with correct initial value from error response');
assert.dom('[data-test-mfa-validate]').isDisabled('Button is disabled during countdown');
assert.dom('[data-test-mfa-passcode]').isDisabled('Input is disabled during countdown');
assert.dom('[data-test-inline-error-message]').exists('Alert message renders');

View File

@@ -4,33 +4,41 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { format } from 'date-fns';
import { find, render, settled } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import timestamp from 'core/utils/timestamp';
module('Integration | Helper | date-format', function (hooks) {
setupRenderingTest(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2018-04-03T14:15:30'));
});
hooks.after(function () {
timestamp.now.restore();
});
test('it is able to format a date object', async function (assert) {
const today = new Date();
const today = timestamp.now();
this.set('today', today);
await render(hbs`{{date-format this.today "yyyy"}}`);
assert.dom(this.element).includesText(today.getFullYear(), 'it renders the date in the year format');
assert.dom(this.element).includesText('2018', 'it renders the date in the year format');
});
test('it supports date timestamps', async function (assert) {
const today = new Date().getTime();
const today = timestamp.now().getTime();
this.set('today', today);
await render(hbs`{{date-format this.today 'hh:mm:ss'}}`);
const formattedDate = this.element.innerText;
assert.ok(formattedDate.match(/^\d{2}:\d{2}:\d{2}$/));
assert.strictEqual(formattedDate, '02:15:30');
});
test('it supports date strings', async function (assert) {
const todayString = new Date().getFullYear().toString();
const todayString = timestamp.now().getFullYear().toString();
this.set('todayString', todayString);
await render(hbs`{{date-format this.todayString "yyyy"}}`);
@@ -46,19 +54,26 @@ module('Integration | Helper | date-format', function (hooks) {
});
test('it supports already formatted dates', async function (assert) {
const formattedDate = new Date();
const formattedDate = timestamp.now();
this.set('formattedDate', formattedDate);
await render(hbs`{{date-format this.formattedDate 'MMMM dd, yyyy hh:mm:ss a' isFormatted=true}}`);
assert.dom(this.element).includesText(format(formattedDate, 'MMMM dd, yyyy hh:mm:ss a'));
assert.dom(this.element).hasText('April 03, 2018 02:15:30 PM');
});
test('displays time zone if withTimeZone=true', async function (assert) {
const timestampDate = '2022-12-06T11:29:15-08:00';
const zone = new Date().toLocaleTimeString(undefined, { timeZoneName: 'short' }).split(' ')[2];
this.set('withTimezone', false);
this.set('timestampDate', timestampDate);
await render(hbs`{{date-format this.timestampDate 'MMM d yyyy, h:mm:ss aaa' withTimeZone=true}}`);
assert.dom(this.element).hasTextContaining(`${zone}`);
await render(
hbs`<span data-test-formatted>{{date-format this.timestampDate 'MMM d yyyy, h:mm:ss aaa' withTimeZone=this.withTimezone}}</span>`
);
const result = find('[data-test-formatted]');
assert.strictEqual(result.innerText.length, 22);
// Compare to with timezone, which should add 4 characters
this.set('withTimezone', true);
await settled();
assert.strictEqual(result.innerText.length, 26);
});
});

View File

@@ -5,19 +5,22 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { format, formatRFC3339, isSameDay, isSameMonth, isSameYear } from 'date-fns';
import { formatRFC3339, isSameDay, isSameMonth, isSameYear } from 'date-fns';
import { parseAPITimestamp, formatChartDate } from 'core/utils/date-formatters';
module('Integration | Util | date formatters utils', function (hooks) {
setupTest(hooks);
const DATE = new Date();
const API_TIMESTAMP = formatRFC3339(DATE).split('T')[0].concat('T00:00:00Z');
const UNIX_TIME = DATE.getTime();
test('parseAPITimestamp: parses API timestamp string irrespective of timezone', async function (assert) {
assert.expect(6);
assert.strictEqual(parseAPITimestamp(UNIX_TIME), undefined, 'it returns if timestamp is not a string');
const DATE = new Date('2012-06-10T15:30:45');
const API_TIMESTAMP = formatRFC3339(DATE).split('T')[0].concat('T00:00:00Z');
const UNIX_TIME = DATE.getTime();
assert.strictEqual(
parseAPITimestamp(UNIX_TIME),
undefined,
'it returns undefined if timestamp is not a string'
);
const parsedTimestamp = parseAPITimestamp(API_TIMESTAMP);
@@ -27,7 +30,7 @@ module('Integration | Util | date formatters utils', function (hooks) {
assert.true(isSameDay(parsedTimestamp, DATE), 'parsed timestamp is correct day');
const formattedTimestamp = parseAPITimestamp(API_TIMESTAMP, 'MM yyyy');
assert.strictEqual(formattedTimestamp, format(DATE, 'MM yyyy'), 'it formats the date');
assert.strictEqual(formattedTimestamp, '06 2012', 'it formats the date');
});
test('formatChartDate: expand chart date to full month and year', async function (assert) {

View File

@@ -4,23 +4,30 @@
*/
import { module, test } from 'qunit';
import sinon from 'sinon';
import { setupTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { lastDayOfMonth, subMonths, format, fromUnixTime, addMonths } from 'date-fns';
import { parseAPITimestamp, ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
import { subMonths, fromUnixTime, addMonths } from 'date-fns';
import { parseAPITimestamp } from 'core/utils/date-formatters';
import timestamp from 'core/utils/timestamp';
module('Unit | Adapter | clients activity', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
hooks.before(function () {
sinon.stub(timestamp, 'now').callsFake(() => new Date('2023-01-13T09:30:15'));
});
hooks.beforeEach(function () {
const date = new Date();
this.store = this.owner.lookup('service:store');
this.modelName = 'clients/activity';
this.startDate = subMonths(date, 6);
this.endDate = date;
this.startDate = subMonths(timestamp.now(), 6);
this.endDate = timestamp.now();
this.readableUnix = (unix) => parseAPITimestamp(fromUnixTime(unix).toISOString(), 'MMMM dd yyyy');
});
hooks.after(function () {
timestamp.now.restore();
});
test('it does not format if both params are timestamp strings', async function (assert) {
assert.expect(1);
@@ -58,27 +65,25 @@ module('Unit | Adapter | clients activity', function (hooks) {
const readableStart = this.readableUnix(start_time);
assert.strictEqual(
readableStart,
`${ARRAY_OF_MONTHS[month]} 01 ${year}`,
`September 01 2022`,
`formatted unix start time is the first of the month: ${readableStart}`
);
assert.strictEqual(end_time, this.endDate.toISOString(), 'end time is a timestamp string');
});
this.store.queryRecord(this.modelName, queryParams);
});
test('it formats end_time only if only start_time is a timestamp string', async function (assert) {
assert.expect(2);
const twoMonthsAgo = subMonths(this.endDate, 2);
const month = twoMonthsAgo.getMonth();
const year = twoMonthsAgo.getFullYear();
const dayOfMonth = format(lastDayOfMonth(new Date(year, month, 10)), 'dd');
const twoMothsAgo = subMonths(this.endDate, 2);
const endMonth = twoMothsAgo.getMonth();
const year = twoMothsAgo.getFullYear();
const queryParams = {
start_time: {
timestamp: this.startDate.toISOString(),
},
end_time: {
monthIdx: month,
monthIdx: endMonth,
year,
},
};
@@ -89,7 +94,7 @@ module('Unit | Adapter | clients activity', function (hooks) {
assert.strictEqual(start_time, this.startDate.toISOString(), 'start time is a timestamp string');
assert.strictEqual(
readableEnd,
`${ARRAY_OF_MONTHS[month]} ${dayOfMonth} ${year}`,
`November 30 2022`,
`formatted unix end time is the last day of the month: ${readableEnd}`
);
});
@@ -105,7 +110,6 @@ module('Unit | Adapter | clients activity', function (hooks) {
const startYear = startDate.getFullYear();
const endMonth = endDate.getMonth();
const endYear = endDate.getFullYear();
const endDay = format(lastDayOfMonth(new Date(endYear, endMonth, 10)), 'dd');
const queryParams = {
start_time: {
monthIdx: startMonth,
@@ -123,12 +127,12 @@ module('Unit | Adapter | clients activity', function (hooks) {
const readableStart = this.readableUnix(start_time);
assert.strictEqual(
readableStart,
`${ARRAY_OF_MONTHS[startMonth]} 01 ${startYear}`,
`May 01 2022`,
`formatted unix start time is the first of the month: ${readableStart}`
);
assert.strictEqual(
readableEnd,
`${ARRAY_OF_MONTHS[endMonth]} ${endDay} ${endYear}`,
`March 31 2023`,
`formatted unix end time is the last day of the month: ${readableEnd}`
);
});

View File

@@ -123,7 +123,7 @@ module('Unit | Service | control group', function (hooks) {
accessor: '12345',
token: 'token',
creation_path: 'kv/',
creation_time: new Date().toISOString(),
creation_time: '2022-03-17T20:00:25.594Z',
ttl: 400,
};
const expected = { ...error, uiParams: { url: '/vault/secrets/kv/show/foo' } };
@@ -143,7 +143,7 @@ module('Unit | Service | control group', function (hooks) {
accessor: '12345',
token: 'token',
creation_path: 'kv/',
creation_time: new Date().toISOString(),
creation_time: '2022-03-17T20:00:25.594Z',
ttl: 400,
};
const service = this.owner.factoryFor('service:control-group').create({
@@ -196,7 +196,7 @@ module('Unit | Service | control group', function (hooks) {
const info = {
accessor: '12345',
creation_path: 'foo/',
creation_time: new Date().toISOString(),
creation_time: '2022-03-17T20:00:25.594Z',
ttl: 300,
};
const key = `${CONTROL_GROUP_PREFIX}${info.accessor}${TOKEN_SEPARATOR}${info.creation_path}`;

View File

@@ -0,0 +1,16 @@
import timestamp from 'core/utils/timestamp';
import sinon from 'sinon';
import { module, test } from 'qunit';
/*
This test coverage is more for an example than actually covering the utility
*/
module('Unit | Utility | timestamp', function () {
test('it can be overridden', function (assert) {
const stub = sinon.stub(timestamp, 'now').callsFake(() => new Date('2030-03-03T03:30:03'));
const result = timestamp.now();
assert.strictEqual(result.toISOString(), new Date('2030-03-03T03:30:03').toISOString());
// Always make sure to restore the stub
stub.restore(); // timestamp.now.restore(); also works
});
});