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

[CORE-41] Add new Consolidated Spend Report page #5192

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
520c4c7
skeleton of cbsr
calypsomatic Dec 5, 2024
a4cc557
Merge branch 'dev' into core-41-cross-billing
calypsomatic Dec 10, 2024
aaa2481
add searching etc
calypsomatic Dec 10, 2024
94477d2
some fixes and renaming
calypsomatic Dec 10, 2024
1ec9649
udpates and tests
calypsomatic Dec 12, 2024
900d0ff
Merge branch 'dev' into core-41-cross-billing
calypsomatic Dec 12, 2024
8e4acb2
begin caching
calypsomatic Dec 12, 2024
bc30bbb
fix test and add mixpanel event
calypsomatic Dec 12, 2024
a35a8e4
Merge branch 'dev' into core-41-cross-billing
calypsomatic Dec 12, 2024
15a986f
hopefully fix test
calypsomatic Dec 13, 2024
b837aa6
fix sorting
calypsomatic Dec 13, 2024
2348fcf
hopefully fix missing workspaces problem
calypsomatic Dec 13, 2024
cfa7271
Merge branch 'dev' into core-41-cross-billing
calypsomatic Dec 13, 2024
b65972d
fix merge
calypsomatic Dec 13, 2024
631c150
update/remove pagination
calypsomatic Dec 13, 2024
41d6f48
pr comments
calypsomatic Dec 18, 2024
4da6ac7
Merge branch 'dev' into core-41-cross-billing
calypsomatic Dec 18, 2024
4cfa9dc
add new events
calypsomatic Dec 18, 2024
a9c27f3
Merge branch 'dev' into core-41-cross-billing
calypsomatic Jan 7, 2025
b0b24ae
begin to updated spend report list item
calypsomatic Jan 9, 2025
f52b54d
update feature preview and hover ui
calypsomatic Jan 10, 2025
7d43f6c
fix header display
calypsomatic Jan 10, 2025
6bf13e6
Merge branch 'dev' into core-41-cross-billing
calypsomatic Jan 10, 2025
d5ab721
add show all workspaces button
calypsomatic Jan 10, 2025
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
254 changes: 254 additions & 0 deletions src/billing/ConsolidatedSpendReport.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
import { asMockedFn } from '@terra-ui-packages/test-utils';
import { act, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { Billing, BillingContract } from 'src/libs/ajax/billing/Billing';
import { renderWithAppContexts } from 'src/testing/test-utils';
import { WorkspaceWrapper } from 'src/workspaces/utils';

import { ConsolidatedSpendReport } from './ConsolidatedSpendReport';

jest.mock('src/libs/ajax/billing/Billing', () => ({ Billing: jest.fn() }));

jest.mock('src/libs/ajax/Metrics');
type NavExports = typeof import('src/libs/nav');
jest.mock(
'src/libs/nav',
(): NavExports => ({
...jest.requireActual<NavExports>('src/libs/nav'),
getLink: jest.fn(() => '/'),
goToPath: jest.fn(),
useRoute: jest.fn().mockReturnValue({ query: {} }),
updateSearch: jest.fn(),
})
);

const spendReport = {
spendSummary: {
cost: '1.20',
credits: '0.00',
currency: 'USD',
endTime: '2024-12-11T23:59:59.999Z',
startTime: '2024-11-11T00:00:00.000Z',
},
spendDetails: [
{
aggregationKey: 'Workspace',
spendData: [
{
cost: '0.11',
credits: '0.00',
currency: 'USD',
endTime: '2024-12-11T23:59:59.999Z',
googleProjectId: 'terra-dev-fe98dcb6',
startTime: '2024-11-11T00:00:00.000Z',
subAggregation: {
aggregationKey: 'Category',
spendData: [
{
category: 'Other',
cost: '0.10',
credits: '0.00',
currency: 'USD',
},
{
category: 'Storage',
cost: '0.00',
credits: '0.00',
currency: 'USD',
},
{
category: 'Compute',
cost: '0.00',
credits: '0.00',
currency: 'USD',
},
],
},
workspace: {
name: 'workspace2',
namespace: 'namespace-1',
},
},
],
},
{
aggregationKey: 'Workspace',
spendData: [
{
cost: '0.11',
credits: '0.00',
currency: 'USD',
endTime: '2024-12-11T23:59:59.999Z',
googleProjectId: 'terra-dev-fe98dcb8',
startTime: '2024-11-11T00:00:00.000Z',
subAggregation: {
aggregationKey: 'Category',
spendData: [
{
category: 'Other',
cost: '0.10',
credits: '0.00',
currency: 'USD',
},
{
category: 'Storage',
cost: '0.00',
credits: '0.00',
currency: 'USD',
},
{
category: 'Compute',
cost: '0.00',
credits: '0.00',
currency: 'USD',
},
],
},
workspace: {
name: 'workspace3',
namespace: 'namespace-2',
},
},
],
},
],
};

const workspaces = [
{
canShare: true,
canCompute: true,
accessLevel: 'WRITER',
policies: [],
public: false,
workspace: {
attributes: {
description: '',
'tag:tags': {
itemsType: 'AttributeValue',
items: [],
},
},
authorizationDomain: [],
billingAccount: 'billingAccounts/00102A-34B56C-78DEFA',
bucketName: 'fc-01111a11-20b2-3033-4044-55c0c5c55555',
cloudPlatform: 'Gcp',
createdBy: '[email protected]',
createdDate: '2024-08-16T13:55:36.984Z',
googleProject: 'terra-dev-fe98dcb7',
googleProjectNumber: '123045678091',
isLocked: false,
lastModified: '2024-12-11T04:32:15.461Z',
name: 'workspace1',
namespace: 'namespace-1',
state: 'Ready',
workflowCollectionName: '01111a11-20b2-3033-4044-55c0c5c55555',
workspaceId: '01111a11-20b2-3033-4044-55c0c5c55555',
workspaceType: 'rawls',
workspaceVersion: 'v2',
},
} as WorkspaceWrapper,
{
canShare: true,
canCompute: true,
accessLevel: 'OWNER',
policies: [],
public: false,
workspace: {
attributes: {
description: '',
'tag:tags': {
itemsType: 'AttributeValue',
items: [],
},
},
authorizationDomain: [],
billingAccount: 'billingAccounts/00102A-34B56C-78DEFA',
bucketName: 'fc-01111a11-20b2-3033-4044-66c0c6c66666',
cloudPlatform: 'Gcp',
createdBy: '[email protected]',
createdDate: '2024-09-26T11:55:36.984Z',
googleProject: 'terra-dev-fe98dcb6',
googleProjectNumber: '123045678092',
isLocked: false,
lastModified: '2024-11-11T04:32:15.461Z',
name: 'workspace2',
namespace: 'namespace-1',
state: 'Ready',
workflowCollectionName: '01111a11-20b2-3033-4044-66c0c6c66666',
workspaceId: '01111a11-20b2-3033-4044-66c0c6c66666',
workspaceType: 'rawls',
workspaceVersion: 'v2',
},
} as WorkspaceWrapper,
{
canShare: true,
canCompute: true,
policies: [],
accessLevel: 'PROJECT_OWNER',
public: false,
workspace: {
attributes: {
description: '',
'tag:tags': {
itemsType: 'AttributeValue',
items: [],
},
},
authorizationDomain: [],
billingAccount: 'billingAccounts/00102A-34B56C-78DEFB',
bucketName: 'fc-01111a11-20b2-3033-4044-77c0c7c77777',
cloudPlatform: 'Gcp',
createdBy: '[email protected]',
createdDate: '2024-08-10T13:50:36.984Z',
googleProject: 'terra-dev-fe98dcb8',
googleProjectNumber: '123045678090',
isLocked: false,
lastModified: '2024-12-19T04:30:15.461Z',
name: 'workspace3',
namespace: 'namespace-2',
state: 'Ready',
workflowCollectionName: '01111a11-20b2-3033-4044-77c0c7c77777',
workspaceId: '01111a11-20b2-3033-4044-77c0c7c77777',
workspaceType: 'rawls',
workspaceVersion: 'v2',
},
} as WorkspaceWrapper,
];

describe('ConsolidatedSpendReport', () => {
it('displays results of spend query', async () => {
// Arrange
const getCrossBillingSpendReport = jest.fn(() => Promise.resolve(spendReport));
asMockedFn(Billing).mockImplementation(
() => ({ getCrossBillingSpendReport } as Partial<BillingContract> as BillingContract)
);

// Act
await act(async () => renderWithAppContexts(<ConsolidatedSpendReport workspaces={workspaces} />));

// Assert
expect(screen.getByText('workspace2')).not.toBeNull();
expect(screen.getByText('workspace3')).not.toBeNull();
});

it('searches by workspace name', async () => {
// Arrange
const user = userEvent.setup();
const getCrossBillingSpendReport = jest.fn(() => Promise.resolve(spendReport));
asMockedFn(Billing).mockImplementation(
() => ({ getCrossBillingSpendReport } as Partial<BillingContract> as BillingContract)
);

// Act
await act(async () => renderWithAppContexts(<ConsolidatedSpendReport workspaces={workspaces} />));
await user.type(screen.getByPlaceholderText('Search by name, project or bucket'), 'workspace2');

// Assert
expect(screen.getByText('workspace2')).not.toBeNull();
expect(screen.queryByText('workspace3')).toBeNull();
});

// TODO: tests for tests for changing time period, tests for caching (once it's implemented)
});
Loading
Loading