Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: fix undefined csv filename #26485

Merged
merged 6 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ui/app/components/clients/attribution.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,17 @@
</p>
<p class="has-bottom-margin-s is-subtitle-gray">SELECTED DATE {{if this.formattedEndDate " RANGE"}}</p>
<p class="has-bottom-margin-s" data-test-export-date-range>
{{this.parseAPITimestamp @startTimestamp "MMMM yyyy"}}
{{this.formattedStartDate}}
{{if this.formattedEndDate "-"}}
{{this.formattedEndDate}}</p>
</M.Body>
<M.Footer as |F|>
<Hds::ButtonSet>
<Hds::Button @text="Export" {{on "click" (fn this.exportChartData this.formattedCsvFileName)}} />
<Hds::Button
@text="Export"
{{on "click" (fn this.exportChartData this.formattedCsvFileName)}}
data-test-confirm-button
/>
<Hds::Button @text="Cancel" @color="secondary" {{on "click" F.close}} />
</Hds::ButtonSet>
{{#if @upgradesDuringActivity}}
Expand Down
30 changes: 14 additions & 16 deletions ui/app/components/clients/attribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,8 @@ import { format, isSameMonth } from 'date-fns';

export default class Attribution extends Component {
@service download;

@tracked showCSVDownloadModal = false;

parseAPITimestamp = (time, format) => parseAPITimestamp(time, format);

get attributionLegend() {
const attributionLegend = [
{ key: 'entity_clients', label: 'entity clients' },
Expand All @@ -60,6 +57,11 @@ export default class Attribution extends Component {
return attributionLegend;
}

get formattedStartDate() {
Copy link
Contributor Author

@hellobontempo hellobontempo Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I accidentally removed this in this PR 🤦

if (!this.args.startTimestamp) return null;
return parseAPITimestamp(this.args.startTimestamp, 'MMMM yyyy');
}

get formattedEndDate() {
if (!this.args.startTimestamp && !this.args.endTimestamp) return null;
// displays on CSV export modal, no need to display duplicate months and years
Expand All @@ -73,9 +75,6 @@ export default class Attribution extends Component {
}

get isSingleNamespace() {
if (!this.args.totalClientAttribution) {
return 'no data';
}
// if a namespace is selected, then we're viewing top 10 auth methods (mounts)
return !!this.args.selectedNamespace;
}
Expand All @@ -100,6 +99,9 @@ export default class Attribution extends Component {
}

get chartText() {
if (!this.args.totalClientAttribution) {
return { description: 'There is a problem gathering data' };
}
const dateText = this.formattedEndDate ? 'date range' : 'month';
switch (this.isSingleNamespace) {
case true:
Expand All @@ -121,10 +123,6 @@ export default class Attribution extends Component {
}`,
totalCopy: `The total clients in the namespace for this ${dateText}. This number is useful for identifying overall usage volume.`,
};
case 'no data':
return {
description: 'There is a problem gathering data',
};
default:
return '';
}
Expand Down Expand Up @@ -157,15 +155,15 @@ export default class Attribution extends Component {
const csvData = [];
// added to clarify that the row of namespace totals without an auth method (blank) are not additional clients
// but indicate the total clients for that ns, including its auth methods
const upgrade = this.args.upgradesDuringActivity.length
const upgrade = this.args.upgradesDuringActivity?.length
? `\n **data contains an upgrade, mount summation may not equal namespace totals`
: '';
const descriptionOfBlanks = this.isSingleNamespace
? ''
: `\n *namespace totals, inclusive of mount clients ${upgrade}`;
: `\n *namespace totals, inclusive of mount clients${upgrade}`;
const csvHeader = [
'Namespace path',
`"Mount path ${descriptionOfBlanks}"`,
`Mount path${descriptionOfBlanks}`,
'Total clients',
'Entity clients',
'Non-entity clients',
Expand Down Expand Up @@ -216,10 +214,10 @@ export default class Attribution extends Component {

get formattedCsvFileName() {
const endRange = this.formattedEndDate ? `-${this.formattedEndDate}` : '';
const csvDateRange = this.formattedStartDate + endRange;
const csvDateRange = this.formattedStartDate ? `_${this.formattedStartDate + endRange}` : '';
return this.isSingleNamespace
? `clients_by_mount_path_${csvDateRange}`
: `clients_by_namespace_${csvDateRange}`;
? `clients_by_mount_path${csvDateRange}`
: `clients_by_namespace${csvDateRange}`;
}

get modalExportText() {
Expand Down
93 changes: 93 additions & 0 deletions ui/tests/integration/components/clients/attribution-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ import { endOfMonth, formatRFC3339 } from 'date-fns';
import { click } from '@ember/test-helpers';
import subMonths from 'date-fns/subMonths';
import timestamp from 'core/utils/timestamp';
import { GENERAL } from 'vault/tests/helpers/general-selectors';

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.csvDownloadStub = sinon.stub(this.owner.lookup('service:download'), 'csv');
const mockNow = timestamp.now();
this.mockNow = mockNow;
this.set('startTimestamp', formatRFC3339(subMonths(mockNow, 6)));
Expand All @@ -40,8 +43,10 @@ module('Integration | Component | clients/attribution', function (hooks) {
{ label: 'auth2/', clients: 2, entity_clients: 1, non_entity_clients: 1 },
]);
});

hooks.after(function () {
timestamp.now.restore();
this.csvDownloadStub.restore();
});

test('it renders empty state with no data', async function (assert) {
Expand Down Expand Up @@ -227,4 +232,92 @@ module('Integration | Component | clients/attribution', function (hooks) {
.hasText('Export attribution data', 'modal appears to export csv');
assert.dom('[ data-test-export-date-range]').includesText('June 2022 - December 2022');
});

test('it downloads csv data for date range', async function (assert) {
assert.expect(2);

await render(hbs`
<Clients::Attribution
@totalClientAttribution={{this.totalClientAttribution}}
@responseTimestamp={{this.timestamp}}
@startTimestamp="2022-06-01T23:00:11.050Z"
@endTimestamp="2022-12-01T23:00:11.050Z"
/>
`);
await click('[data-test-attribution-export-button]');
await click(GENERAL.confirmButton);
const [filename, content] = this.csvDownloadStub.lastCall.args;
assert.strictEqual(filename, 'clients_by_namespace_June 2022-December 2022', 'csv has expected filename');
assert.strictEqual(
content,
`Namespace path,Mount path\n *namespace totals, inclusive of mount clients,Total clients,Entity clients,Non-entity clients\nsecond,*,10,7,3\nfirst,*,5,3,2`,
'csv has expected content'
);
});

test('it downloads csv data for a single month', async function (assert) {
assert.expect(2);
await render(hbs`
<Clients::Attribution
@totalClientAttribution={{this.totalClientAttribution}}
@responseTimestamp={{this.timestamp}}
@startTimestamp="2022-06-01T23:00:11.050Z"
@endTimestamp="2022-06-21T23:00:11.050Z"
/>
`);
await click('[data-test-attribution-export-button]');
await click(GENERAL.confirmButton);
const [filename, content] = this.csvDownloadStub.lastCall.args;
assert.strictEqual(filename, 'clients_by_namespace_June 2022', 'csv has single month in filename');
assert.strictEqual(
content,
`Namespace path,Mount path\n *namespace totals, inclusive of mount clients,Total clients,Entity clients,Non-entity clients\nsecond,*,10,7,3\nfirst,*,5,3,2`,
'csv has expected content'
);
});

test('it downloads csv data when a namespace is selected', async function (assert) {
assert.expect(2);
this.selectedNamespace = 'second';

await render(hbs`
<Clients::Attribution
@totalClientAttribution={{this.namespaceMountsData}}
@selectedNamespace={{this.selectedNamespace}}
@responseTimestamp={{this.timestamp}}
@startTimestamp="2022-06-01T23:00:11.050Z"
@endTimestamp="2022-12-21T23:00:11.050Z"
/>
`);

await click('[data-test-attribution-export-button]');
await click(GENERAL.confirmButton);
const [filename, content] = this.csvDownloadStub.lastCall.args;
assert.strictEqual(
filename,
'clients_by_mount_path_June 2022-December 2022',
'csv has expected filename for a selected namespace'
);
assert.strictEqual(
content,
`Namespace path,Mount path,Total clients,Entity clients,Non-entity clients\nsecond,auth1/,3,2,1\nsecond,auth2/,2,1,1`,
'csv has expected content for a selected namespace'
);
});

test('csv filename omits date if no start/end timestamp', async function (assert) {
assert.expect(1);

await render(hbs`
<Clients::Attribution
@totalClientAttribution={{this.totalClientAttribution}}
@responseTimestamp={{this.timestamp}}
/>
`);

await click('[data-test-attribution-export-button]');
await click(GENERAL.confirmButton);
const [filename, ,] = this.csvDownloadStub.lastCall.args;
assert.strictEqual(filename, 'clients_by_namespace');
});
});
Loading