thank you for the comments, @freben
This commit is contained in:
@@ -27,7 +27,8 @@ your app's [`plugins.ts`](https://github.com/spotify/backstage/blob/master/packa
|
||||
to enable the plugin:
|
||||
|
||||
```js
|
||||
export { default as LighthousePlugin } from '@backstage/plugin-lighthouse';
|
||||
import { default as LighthousePlugin } from '@backstage/plugin-lighthouse';
|
||||
export LighthousePlugin;
|
||||
```
|
||||
|
||||
Then, you need to use the `lighthouseApiRef` exported from the plugin to initialize the Rest API in
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build:watch": "backstage-cli plugin:build --watch",
|
||||
"build": "backstage-cli build-cache -- backstage-cli plugin:build",
|
||||
"build": "backstage-cli plugin:build",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test"
|
||||
},
|
||||
|
||||
@@ -122,13 +122,18 @@ export class LighthouseRestApi implements LighthouseApi {
|
||||
async getWebsiteList({ limit, offset }: LASListRequest = {}): Promise<
|
||||
WebsiteListResponse
|
||||
> {
|
||||
const params = new URLSearchParams();
|
||||
if (typeof limit === 'number') params.append('limit', limit.toString());
|
||||
if (typeof offset === 'number') params.append('offset', offset.toString());
|
||||
return await this.fetch<WebsiteListResponse>(
|
||||
`/v1/websites?limit=${limit}&offset=${offset}`,
|
||||
`/v1/websites?${params.toString()}`,
|
||||
);
|
||||
}
|
||||
|
||||
async getWebsiteForAuditId(auditId: string): Promise<Website> {
|
||||
return await this.fetch<Website>(`/v1/audits/${auditId}/website`);
|
||||
return await this.fetch<Website>(
|
||||
`/v1/audits/${encodeURIComponent(auditId)}/website`,
|
||||
);
|
||||
}
|
||||
|
||||
async triggerAudit(payload: TriggerAuditPayload): Promise<Audit> {
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { render } from '@testing-library/react';
|
||||
import { wrapInThemedTestApp } from '@backstage/test-utils';
|
||||
|
||||
@@ -24,15 +22,9 @@ import AuditListTable from './AuditListTable';
|
||||
import { WebsiteListResponse } from '../../api';
|
||||
import { formatTime } from '../../utils';
|
||||
|
||||
const websiteListResponseJson = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '../../__fixtures__/website-list-response.json'),
|
||||
)
|
||||
.toString();
|
||||
import * as data from '../../__fixtures__/website-list-response.json';
|
||||
|
||||
const websiteListResponse: WebsiteListResponse = JSON.parse(
|
||||
websiteListResponseJson,
|
||||
);
|
||||
const websiteListResponse = data as WebsiteListResponse;
|
||||
|
||||
describe('AuditListTable', () => {
|
||||
it('renders the link to each website', () => {
|
||||
|
||||
@@ -51,17 +51,21 @@ export const CATEGORY_LABELS: Record<LighthouseCategoryId, string> = {
|
||||
pwa: 'Progressive Web App',
|
||||
};
|
||||
|
||||
const useStyles = makeStyles({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
table: {
|
||||
minWidth: 650,
|
||||
},
|
||||
status: {
|
||||
textTransform: 'capitalize',
|
||||
},
|
||||
link: { padding: '0.75rem 0', display: 'inline-block' },
|
||||
link: {
|
||||
paddingTop: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(2),
|
||||
display: 'inline-block',
|
||||
},
|
||||
statusCell: { whiteSpace: 'nowrap' },
|
||||
sparklinesCell: { minWidth: 120 },
|
||||
});
|
||||
}));
|
||||
|
||||
type SparklinesDataByCategory = Record<LighthouseCategoryId, number[]>;
|
||||
function buildSparklinesDataForItem(item: Website): SparklinesDataByCategory {
|
||||
|
||||
@@ -27,23 +27,22 @@ jest.mock('react-router-dom', () => {
|
||||
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import mockFetch from 'jest-fetch-mock';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { ApiRegistry, ApiProvider } from '@backstage/core';
|
||||
import { wrapInThemedTestApp, wrapInTheme } from '@backstage/test-utils';
|
||||
|
||||
import { lighthouseApiRef, LighthouseRestApi } from '../../api';
|
||||
import {
|
||||
lighthouseApiRef,
|
||||
LighthouseRestApi,
|
||||
WebsiteListResponse,
|
||||
} from '../../api';
|
||||
import AuditList from '.';
|
||||
|
||||
const { useHistory } = require.requireMock('react-router-dom');
|
||||
import * as data from '../../__fixtures__/website-list-response.json';
|
||||
|
||||
const websiteListJson = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '../../__fixtures__/website-list-response.json'),
|
||||
)
|
||||
.toString();
|
||||
const { useHistory } = require.requireMock('react-router-dom');
|
||||
const websiteListResponse = data as WebsiteListResponse;
|
||||
|
||||
describe('AuditList', () => {
|
||||
let apis: ApiRegistry;
|
||||
@@ -52,7 +51,7 @@ describe('AuditList', () => {
|
||||
apis = ApiRegistry.from([
|
||||
[lighthouseApiRef, new LighthouseRestApi('http://lighthouse')],
|
||||
]);
|
||||
mockFetch.mockResponse(websiteListJson);
|
||||
mockFetch.mockResponse(JSON.stringify(websiteListResponse));
|
||||
});
|
||||
|
||||
it('should render the table', async () => {
|
||||
@@ -116,7 +115,7 @@ describe('AuditList', () => {
|
||||
|
||||
describe('when multiple pages are needed', () => {
|
||||
beforeEach(() => {
|
||||
const response = JSON.parse(websiteListJson);
|
||||
const response = { ...websiteListResponse };
|
||||
response.limit = 5;
|
||||
response.offset = 5;
|
||||
response.total = 7;
|
||||
|
||||
@@ -50,9 +50,9 @@ const AuditList: FC<{}> = () => {
|
||||
: 1;
|
||||
|
||||
const lighthouseApi = useApi(lighthouseApiRef);
|
||||
const { value, loading, error } = useAsync(
|
||||
async (): Promise<WebsiteListResponse> =>
|
||||
lighthouseApi.getWebsiteList({
|
||||
const { value, loading, error } = useAsync<WebsiteListResponse>(
|
||||
async () =>
|
||||
await lighthouseApi.getWebsiteList({
|
||||
limit: LIMIT,
|
||||
offset: (page - 1) * LIMIT,
|
||||
}),
|
||||
|
||||
@@ -22,8 +22,6 @@ jest.mock('react-router-dom', () => ({
|
||||
}));
|
||||
|
||||
import React from 'react';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import mockFetch from 'jest-fetch-mock';
|
||||
import { render } from '@testing-library/react';
|
||||
import { wrapInThemedTestApp } from '@backstage/test-utils';
|
||||
@@ -32,29 +30,24 @@ import { ApiRegistry, ApiProvider } from '@backstage/core';
|
||||
import AuditView from '.';
|
||||
import { lighthouseApiRef, LighthouseRestApi, Audit, Website } from '../../api';
|
||||
import { formatTime } from '../../utils';
|
||||
import * as data from '../../__fixtures__/website-response.json';
|
||||
|
||||
const { useParams }: { useParams: jest.Mock } = require.requireMock(
|
||||
'react-router-dom',
|
||||
);
|
||||
|
||||
const websiteResponseJson = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '../../__fixtures__/website-response.json'),
|
||||
)
|
||||
.toString();
|
||||
const websiteResponse = data as Website;
|
||||
|
||||
describe('AuditView', () => {
|
||||
let apis: ApiRegistry;
|
||||
let website: Website;
|
||||
let id: string;
|
||||
|
||||
beforeEach(() => {
|
||||
mockFetch.mockResponse(websiteResponseJson);
|
||||
mockFetch.mockResponse(JSON.stringify(websiteResponse));
|
||||
apis = ApiRegistry.from([
|
||||
[lighthouseApiRef, new LighthouseRestApi('https://lighthouse')],
|
||||
]);
|
||||
website = JSON.parse(websiteResponseJson) as Website;
|
||||
id = website.audits.find(a => a.status === 'COMPLETED')?.id as string;
|
||||
id = websiteResponse.audits.find(a => a.status === 'COMPLETED')
|
||||
?.id as string;
|
||||
useParams.mockReturnValue({ id });
|
||||
});
|
||||
|
||||
@@ -105,7 +98,7 @@ describe('AuditView', () => {
|
||||
|
||||
await rendered.findByTestId('audit-sidebar');
|
||||
|
||||
website.audits.forEach(a => {
|
||||
websiteResponse.audits.forEach(a => {
|
||||
expect(
|
||||
rendered.queryByText(formatTime(a.timeCreated)),
|
||||
).toBeInTheDocument();
|
||||
@@ -123,13 +116,15 @@ describe('AuditView', () => {
|
||||
|
||||
await rendered.findByTestId('audit-sidebar');
|
||||
|
||||
const audit = website.audits.find(a => a.id === id) as Audit;
|
||||
const audit = websiteResponse.audits.find(a => a.id === id) as Audit;
|
||||
const auditElement = rendered.getByText(formatTime(audit.timeCreated));
|
||||
expect(auditElement.parentElement?.parentElement?.className).toContain(
|
||||
'selected',
|
||||
);
|
||||
|
||||
const notSelectedAudit = website.audits.find(a => a.id !== id) as Audit;
|
||||
const notSelectedAudit = websiteResponse.audits.find(
|
||||
a => a.id !== id,
|
||||
) as Audit;
|
||||
const notSelectedAuditElement = rendered.getByText(
|
||||
formatTime(notSelectedAudit.timeCreated),
|
||||
);
|
||||
@@ -149,7 +144,7 @@ describe('AuditView', () => {
|
||||
|
||||
await rendered.findByTestId('audit-sidebar');
|
||||
|
||||
website.audits.forEach(a => {
|
||||
websiteResponse.audits.forEach(a => {
|
||||
expect(
|
||||
rendered.getByText(formatTime(a.timeCreated)).parentElement
|
||||
?.parentElement,
|
||||
@@ -188,7 +183,8 @@ describe('AuditView', () => {
|
||||
|
||||
describe.skip('when a loading audit is accessed', () => {
|
||||
it('shows a loading view', async () => {
|
||||
id = website.audits.find(a => a.status === 'RUNNING')?.id as string;
|
||||
id = websiteResponse.audits.find(a => a.status === 'RUNNING')
|
||||
?.id as string;
|
||||
useParams.mockReturnValueOnce({ id });
|
||||
|
||||
const rendered = render(
|
||||
@@ -207,7 +203,8 @@ describe('AuditView', () => {
|
||||
|
||||
describe.skip('when a failed audit is accessed', () => {
|
||||
it('shows an error message', async () => {
|
||||
id = website.audits.find(a => a.status === 'FAILED')?.id as string;
|
||||
id = websiteResponse.audits.find(a => a.status === 'FAILED')
|
||||
?.id as string;
|
||||
useParams.mockReturnValueOnce({ id });
|
||||
|
||||
const rendered = render(
|
||||
|
||||
@@ -106,7 +106,7 @@ const AuditView: FC<{ audit?: Audit }> = ({ audit }: { audit?: Audit }) => {
|
||||
<iframe
|
||||
className={classes.iframe}
|
||||
title={`Lighthouse audit${audit?.url ? ` for ${audit.url}` : ''}`}
|
||||
src={`${lighthouseUrl}/v1/audits/${params.id}`}
|
||||
src={`${lighthouseUrl}/v1/audits/${encodeURIComponent(params.id)}`}
|
||||
/>
|
||||
</InfoCard>
|
||||
);
|
||||
@@ -118,7 +118,7 @@ const ConnectedAuditView: FC<{}> = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
const { loading, error, value: nextValue } = useAsync<Website>(
|
||||
async () => lighthouseApi.getWebsiteForAuditId(params.id),
|
||||
async () => await lighthouseApi.getWebsiteForAuditId(params.id),
|
||||
[params.id],
|
||||
);
|
||||
const [value, setValue] = useState<Website>();
|
||||
|
||||
@@ -26,8 +26,6 @@ jest.mock('react-router-dom', () => {
|
||||
});
|
||||
|
||||
import React from 'react';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import mockFetch from 'jest-fetch-mock';
|
||||
import { wait, render, fireEvent } from '@testing-library/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
@@ -39,18 +37,14 @@ import {
|
||||
} from '@backstage/core';
|
||||
import { wrapInThemedTestApp, wrapInTheme } from '@backstage/test-utils';
|
||||
|
||||
import { lighthouseApiRef, LighthouseRestApi } from '../../api';
|
||||
import { lighthouseApiRef, LighthouseRestApi, Audit } from '../../api';
|
||||
import CreateAudit from '.';
|
||||
import * as data from '../../__fixtures__/create-audit-response.json';
|
||||
|
||||
const { useHistory }: { useHistory: jest.Mock } = require.requireMock(
|
||||
'react-router-dom',
|
||||
);
|
||||
|
||||
const createAuditResponseJson = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '../../__fixtures__/create-audit-response.json'),
|
||||
)
|
||||
.toString();
|
||||
const createAuditResponse = data as Audit;
|
||||
|
||||
// TODO add act() to these tests without breaking them!
|
||||
describe('CreateAudit', () => {
|
||||
@@ -123,7 +117,7 @@ describe('CreateAudit', () => {
|
||||
describe('when the audit is successfully created', () => {
|
||||
it('triggers a location change to the table', async () => {
|
||||
useHistory().push.mockClear();
|
||||
mockFetch.mockResponseOnce(createAuditResponseJson);
|
||||
mockFetch.mockResponseOnce(JSON.stringify(createAuditResponse));
|
||||
|
||||
const rendered = render(
|
||||
wrapInThemedTestApp(
|
||||
|
||||
@@ -47,7 +47,8 @@ your app's [\`plugins.ts\`](https://github.com/spotify/backstage/blob/master/pac
|
||||
to enable the plugin:
|
||||
|
||||
\`\`\`js
|
||||
export { default as LighthousePlugin } from '@backstage/plugin-lighthouse';
|
||||
import { default as LighthousePlugin } from '@backstage/plugin-lighthouse';
|
||||
export LighthousePlugin;
|
||||
\`\`\`
|
||||
|
||||
Then, you need to use the \`lighthouseApiRef\` exported from the plugin to initialize the Rest API in
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user