mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 02:02:43 +00:00
* Client Count Routing Updates (#24733) * updates client count routing for sync and future additions * adds copyright header to clients sync template * adds missing copyright headers * UI: Adds secret_syncs to mirage /activity endpoint (#24846) * add secret_syncs to mirage endpoint * import clients handler * UI: Set up client charts for incoming sync data (#24852) * sum stacked bar values for tooltip total * make tooltip dynamic based on chartLegend * remove redundant helper * add secret_syncs to client count utils * move sum function to helper * update horizontal bar chart to include sync_clients * calculate sum of bars in tooltip * rename color palette const, define chart legends in each parent component instead of token.js * update tooltips * update mirage handler to add sys/ namespace * update mirage handler to add sys/ namespace * use pushObject * update test * UI: Secret sync bar chart (#24926) * install lineal * add ember-style-modifier dep * Add client count types for serialized data * Add sync bar chart component with tests * Chart is responsive * address comments * Clients Counts Parent Route (#24899) * adds interfaces for clients models * moves date formatting logic from clients activity adapter to utils file * adds clients counts route * updates links to clients route to point to top level and updates redirect to counts overview route * removes clients base route and moves overview and sync routes under counts * adds clients counts page component * converts clients route to ts * adds billing start timestamp to clients config mirage response and updates counts route to always attempt to fetch activity * fixes issue with updating namespace and auth mount query params always triggering client counts route model hook * adds tests for clients counts page component * adds missing copyright header to client-counts type file * Update ui/app/components/clients/page/counts.hbs Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * fixes bad import in sync-bar-chart * updates clients counts route to bypass query if there is not start_time * pins d3-shape to 1.3.7 for now -- makes lineal play nice with old charts * fixes sync bar chart tooltip assertion --------- Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * UI: convert line-chart to lineal (#24961) * lineal chart alongside svg * Add version-history to sync handler for testing * line chart is TS, test updated * remove d3-shape resolution * fix clients/token-test * use chartHeight in running-total template * use M/yy key instead of timestamp, chart is responsive * Add test for swapping datasets * add more edge case tests * more test * remove untrue assertion * fix weird decimal when between 1.1k and 2k * address feedback * Update line-chart to use timestamp instead of month key * Add timestamp to all places where month is on the clients activity response * Client Counts Overview (#24969) * adds counts base component for use in client counts child routes * adds clients counts overview page component * splits out monthly new chart from clients running total component * adds missing copyright headers * moves running total related assertions from token to overview acceptance test * removes new client assertions from running-total test and adds tests for monthly-new component * updates copy in running-total component * fixes clients overview tests * fixes timestamp stub not being restored in monthly-new test * fixes mfa-login test * renames counts component to activity * removes unused selectedAuthMethod arg from running-total component * adds timestamp back to running-total component * Secrets sync UI: add sync page component (#24982) * adds counts base component for use in client counts child routes * adds clients counts overview page component * splits out monthly new chart from clients running total component * adds missing copyright headers * move sync-bar-chart to charts/ folder * update types and rename chart * rename template file * moves running total related assertions from token to overview acceptance test * removes new client assertions from running-total test and adds tests for monthly-new component * updates copy in running-total component * fixes clients overview tests * fixes timestamp stub not being restored in monthly-new test * fixes mfa-login test * fix 0 values erroring charts * separate timestamp again * address merge conflicts * finish building sync chart component WIP css * renames counts component to activity * update import * revert name to dataKey * update styling for charts without legends * use monthly stat chart component for layout * use monthly chart stats in monthly new * implement stat wrapper; * remove extra grid div * rename component * fix legend css; * update test[ * remove arbitrarily setting max * add single month view * use stat text * update line chart tests * rename line chart * update tests --------- Co-authored-by: Jordan Reimer <zofskeez@gmail.com> * update selectors * add sync page tests * Secrets Sync UI: Add secrets syncs to csv export (#25056) * update mirage and add sync clients to export csv * fix sync legend label * remove word * update copy in modal * update mirage * fix attribution tooltip text * Clients Counts Token Route (#25019) * renames token route and page component back to dashboard * adds client counts token route and page component * updates charts in token page to use ChartContainer component * adds tests for clients token page component * restore clients dashboard test * use var for chart title sync page * updates clients token page to show usage stats when querying single month * updates token page clients averages to only include entity and non-entity clients in calculation * fixes monthly total counts lower than new clients in mirage handler * fixes token test --------- Co-authored-by: clairebontempo@gmail.com <clairebontempo@gmail.com> * Clients Usage Stats/Running Total Updates (#25094) * updates clients usage counts and running totals * updates usage stats total copy * fixes client counts overview tests * Secrets sync UI: cleanup and consolidation of components (#25090) * rename authMethod to mountPath * generalize count template copy * add todo to delete monthly new component * rename to tokenTab * wrap filters in conditional checking for start timestamp * some users may not have access to /config endpoint * fix querying when user has no billing date permissions and clicks current billing period * extend activity component from counts page * Revert "extend activity component from counts page" This reverts commit 1d0e85c82faf88c4385a04b1a5841cdde7fd00e0. * rename to startTimestampISO * remove timestamp from route and just use activity model responseTimestamp * fix chart y domain max * fix typos in usage stat and running totals component * delete backing class for display only template; * updates tests * adds comment for fetching license to get start date for billing * cleans up unused client counts files (#25157) * adds changelog * fix assertion copy * adds changelog description * updates enterprise sidebar nav test --------- Co-authored-by: clairebontempo@gmail.com <clairebontempo@gmail.com> Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com>
241 lines
10 KiB
JavaScript
241 lines
10 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { module, test } from 'qunit';
|
|
import { setupApplicationTest } from 'ember-qunit';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import clientsHandler from 'vault/mirage/handlers/clients';
|
|
import sinon from 'sinon';
|
|
import { visit, click, findAll, find, settled } from '@ember/test-helpers';
|
|
import authPage from 'vault/tests/pages/auth';
|
|
import { ARRAY_OF_MONTHS } from 'core/utils/date-formatters';
|
|
import { SELECTORS, STATIC_NOW, LICENSE_START, UPGRADE_DATE } from 'vault/tests/helpers/clients';
|
|
import { create } from 'ember-cli-page-object';
|
|
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
|
import { formatNumber } from 'core/helpers/format-number';
|
|
import timestamp from 'core/utils/timestamp';
|
|
import ss from 'vault/tests/pages/components/search-select';
|
|
|
|
const searchSelect = create(ss);
|
|
|
|
module('Acceptance | clients | overview', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
setupMirage(hooks);
|
|
|
|
hooks.before(function () {
|
|
sinon.stub(timestamp, 'now').callsFake(() => STATIC_NOW);
|
|
});
|
|
|
|
hooks.beforeEach(async function () {
|
|
clientsHandler(this.server);
|
|
this.store = this.owner.lookup('service:store');
|
|
await authPage.login();
|
|
return visit('/vault/clients/counts/overview');
|
|
});
|
|
|
|
hooks.after(function () {
|
|
timestamp.now.restore();
|
|
});
|
|
|
|
test('it should render charts', async function (assert) {
|
|
assert
|
|
.dom(SELECTORS.counts.startMonth)
|
|
.hasText('July 2022', 'billing start month is correctly parsed from license');
|
|
assert
|
|
.dom(SELECTORS.rangeDropdown)
|
|
.hasText(`Jul 2022 - Jan 2023`, 'Date range shows dates correctly parsed activity response');
|
|
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.exists('Shows running totals with monthly breakdown charts');
|
|
assert
|
|
.dom(SELECTORS.charts.line.xAxisLabel)
|
|
.hasText(`7/22`, 'x-axis labels start with billing start date');
|
|
assert.strictEqual(
|
|
findAll('[data-test-line-chart="plot-point"]').length,
|
|
6,
|
|
`line chart plots 6 points to match query`
|
|
);
|
|
});
|
|
|
|
test('it should update charts when querying date ranges', async function (assert) {
|
|
// query for single, historical month with no new counts
|
|
await click(SELECTORS.rangeDropdown);
|
|
await click('[data-test-show-calendar]');
|
|
if (parseInt(find('[data-test-display-year]').innerText) > LICENSE_START.getFullYear()) {
|
|
await click('[data-test-previous-year]');
|
|
}
|
|
await click(`[data-test-calendar-month=${ARRAY_OF_MONTHS[LICENSE_START.getMonth()]}]`);
|
|
assert
|
|
.dom(SELECTORS.runningTotalMonthStats)
|
|
.doesNotExist('running total single month stat boxes do not show');
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.doesNotExist('running total month over month charts do not show');
|
|
assert.dom(SELECTORS.attributionBlock).exists('attribution area shows');
|
|
assert
|
|
.dom('[data-test-chart-container="new-clients"] [data-test-component="empty-state"]')
|
|
.exists('new client attribution has empty state');
|
|
assert
|
|
.dom('[data-test-empty-state-subtext]')
|
|
.hasText('There are no new clients for this namespace during this time period. ');
|
|
assert.dom('[data-test-chart-container="total-clients"]').exists('total client attribution chart shows');
|
|
|
|
// reset to billing period
|
|
await click(SELECTORS.rangeDropdown);
|
|
await click('[data-test-current-billing-period]');
|
|
|
|
// change billing start to month/year of first upgrade
|
|
await click(SELECTORS.counts.startEdit);
|
|
await click(SELECTORS.monthDropdown);
|
|
await click(`[data-test-dropdown-month="${ARRAY_OF_MONTHS[UPGRADE_DATE.getMonth()]}"]`);
|
|
await click(SELECTORS.yearDropdown);
|
|
await click(`[data-test-dropdown-year="${UPGRADE_DATE.getFullYear()}"]`);
|
|
await click('[data-test-date-dropdown-submit]');
|
|
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.exists('Shows running totals with monthly breakdown charts');
|
|
assert
|
|
.dom(SELECTORS.charts.line.xAxisLabel)
|
|
.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 (Oct 2022)
|
|
await click(SELECTORS.rangeDropdown);
|
|
await click('[data-test-show-calendar]');
|
|
await click('[data-test-previous-year]');
|
|
await click('[data-test-calendar-month="October"]');
|
|
|
|
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.exists('Shows running totals with monthly breakdown charts');
|
|
assert.strictEqual(
|
|
findAll('[data-test-line-chart="plot-point"]').length,
|
|
3,
|
|
`line chart plots 3 points to match query`
|
|
);
|
|
const xAxisLabels = findAll(SELECTORS.charts.line.xAxisLabel);
|
|
assert
|
|
.dom(xAxisLabels[xAxisLabels.length - 1])
|
|
.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]');
|
|
assert.dom('[data-test-display-year]').hasText('2022');
|
|
await click('[data-test-calendar-month="August"]');
|
|
|
|
assert.dom(SELECTORS.runningTotalMonthStats).exists('running total single month stat boxes show');
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.doesNotExist('running total month over month charts do not show');
|
|
assert.dom(SELECTORS.attributionBlock).exists('attribution area shows');
|
|
assert.dom('[data-test-chart-container="new-clients"]').exists('new client attribution chart shows');
|
|
assert.dom('[data-test-chart-container="total-clients"]').exists('total client attribution chart shows');
|
|
|
|
// reset to billing period
|
|
await click(SELECTORS.rangeDropdown);
|
|
await click('[data-test-current-billing-period]');
|
|
// query month older than count start date
|
|
await click(SELECTORS.counts.startEdit);
|
|
await click(SELECTORS.monthDropdown);
|
|
await click(`[data-test-dropdown-month="${ARRAY_OF_MONTHS[LICENSE_START.getMonth()]}"]`);
|
|
await click(SELECTORS.yearDropdown);
|
|
await click(`[data-test-dropdown-year="${LICENSE_START.getFullYear() - 3}"]`);
|
|
await click('[data-test-date-dropdown-submit]');
|
|
assert
|
|
.dom(SELECTORS.counts.startDiscrepancy)
|
|
.hasTextContaining(
|
|
`We only have data from January 2022`,
|
|
'warning banner displays that date queried was prior to count start date'
|
|
);
|
|
});
|
|
|
|
test('totals filter correctly with full data', async function (assert) {
|
|
assert
|
|
.dom(SELECTORS.charts.chart('running total'))
|
|
.exists('Shows running totals with monthly breakdown charts');
|
|
assert.dom(SELECTORS.attributionBlock).exists('Shows attribution area');
|
|
|
|
const response = await this.store.peekRecord('clients/activity', 'some-activity-id');
|
|
// FILTER BY NAMESPACE
|
|
await clickTrigger();
|
|
await searchSelect.options.objectAt(0).click();
|
|
await settled();
|
|
const topNamespace = response.byNamespace[0];
|
|
const topMount = topNamespace.mounts[0];
|
|
|
|
assert.dom(SELECTORS.selectedNs).hasText(topNamespace.label, 'selects top namespace');
|
|
assert.dom('[data-test-top-attribution]').includesText('Top auth method');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Entity clients'))
|
|
.includesText(`${formatNumber([topNamespace.entity_clients])}`, 'total entity clients is accurate');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Non-entity clients'))
|
|
.includesText(
|
|
`${formatNumber([topNamespace.non_entity_clients])}`,
|
|
'total non-entity clients is accurate'
|
|
);
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
|
|
.includesText(`${formatNumber([topNamespace.secret_syncs])}`, 'total sync clients is accurate');
|
|
assert
|
|
.dom('[data-test-attribution-clients] p')
|
|
.includesText(`${formatNumber([topMount.clients])}`, 'top attribution clients accurate');
|
|
|
|
// FILTER BY AUTH METHOD
|
|
await clickTrigger();
|
|
await searchSelect.options.objectAt(0).click();
|
|
await settled();
|
|
|
|
assert.ok(true, 'Filter by first auth method');
|
|
assert.dom(SELECTORS.selectedAuthMount).hasText(topMount.label, 'selects top mount');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Entity clients'))
|
|
.includesText(`${formatNumber([topMount.entity_clients])}`, 'total entity clients is accurate');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Non-entity clients'))
|
|
.includesText(`${formatNumber([topMount.non_entity_clients])}`, 'total non-entity clients is accurate');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
|
|
.includesText(`${formatNumber([topMount.secret_syncs])}`, 'total sync clients is accurate');
|
|
assert.dom(SELECTORS.attributionBlock).doesNotExist('Does not show attribution block');
|
|
|
|
await click('#namespace-search-select [data-test-selected-list-button="delete"]');
|
|
assert.ok(true, 'Remove namespace filter without first removing auth method filter');
|
|
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Entity clients'))
|
|
.hasTextContaining(
|
|
`${formatNumber([response.total.entity_clients])}`,
|
|
'total entity clients is back to unfiltered value'
|
|
);
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Non-entity clients'))
|
|
.hasTextContaining(
|
|
`${formatNumber([formatNumber([response.total.non_entity_clients])])}`,
|
|
'total non-entity clients is back to unfiltered value'
|
|
);
|
|
assert
|
|
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
|
|
.hasTextContaining(
|
|
`${formatNumber([formatNumber([response.total.secret_syncs])])}`,
|
|
'total sync clients is back to unfiltered value'
|
|
);
|
|
assert
|
|
.dom('[data-test-attribution-clients]')
|
|
.hasTextContaining(
|
|
`${formatNumber([topNamespace.clients])}`,
|
|
'top attribution clients back to unfiltered value'
|
|
);
|
|
});
|
|
});
|