feat: added new simple router with some tests

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2022-02-04 15:42:56 +01:00
parent 5c067a3562
commit 06ce6d19d5
3 changed files with 180 additions and 0 deletions
@@ -0,0 +1,83 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { TemplateListPage } from '../TemplateListPage';
import { TemplateWizardPage } from '../TemplateWizardPage';
import { Router } from './Router';
import { renderInTestApp } from '@backstage/test-utils';
import {
createScaffolderFieldExtension,
ScaffolderFieldExtensions,
} from '../../extensions';
import { scaffolderPlugin } from '../../plugin';
jest.mock('../TemplateListPage', () => ({
TemplateListPage: jest.fn(() => null),
}));
jest.mock('../TemplateWizardPage', () => ({
TemplateWizardPage: jest.fn(() => null),
}));
describe('Router', () => {
beforeEach(() => {
(TemplateWizardPage as jest.Mock).mockClear();
(TemplateListPage as jest.Mock).mockClear();
});
describe('/', () => {
it('should render the TemplateListPage', async () => {
await renderInTestApp(<Router />);
expect(TemplateListPage).toHaveBeenCalled();
});
});
describe('/templates/:templateName', () => {
it('should render the TemplateWizard page', async () => {
await renderInTestApp(<Router />, { routeEntries: ['/templates/foo'] });
expect(TemplateWizardPage).toHaveBeenCalled();
});
it('should extract the fieldExtensions and pass them through', async () => {
const mockComponent = () => null;
const CustomFieldExtension = scaffolderPlugin.provide(
createScaffolderFieldExtension({
name: 'custom',
component: mockComponent,
}),
);
await renderInTestApp(
<Router>
<ScaffolderFieldExtensions>
<CustomFieldExtension />
</ScaffolderFieldExtensions>
</Router>,
{ routeEntries: ['/templates/foo'] },
);
const mock = TemplateWizardPage as jest.Mock;
const [{ customFieldExtensions }] = mock.mock.calls[0];
expect(customFieldExtensions).toEqual(
expect.arrayContaining([
expect.objectContaining({ name: 'custom', component: mockComponent }),
]),
);
});
});
});
@@ -0,0 +1,81 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { PropsWithChildren } from 'react';
import { Routes, Route, useOutlet } from 'react-router';
import { TemplateListPage } from '../TemplateListPage';
import { SecretsContextProvider } from '../TemplateWizardPage/SecretsContext';
import { TemplateWizardPage } from '../TemplateWizardPage';
import {
FieldExtensionOptions,
FIELD_EXTENSION_WRAPPER_KEY,
FIELD_EXTENSION_KEY,
DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS,
} from '../../extensions';
import { useElementFilter } from '@backstage/core-plugin-api';
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
export type RouterProps = {
TemplateCardComponent?: React.ComponentType<{
template: TemplateEntityV1beta3;
}>;
};
export const Router = (props: PropsWithChildren<RouterProps>) => {
const { TemplateCardComponent } = props;
const outlet = useOutlet() || props.children;
const customFieldExtensions = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: FIELD_EXTENSION_WRAPPER_KEY,
})
.findComponentData<FieldExtensionOptions>({
key: FIELD_EXTENSION_KEY,
}),
);
const fieldExtensions = [
...customFieldExtensions,
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(
({ name }) =>
!customFieldExtensions.some(
customFieldExtension => customFieldExtension.name === name,
),
),
];
return (
<Routes>
<Route
path="/"
element={
<TemplateListPage TemplateCardComponent={TemplateCardComponent} />
}
/>
<Route
path="/templates/:templateName"
element={
<SecretsContextProvider>
<TemplateWizardPage customFieldExtensions={fieldExtensions} />
</SecretsContextProvider>
}
/>
</Routes>
);
};
@@ -0,0 +1,16 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { Router } from './Router';