plugins/tech-radar: migrate to new plugin pattern and avoid using api for config
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createApiRef } from '@backstage/core';
|
||||
import { MovedState } from './utils/types';
|
||||
|
||||
/**
|
||||
@@ -72,37 +71,3 @@ export interface TechRadarApi extends TechRadarComponentProps {
|
||||
subtitle?: string;
|
||||
pageTitle?: string;
|
||||
}
|
||||
|
||||
export const techRadarApiRef = createApiRef<TechRadarApi>({
|
||||
id: 'plugin.techradar',
|
||||
description: 'Used by the Tech Radar to render the visualization',
|
||||
});
|
||||
|
||||
export class TechRadar implements TechRadarApi {
|
||||
// Default columns
|
||||
public width: TechRadarApi['width'];
|
||||
public height: TechRadarApi['height'];
|
||||
public getData: TechRadarApi['getData'];
|
||||
public svgProps: TechRadarApi['svgProps'];
|
||||
public title: TechRadarApi['title'];
|
||||
public subtitle: TechRadarApi['subtitle'];
|
||||
public pageTitle: TechRadarApi['pageTitle'];
|
||||
|
||||
constructor(overrideOptions: TechRadarApi) {
|
||||
const defaultOptions: Partial<TechRadarApi> = {
|
||||
title: 'Tech Radar',
|
||||
subtitle: 'Pick the recommended technologies for your projects',
|
||||
pageTitle: 'Company Radar',
|
||||
};
|
||||
|
||||
const options = { ...defaultOptions, ...overrideOptions };
|
||||
|
||||
this.width = options.width;
|
||||
this.height = options.height;
|
||||
this.getData = options.getData;
|
||||
this.svgProps = options.svgProps;
|
||||
this.title = options.title;
|
||||
this.subtitle = options.subtitle;
|
||||
this.pageTitle = options.pageTitle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { render, waitForElement } from '@testing-library/react';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core';
|
||||
import { withLogCollector } from '@backstage/test-utils-core';
|
||||
import { withLogCollector } from '@backstage/test-utils';
|
||||
|
||||
import GetBBoxPolyfill from '../utils/polyfills/getBBox';
|
||||
import RadarComponent from './RadarComponent';
|
||||
|
||||
@@ -19,11 +19,10 @@ import { render, waitForElement } from '@testing-library/react';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core';
|
||||
import { withLogCollector } from '@backstage/test-utils-core';
|
||||
|
||||
import GetBBoxPolyfill from '../utils/polyfills/getBBox';
|
||||
import { techRadarApiRef, TechRadar } from '../index';
|
||||
import RadarPage from './RadarPage';
|
||||
import { RadarPage } from './RadarPage';
|
||||
import { MockErrorApi, wrapInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('RadarPage', () => {
|
||||
beforeAll(() => {
|
||||
@@ -35,24 +34,18 @@ describe('RadarPage', () => {
|
||||
});
|
||||
|
||||
it('should render a progress bar', async () => {
|
||||
const errorApi = { post: () => {} };
|
||||
const techRadarApi = new TechRadar({
|
||||
const techRadarProps = {
|
||||
width: 1200,
|
||||
height: 800,
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
});
|
||||
};
|
||||
|
||||
const { getByTestId, queryByTestId } = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.from([
|
||||
[errorApiRef, errorApi],
|
||||
[techRadarApiRef, techRadarApi],
|
||||
])}
|
||||
>
|
||||
<RadarPage />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
wrapInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ThemeProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
expect(getByTestId('progress')).toBeInTheDocument();
|
||||
@@ -61,24 +54,18 @@ describe('RadarPage', () => {
|
||||
});
|
||||
|
||||
it('should render a header with a svg', async () => {
|
||||
const errorApi = { post: () => {} };
|
||||
const techRadarApi = new TechRadar({
|
||||
const techRadarProps = {
|
||||
width: 1200,
|
||||
height: 800,
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
});
|
||||
};
|
||||
|
||||
const { getByText, getByTestId } = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.from([
|
||||
[errorApiRef, errorApi],
|
||||
[techRadarApiRef, techRadarApi],
|
||||
])}
|
||||
>
|
||||
<RadarPage />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
wrapInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ThemeProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
await waitForElement(() => getByTestId('tech-radar-svg'));
|
||||
@@ -90,78 +77,29 @@ describe('RadarPage', () => {
|
||||
});
|
||||
|
||||
it('should call the errorApi if load fails', async () => {
|
||||
const errorApi = { post: jest.fn() };
|
||||
const errorApi = new MockErrorApi({ collect: true });
|
||||
const techRadarLoadFail = () =>
|
||||
Promise.reject(new Error('404 Page Not Found'));
|
||||
const techRadarApi = new TechRadar({
|
||||
const techRadarProps = {
|
||||
width: 1200,
|
||||
height: 800,
|
||||
getData: techRadarLoadFail,
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
});
|
||||
};
|
||||
|
||||
const { queryByTestId } = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.from([
|
||||
[errorApiRef, errorApi],
|
||||
[techRadarApiRef, techRadarApi],
|
||||
])}
|
||||
>
|
||||
<RadarPage />
|
||||
<ApiProvider apis={ApiRegistry.with(errorApiRef, errorApi)}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
await waitForElement(() => !queryByTestId('progress'));
|
||||
|
||||
expect(errorApi.post).toHaveBeenCalledTimes(1);
|
||||
expect(errorApi.post).toHaveBeenCalledWith(new Error('404 Page Not Found'));
|
||||
expect(errorApi.getErrors()).toEqual([
|
||||
{ error: new Error('404 Page Not Found'), context: undefined },
|
||||
]);
|
||||
expect(queryByTestId('tech-radar-svg')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render without errorApiRef', () => {
|
||||
const techRadarApi = new TechRadar({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
});
|
||||
|
||||
expect(
|
||||
withLogCollector(['error'], () => {
|
||||
expect(() => {
|
||||
render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.from([[techRadarApiRef, techRadarApi]])}
|
||||
>
|
||||
<RadarPage />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
}).toThrow();
|
||||
}).error[0],
|
||||
).toMatch(
|
||||
/^Error: Uncaught \[Error: No implementation available for apiRef{core.error}\]/,
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render without techRadarApiRef', () => {
|
||||
const errorApi = { post: () => {} };
|
||||
|
||||
expect(
|
||||
withLogCollector(['error'], () => {
|
||||
expect(() => {
|
||||
render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider apis={ApiRegistry.from([[errorApiRef, errorApi]])}>
|
||||
<RadarPage />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
}).toThrow();
|
||||
}).error[0],
|
||||
).toMatch(
|
||||
/^Error: Uncaught \[Error: No implementation available for apiRef{plugin.techradar}\]/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,36 +24,46 @@ import {
|
||||
HeaderLabel,
|
||||
SupportButton,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import RadarComponent from '../components/RadarComponent';
|
||||
import { techRadarApiRef, TechRadarApi } from '../api';
|
||||
import { TechRadarComponentProps } from '../api';
|
||||
|
||||
const RadarPage = (): JSX.Element => {
|
||||
const techRadarApi = useApi<TechRadarApi>(techRadarApiRef);
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Header title={techRadarApi.title} subtitle={techRadarApi.subtitle}>
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Beta" />
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title={techRadarApi.pageTitle}>
|
||||
<SupportButton>
|
||||
This is used for visualizing the official guidelines of different
|
||||
areas of software development such as languages, frameworks,
|
||||
infrastructure and processes.
|
||||
</SupportButton>
|
||||
</ContentHeader>
|
||||
<Grid container spacing={3} direction="row">
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<RadarComponent {...techRadarApi} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
export type TechRadarPageProps = TechRadarComponentProps & {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
pageTitle?: string;
|
||||
};
|
||||
|
||||
export default RadarPage;
|
||||
export const RadarPage = ({
|
||||
title,
|
||||
subtitle,
|
||||
pageTitle,
|
||||
...props
|
||||
}: TechRadarPageProps): JSX.Element => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Header title={title} subtitle={subtitle}>
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Beta" />
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title={pageTitle}>
|
||||
<SupportButton>
|
||||
This is used for visualizing the official guidelines of different
|
||||
areas of software development such as languages, frameworks,
|
||||
infrastructure and processes.
|
||||
</SupportButton>
|
||||
</ContentHeader>
|
||||
<Grid container spacing={3} direction="row">
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<RadarComponent {...props} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
RadarPage.defaultProps = {
|
||||
title: 'Tech Radar',
|
||||
subtitle: 'Pick the recommended technologies for your projects',
|
||||
pageTitle: 'Company Radar',
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
export { plugin } from './plugin';
|
||||
|
||||
export { RadarPage as Router } from './components/RadarPage';
|
||||
|
||||
/**
|
||||
* The TypeScript API for configuring Tech Radar.
|
||||
*/
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import RadarPage from './components/RadarPage';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'tech-radar',
|
||||
register({ router }) {
|
||||
router.registerRoute('/tech-radar', RadarPage);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user