declare default properties using accessors

This commit is contained in:
Ryan Vazquez
2021-02-21 13:36:32 -05:00
parent 1add977bae
commit 3b55f5f81f
4 changed files with 169 additions and 9 deletions
@@ -0,0 +1,77 @@
import React from 'react';
import pluralize from 'pluralize';
import { renderInTestApp } from '@backstage/test-utils';
import { ProjectGrowthAlert } from './ProjectGrowthAlert';
import { ProjectGrowthData } from '../types';
import {
MockCurrencyProvider,
MockConfigProvider,
MockBillingDateProvider,
} from '../utils/tests';
const mockData: ProjectGrowthData = {
project: 'test-project',
periodStart: '2021-01-01',
periodEnd: '2021-02-01',
aggregation: [0, 0],
change: {
ratio: 0,
amount: 0
},
products: [
{
id: 'product-a',
aggregation: [0, 0]
}
],
};
// suppress recharts componentDidUpdate deprecation warnings
jest.spyOn(console, 'warn').mockImplementation(() => { });
async function renderInContext(children: JSX.Element) {
return renderInTestApp(
<MockConfigProvider>
<MockBillingDateProvider>
<MockCurrencyProvider>
{children}
</MockCurrencyProvider>
</MockBillingDateProvider>
</MockConfigProvider>
)
}
class CustomProjectGrowthAlert extends ProjectGrowthAlert {
get url() {
return 'path/to/resource';
}
get title() {
return `Investigate cost growth in ${pluralize('project', this.data.products.length, true)}`;
}
}
describe('ProjectGrowthAlert', () => {
describe('constructor', () => {
it('should create a project growth alert', async () => {
const alert = new ProjectGrowthAlert(mockData);
const { getByText, queryByText } = await renderInContext(alert.element);
expect(alert.url).toBe('/cost-insights/investigating-growth');
expect(alert.title).toBe('Investigate cost growth in project test-project');
expect(alert.subtitle).toBe('Cost growth outpacing business growth is unsustainable long-term.');
expect(getByText('1 product')).toBeInTheDocument();
expect(queryByText('sorted by cost')).not.toBeInTheDocument();
});
it('a subclass can inherit and override defaults using accessors', async () => {
const alert = new CustomProjectGrowthAlert(mockData);
const { getByText, queryByText } = await renderInContext(alert.element);
expect(alert.url).toBe('path/to/resource');
expect(alert.title).toBe('Investigate cost growth in 1 project');
expect(alert.subtitle).toBe('Cost growth outpacing business growth is unsustainable long-term.');
expect(getByText('1 product')).toBeInTheDocument();
expect(queryByText('sorted by cost')).not.toBeInTheDocument();
});
});
})
@@ -27,18 +27,22 @@ import { Alert, ProjectGrowthData } from '../types';
export class ProjectGrowthAlert implements Alert {
data: ProjectGrowthData;
url = '/cost-insights/investigating-growth';
subtitle =
'Cost growth outpacing business growth is unsustainable long-term.';
constructor(data: ProjectGrowthData) {
this.data = data;
}
get url() {
return '/cost-insights/investigating-growth';
}
get title() {
return `Investigate cost growth in project ${this.data.project}`;
}
get subtitle() {
return 'Cost growth outpacing business growth is unsustainable long-term.';
}
get element() {
return <ProjectGrowthAlertCard alert={this.data} />;
}
@@ -0,0 +1,72 @@
import React from 'react';
import pluralize from 'pluralize';
import { renderInTestApp } from '@backstage/test-utils';
import { UnlabeledDataflowAlert } from './UnlabeledDataflowAlert';
import { UnlabeledDataflowData } from '../types';
import {
MockCurrencyProvider,
MockConfigProvider,
MockBillingDateProvider,
} from '../utils/tests';
const mockData: UnlabeledDataflowData = {
periodStart: '2021-02-01',
periodEnd: '2021-03-31',
unlabeledCost: 0,
labeledCost: 0,
projects: [
{
id: 'project-a',
labeledCost: 0,
unlabeledCost: 0
}
]
};
// suppress recharts componentDidUpdate deprecation warnings
jest.spyOn(console, 'warn').mockImplementation(() => { });
async function renderInContext(children: JSX.Element) {
return renderInTestApp(
<MockConfigProvider>
<MockBillingDateProvider>
<MockCurrencyProvider>
{children}
</MockCurrencyProvider>
</MockBillingDateProvider>
</MockConfigProvider>
)
}
class CustomUnlabeledDataflowAlert extends UnlabeledDataflowAlert {
get url() {
return 'path/to/resource';
}
get title() {
return `Add labels to ${pluralize('workflow', this.data.projects.length, true)}`;
}
}
describe('UnlabeledDataflowAlert', () => {
describe('constructor', () => {
it('should create an unlabeled dataflow alert', async () => {
const alert = new UnlabeledDataflowAlert(mockData);
const { getByText } = await renderInContext(alert.element);
expect(alert.url).toBe('/cost-insights/labeling-jobs');
expect(alert.title).toBe('Add labels to workflows');
expect(alert.subtitle).toBe('Labels show in billing data, enabling cost insights for each workflow.');
expect(getByText('Showing costs from 1 project with unlabeled Dataflow jobs in the last 30 days.')).toBeInTheDocument();
});
it('a subclass can inherit and override defaults using accessors', async () => {
const alert = new CustomUnlabeledDataflowAlert(mockData);
const { getByText } = await renderInContext(alert.element);
expect(alert.url).toBe('path/to/resource');
expect(alert.title).toBe('Add labels to 1 workflow');
expect(alert.subtitle).toBe('Labels show in billing data, enabling cost insights for each workflow.');
expect(getByText('Showing costs from 1 project with unlabeled Dataflow jobs in the last 30 days.')).toBeInTheDocument();
});
});
})
@@ -28,15 +28,22 @@ export class UnlabeledDataflowAlert implements Alert {
data: UnlabeledDataflowData;
status?: AlertStatus;
url = '/cost-insights/labeling-jobs';
title = 'Add labels to workflows';
subtitle =
'Labels show in billing data, enabling cost insights for each workflow.';
constructor(data: UnlabeledDataflowData) {
this.data = data;
}
get url() {
return '/cost-insights/labeling-jobs';
}
get title() {
return 'Add labels to workflows';
}
get subtitle() {
return 'Labels show in billing data, enabling cost insights for each workflow.';
}
get element() {
return <UnlabeledDataflowAlertCard alert={this.data} />;
}