chore: more tests

Signed-off-by: benjdlambert <ben@blam.sh>

Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
benjdlambert
2025-08-04 16:50:53 +02:00
parent aab7bc21cd
commit eeade86c09
2 changed files with 118 additions and 1 deletions
@@ -13,11 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { renderInTestApp } from '@backstage/frontend-test-utils';
import { createComponentRef } from '../components';
import { makeComponentFromRef } from '../components/makeComponentFromRef';
import { ComponentImplementationBlueprint } from './ComponentImplementationBlueprint';
import { PageBlueprint } from './PageBlueprint';
import { waitFor, screen } from '@testing-library/react';
describe('ComponentImplementationBlueprint', () => {
it('should allow defining a component override for sync component ref', () => {
it('should allow defining a component override for a component ref', () => {
const componentRef = createComponentRef({
id: 'test.component',
loader: () => (props: { hello: string }) => <div>{props.hello}</div>,
@@ -38,4 +42,115 @@ describe('ComponentImplementationBlueprint', () => {
expect(extension).toBeDefined();
});
it('should render default component refs in the app', async () => {
const testComponentRef = createComponentRef({
id: 'test.component',
loader: () => (props: { hello: string }) => <div>{props.hello}</div>,
});
const TestComponent = makeComponentFromRef({ ref: testComponentRef });
renderInTestApp(<div />, {
extensions: [
PageBlueprint.make({
params: define =>
define({
// todo(blam): there's a bug that this path cannot be `/`?
defaultPath: '/test',
loader: async () => <TestComponent hello="test!" />,
}),
}),
],
initialRouteEntries: ['/test'],
});
await waitFor(() => expect(screen.getByText('test!')).toBeInTheDocument());
});
it('should render a component ref without a default implementation', async () => {
const testComponentRef = createComponentRef({
id: 'test.component',
});
const TestComponent = makeComponentFromRef({ ref: testComponentRef });
renderInTestApp(<div />, {
extensions: [
PageBlueprint.make({
params: define =>
define({
defaultPath: '/test',
loader: async () => <TestComponent />,
}),
}),
],
initialRouteEntries: ['/test'],
});
await waitFor(() =>
expect(screen.getByTestId('test.component')).toBeInTheDocument(),
);
});
it('should render a component ref with an async loader implementation', async () => {
const testComponentRef = createComponentRef({
id: 'test.component',
loader: async () => (props: { hello: string }) =>
<div>{props.hello}</div>,
});
const TestComponent = makeComponentFromRef({ ref: testComponentRef });
renderInTestApp(<div />, {
extensions: [
PageBlueprint.make({
params: define =>
define({
// todo(blam): there's a bug that this path cannot be `/`?
defaultPath: '/test',
loader: async () => <TestComponent hello="test!" />,
}),
}),
],
initialRouteEntries: ['/test'],
});
await waitFor(() => expect(screen.getByText('test!')).toBeInTheDocument());
});
it('should allow overriding a component ref with the blueprint', async () => {
const testComponentRef = createComponentRef({
id: 'test.component',
loader: () => (props: { hello: string }) => <div>{props.hello}</div>,
});
const TestComponent = makeComponentFromRef({ ref: testComponentRef });
const extension = ComponentImplementationBlueprint.make({
params: define =>
define({
ref: testComponentRef,
loader: () => props => <div>Override {props.hello}</div>,
}),
});
renderInTestApp(<div />, {
extensions: [
extension,
PageBlueprint.make({
params: define =>
define({
defaultPath: '/test',
loader: async () => <TestComponent hello="test!" />,
}),
}),
],
initialRouteEntries: ['/test'],
});
await waitFor(() =>
expect(screen.getByText('Override test!')).toBeInTheDocument(),
);
});
});
@@ -16,6 +16,7 @@
import { lazy, Suspense } from 'react';
import { ComponentRef } from './createComponentRef';
import { OpaqueComponentRef } from '@internal/frontend';
import { componentsApiRef, useApi } from '../apis';
export function makeComponentFromRef<
InternalComponentProps extends {},
@@ -31,6 +32,7 @@ export function makeComponentFromRef<
);
const ComponentRefImpl = (props: ExternalComponentProps) => {
const api = useApi(componentsApiRef);
const innerProps = options.transformProps?.(props) ?? props;
const ComponentOrPromise = options.loader?.() ?? FallbackComponent;