Merge pull request #15312 from agentbellnorm/techdocs/support-older-react-router

[TechDocs] Support older versions of react router
This commit is contained in:
Morgan Bentell
2022-12-20 11:00:19 +01:00
committed by GitHub
8 changed files with 103 additions and 2 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-techdocs-react': minor
'@backstage/plugin-techdocs': patch
---
Support older versions of react-router
+3
View File
@@ -32,6 +32,9 @@ export const SHADOW_DOM_STYLE_LOAD_EVENT = 'TECH_DOCS_SHADOW_DOM_STYLE_LOAD';
// @public
export type SyncResult = 'cached' | 'updated';
// @public
export const TECHDOCS_ADDONS_KEY = 'techdocs.addons.addon.v1';
// @public
export const TECHDOCS_ADDONS_WRAPPER_KEY = 'techdocs.addons.wrapper.v1';
+4
View File
@@ -27,6 +27,10 @@ import {
import { TechDocsAddonLocations, TechDocsAddonOptions } from './types';
/**
* Key for each addon.
* @public
*/
export const TECHDOCS_ADDONS_KEY = 'techdocs.addons.addon.v1';
/**
+1
View File
@@ -25,6 +25,7 @@ export {
createTechDocsAddonExtension,
TechDocsAddons,
TECHDOCS_ADDONS_WRAPPER_KEY,
TECHDOCS_ADDONS_KEY,
} from './addons';
export { techdocsApiRef, techdocsStorageApiRef } from './api';
export type { SyncResult, TechDocsApi, TechDocsStorageApi } from './api';
+1
View File
@@ -67,6 +67,7 @@
"@backstage/cli": "workspace:^",
"@backstage/core-app-api": "workspace:^",
"@backstage/dev-utils": "workspace:^",
"@backstage/plugin-techdocs-module-addons-contrib": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
@@ -27,6 +27,12 @@ import { techdocsApiRef, techdocsStorageApiRef } from '../../../api';
import { rootRouteRef, rootDocsRouteRef } from '../../../routes';
import { TechDocsReaderPage } from './TechDocsReaderPage';
import { Route, useParams } from 'react-router-dom';
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { FlatRoutes } from '@backstage/core-app-api';
import { Page } from '@backstage/core-components';
const mockEntityMetadata = {
locationMetadata: {
@@ -66,6 +72,16 @@ const techdocsStorageApiMock: jest.Mocked<typeof techdocsStorageApiRef.T> = {
syncEntityDocs: jest.fn(),
};
const PageMock = () => {
const { namespace, kind, name } = useParams();
return <>{`PageMock: ${namespace}#${kind}#${name}`}</>;
};
jest.mock('@backstage/core-components', () => ({
...jest.requireActual('@backstage/core-components'),
Page: jest.fn(),
}));
const Wrapper = ({ children }: { children: React.ReactNode }) => {
return (
<ThemeProvider theme={lightTheme}>
@@ -97,6 +113,12 @@ describe('<TechDocsReaderPage />', () => {
afterEach(() => {
jest.resetAllMocks();
});
beforeEach(() => {
const realPage = jest.requireActual('@backstage/core-components').Page;
(Page as jest.Mock).mockImplementation(realPage);
});
it('should render a techdocs reader page without children', async () => {
const rendered = await renderInTestApp(
<Wrapper>
@@ -146,4 +168,63 @@ describe('<TechDocsReaderPage />', () => {
expect(rendered.getByText('techdocs reader page')).toBeInTheDocument();
});
});
it('should render techdocs reader page with addons', async () => {
(Page as jest.Mock).mockImplementation(PageMock);
const name = 'test-name';
const namespace = 'test-namespace';
const kind = 'test';
await act(async () => {
const rendered = await renderInTestApp(
<Wrapper>
<FlatRoutes>
<Route
path="/docs/:namespace/:kind/:name/*"
element={<TechDocsReaderPage />}
>
<TechDocsAddons>
<ReportIssue />
</TechDocsAddons>
</Route>
</FlatRoutes>
</Wrapper>,
{
mountedRoutes,
routeEntries: ['/docs/test-namespace/test/test-name'],
},
);
expect(
rendered.getByText(`PageMock: ${namespace}#${kind}#${name}`),
).toBeInTheDocument();
});
});
it('should render techdocs reader page with addons and page', async () => {
(Page as jest.Mock).mockImplementation(PageMock);
await act(async () => {
const rendered = await renderInTestApp(
<Wrapper>
<FlatRoutes>
<Route
path="/docs/:namespace/:kind/:name/*"
element={<TechDocsReaderPage />}
>
<p>the page</p>
<TechDocsAddons>
<ReportIssue />
</TechDocsAddons>
</Route>
</FlatRoutes>
</Wrapper>,
{
mountedRoutes,
routeEntries: ['/docs/test-namespace/test/test-name'],
},
);
expect(rendered.getByText('the page')).toBeInTheDocument();
});
});
});
@@ -21,6 +21,7 @@ import { Page } from '@backstage/core-components';
import { CompoundEntityRef } from '@backstage/catalog-model';
import {
TECHDOCS_ADDONS_WRAPPER_KEY,
TECHDOCS_ADDONS_KEY,
TechDocsReaderPageProvider,
} from '@backstage/plugin-techdocs-react';
@@ -165,11 +166,14 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {
if (!children) {
const childrenList = outlet ? Children.toArray(outlet.props.children) : [];
const grandChildren = childrenList.flatMap(
const grandChildren = childrenList.flatMap<ReactElement>(
child => (child as ReactElement)?.props?.children ?? [],
);
const page: React.ReactNode = grandChildren.find(
grandChild => !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY),
grandChild =>
!getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&
!getComponentData(grandChild, TECHDOCS_ADDONS_KEY),
);
// As explained above, "page" is configuration 4 and <TechDocsReaderLayout> is 1
+1
View File
@@ -8263,6 +8263,7 @@ __metadata:
"@backstage/plugin-catalog-react": "workspace:^"
"@backstage/plugin-search-common": "workspace:^"
"@backstage/plugin-search-react": "workspace:^"
"@backstage/plugin-techdocs-module-addons-contrib": "workspace:^"
"@backstage/plugin-techdocs-react": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/theme": "workspace:^"