feat(core): add support config & button/error components
This adds a new app.support top level config that can be used to configure various support links and other information. This can later be extended for plugins to append their own specific support items.
This commit is contained in:
@@ -33,9 +33,8 @@ export const EntityLinksCard = ({ cols = undefined }: Props) => {
|
||||
const { entity } = useEntity();
|
||||
const app = useApp();
|
||||
|
||||
const iconResolver = (key: IconKey | undefined): IconComponent => {
|
||||
return app.getSystemIcon(key ?? '') ?? LanguageIcon;
|
||||
};
|
||||
const iconResolver = (key: IconKey | undefined): IconComponent =>
|
||||
key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;
|
||||
|
||||
const links = entity?.metadata?.links;
|
||||
|
||||
|
||||
+20
-16
@@ -17,9 +17,9 @@
|
||||
import { DomainEntity } from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { DomainExplorerContent } from './DomainExplorerContent';
|
||||
|
||||
describe('<DomainExplorerContent />', () => {
|
||||
@@ -33,11 +33,9 @@ describe('<DomainExplorerContent />', () => {
|
||||
};
|
||||
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
<MemoryRouter>
|
||||
<ApiProvider apis={ApiRegistry.with(catalogApiRef, catalogApi)}>
|
||||
{children}
|
||||
</ApiProvider>
|
||||
</MemoryRouter>
|
||||
<ApiProvider apis={ApiRegistry.with(catalogApiRef, catalogApi)}>
|
||||
{children}
|
||||
</ApiProvider>
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -69,9 +67,11 @@ describe('<DomainExplorerContent />', () => {
|
||||
];
|
||||
catalogApi.getEntities.mockResolvedValue({ items: entities });
|
||||
|
||||
const { getByText } = render(<DomainExplorerContent />, {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<DomainExplorerContent />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('artists')).toBeInTheDocument();
|
||||
@@ -82,9 +82,11 @@ describe('<DomainExplorerContent />', () => {
|
||||
it('renders empty state', async () => {
|
||||
catalogApi.getEntities.mockResolvedValue({ items: [] });
|
||||
|
||||
const { getByText } = render(<DomainExplorerContent />, {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<DomainExplorerContent />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(getByText('No domains to display')).toBeInTheDocument(),
|
||||
@@ -95,9 +97,11 @@ describe('<DomainExplorerContent />', () => {
|
||||
const catalogError = new Error('Network timeout');
|
||||
catalogApi.getEntities.mockRejectedValueOnce(catalogError);
|
||||
|
||||
const { getByText } = render(<DomainExplorerContent />, {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<DomainExplorerContent />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(getByText(/Could not load domains/)).toBeInTheDocument(),
|
||||
|
||||
@@ -19,11 +19,11 @@ import {
|
||||
ExploreTool,
|
||||
exploreToolsConfigRef,
|
||||
} from '@backstage/plugin-explore-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { ToolExplorerContent } from './ToolExplorerContent';
|
||||
|
||||
describe('<ToolExplorerContent />', () => {
|
||||
@@ -33,13 +33,11 @@ describe('<ToolExplorerContent />', () => {
|
||||
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<MemoryRouter>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.with(exploreToolsConfigRef, exploreToolsConfigApi)}
|
||||
>
|
||||
{children}
|
||||
</ApiProvider>
|
||||
</MemoryRouter>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.with(exploreToolsConfigRef, exploreToolsConfigApi)}
|
||||
>
|
||||
{children}
|
||||
</ApiProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
@@ -70,9 +68,11 @@ describe('<ToolExplorerContent />', () => {
|
||||
];
|
||||
exploreToolsConfigApi.getTools.mockResolvedValue(tools);
|
||||
|
||||
const { getByText } = render(<ToolExplorerContent />, {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<ToolExplorerContent />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Lighthouse')).toBeInTheDocument();
|
||||
@@ -83,9 +83,11 @@ describe('<ToolExplorerContent />', () => {
|
||||
it('renders empty state', async () => {
|
||||
exploreToolsConfigApi.getTools.mockResolvedValue([]);
|
||||
|
||||
const { getByText } = render(<ToolExplorerContent />, {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<ToolExplorerContent />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(getByText('No tools to display')).toBeInTheDocument(),
|
||||
|
||||
@@ -14,23 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import ProfileCatalog from './ProfileCatalog';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import {
|
||||
ApiProvider,
|
||||
ApiRegistry,
|
||||
githubAuthApiRef,
|
||||
GithubAuth,
|
||||
githubAuthApiRef,
|
||||
OAuthRequestManager,
|
||||
UrlPatternDiscovery,
|
||||
} from '@backstage/core';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { gitOpsApiRef, GitOpsRestApi } from '../../api';
|
||||
import ProfileCatalog from './ProfileCatalog';
|
||||
|
||||
describe('ProfileCatalog', () => {
|
||||
it('should render', () => {
|
||||
it('should render', async () => {
|
||||
const oauthRequestApi = new OAuthRequestManager();
|
||||
const apis = ApiRegistry.from([
|
||||
[gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')],
|
||||
@@ -44,15 +44,15 @@ describe('ProfileCatalog', () => {
|
||||
}),
|
||||
],
|
||||
]);
|
||||
const rendered = render(
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider apis={apis}>
|
||||
<ProfileCatalog />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
expect(
|
||||
rendered.getByText('Create GitOps-managed Cluster'),
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(getByText('Create GitOps-managed Cluster')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
+20
-22
@@ -21,11 +21,10 @@ import {
|
||||
errorApiRef,
|
||||
} from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { RegisterComponentPage } from './RegisterComponentPage';
|
||||
|
||||
const errorApi: jest.Mocked<typeof errorApiRef.T> = {
|
||||
@@ -44,30 +43,29 @@ const catalogApi: jest.Mocked<typeof catalogApiRef.T> = {
|
||||
};
|
||||
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
<MemoryRouter>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.with(errorApiRef, errorApi).with(
|
||||
catalogApiRef,
|
||||
catalogApi,
|
||||
)}
|
||||
>
|
||||
<ThemeProvider theme={lightTheme}>{children}</ThemeProvider>
|
||||
</ApiProvider>
|
||||
</MemoryRouter>
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.with(errorApiRef, errorApi).with(
|
||||
catalogApiRef,
|
||||
catalogApi,
|
||||
)}
|
||||
>
|
||||
<ThemeProvider theme={lightTheme}>{children}</ThemeProvider>
|
||||
</ApiProvider>
|
||||
);
|
||||
|
||||
describe('RegisterComponentPage', () => {
|
||||
it('should render', () => {
|
||||
render(
|
||||
<RegisterComponentPage
|
||||
catalogRouteRef={createRouteRef({
|
||||
path: '/catalog',
|
||||
title: 'Service Catalog',
|
||||
})}
|
||||
/>,
|
||||
{ wrapper: Wrapper },
|
||||
it('should render', async () => {
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Wrapper>
|
||||
<RegisterComponentPage
|
||||
catalogRouteRef={createRouteRef({
|
||||
path: '/catalog',
|
||||
title: 'Service Catalog',
|
||||
})}
|
||||
/>
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Register existing component')).toBeInTheDocument();
|
||||
expect(getByText('Register existing component')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,16 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, waitForElement } from '@testing-library/react';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
import {
|
||||
MockErrorApi,
|
||||
renderInTestApp,
|
||||
wrapInTestApp,
|
||||
} from '@backstage/test-utils';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core';
|
||||
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { render, waitForElement } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import GetBBoxPolyfill from '../utils/polyfills/getBBox';
|
||||
import { RadarPage } from './RadarPage';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MockErrorApi, wrapInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('RadarPage', () => {
|
||||
beforeAll(() => {
|
||||
@@ -67,12 +70,10 @@ describe('RadarPage', () => {
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
};
|
||||
|
||||
const { getByText, getByTestId } = render(
|
||||
wrapInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ThemeProvider>,
|
||||
),
|
||||
const { getByText, getByTestId } = await renderInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
await waitForElement(() => getByTestId('tech-radar-svg'));
|
||||
@@ -94,7 +95,7 @@ describe('RadarPage', () => {
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
};
|
||||
|
||||
const { queryByTestId } = render(
|
||||
const { queryByTestId } = await renderInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider apis={ApiRegistry.with(errorApiRef, errorApi)}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
|
||||
@@ -14,23 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import WelcomePage from './WelcomePage';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import {
|
||||
ApiProvider,
|
||||
ApiRegistry,
|
||||
errorApiRef,
|
||||
configApiRef,
|
||||
ConfigReader,
|
||||
errorApiRef,
|
||||
} from '@backstage/core';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import WelcomePage from './WelcomePage';
|
||||
|
||||
describe('WelcomePage', () => {
|
||||
it('should render', () => {
|
||||
// TODO: use common test app with mock implementations of all core APIs
|
||||
const rendered = render(
|
||||
it('should render', async () => {
|
||||
const { baseElement } = await renderInTestApp(
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.from([
|
||||
[errorApiRef, { post: jest.fn() }],
|
||||
@@ -42,6 +41,6 @@ describe('WelcomePage', () => {
|
||||
</ThemeProvider>
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(rendered.baseElement).toBeInTheDocument();
|
||||
expect(baseElement).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user