diff --git a/packages/frontend-app-api/src/apis/implementations/SwappableComponentsApi/DefaultSwappableComponentsApi.test.tsx b/packages/frontend-app-api/src/apis/implementations/SwappableComponentsApi/DefaultSwappableComponentsApi.test.tsx
index e71ad50bfb..78b4c6f596 100644
--- a/packages/frontend-app-api/src/apis/implementations/SwappableComponentsApi/DefaultSwappableComponentsApi.test.tsx
+++ b/packages/frontend-app-api/src/apis/implementations/SwappableComponentsApi/DefaultSwappableComponentsApi.test.tsx
@@ -14,15 +14,22 @@
* limitations under the License.
*/
-import { createSwappableComponent } from '@backstage/frontend-plugin-api';
+import {
+ ApiBlueprint,
+ createExtensionInput,
+ createSwappableComponent,
+ SwappableComponentBlueprint,
+ swappableComponentsApiRef,
+} from '@backstage/frontend-plugin-api';
import { DefaultSwappableComponentsApi } from './DefaultSwappableComponentsApi';
import { render, screen } from '@testing-library/react';
+import { renderInTestApp } from '@backstage/frontend-test-utils';
const { ref: testRefA } = createSwappableComponent({ id: 'test.a' });
const { ref: testRefB1 } = createSwappableComponent({ id: 'test.b' });
const { ref: testRefB2 } = createSwappableComponent({ id: 'test.b' });
-describe('DefaultComponentsApi', () => {
+describe('DefaultSwappableComponentsApi', () => {
it('should provide components', async () => {
const api = DefaultSwappableComponentsApi.fromComponents([
{
@@ -53,4 +60,205 @@ describe('DefaultComponentsApi', () => {
await expect(screen.findByText('test.b')).resolves.toBeInTheDocument();
});
+
+ describe('integration tests', () => {
+ const api = ApiBlueprint.makeWithOverrides({
+ name: 'swappable-components',
+ inputs: {
+ components: createExtensionInput([
+ SwappableComponentBlueprint.dataRefs.component,
+ ]),
+ },
+ factory: (originalFactory, { inputs }) => {
+ return originalFactory(defineParams =>
+ defineParams({
+ api: swappableComponentsApiRef,
+ deps: {},
+ factory: () =>
+ DefaultSwappableComponentsApi.fromComponents(
+ inputs.components.map(i =>
+ i.get(SwappableComponentBlueprint.dataRefs.component),
+ ),
+ ),
+ }),
+ );
+ },
+ });
+
+ describe('no api provided', () => {
+ it('should render the fallback if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ });
+
+ renderInTestApp(, {});
+
+ await expect(
+ screen.findByTestId('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render the default compnoent if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => () =>
test.mock
,
+ });
+
+ renderInTestApp(, {});
+
+ await expect(
+ screen.findByText('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render async loader component if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: async () => () => test.mock
,
+ });
+
+ renderInTestApp(, {});
+
+ await expect(
+ screen.findByText('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should transform props correctly', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => (props: { inner: string }) =>
+ inner: {props.inner}
,
+ transformProps: (props: { external: string }) => ({
+ inner: props.external,
+ }),
+ });
+
+ renderInTestApp(, {});
+
+ await expect(
+ screen.findByText('inner: test'),
+ ).resolves.toBeInTheDocument();
+ });
+ });
+
+ describe('with overrides', () => {
+ it('should render the fallback if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ });
+
+ renderInTestApp(, {
+ extensions: [api],
+ });
+
+ await expect(
+ screen.findByTestId('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render the default compnoent if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => () => test.mock
,
+ });
+
+ renderInTestApp(, {
+ extensions: [api],
+ });
+
+ await expect(
+ screen.findByText('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render async loader component if no other component is provided', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: async () => () => test.mock
,
+ });
+
+ renderInTestApp(, {
+ extensions: [api],
+ });
+
+ await expect(
+ screen.findByText('test.mock'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render the component provided by the blueprint', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => () => test.mock
,
+ });
+
+ const override = SwappableComponentBlueprint.make({
+ params: define =>
+ define({
+ component: MockComponent,
+ loader: () => () => Overriden!
,
+ }),
+ });
+
+ renderInTestApp(, {
+ extensions: [api, override],
+ });
+
+ await expect(
+ screen.findByText('Overriden!'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should render the async component provided by the blueprint', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => () => test.mock
,
+ });
+
+ const override = SwappableComponentBlueprint.make({
+ params: define =>
+ define({
+ component: MockComponent,
+ loader: async () => () => Overriden!
,
+ }),
+ });
+
+ renderInTestApp(, {
+ extensions: [api, override],
+ });
+
+ await expect(
+ screen.findByText('Overriden!'),
+ ).resolves.toBeInTheDocument();
+ });
+
+ it('should transform props correctly', async () => {
+ const MockComponent = createSwappableComponent({
+ id: 'test.mock',
+ loader: () => (props: { inner: string }) =>
+ inner: {props.inner}
,
+ transformProps: (props: { external: string }) => ({
+ inner: props.external,
+ }),
+ });
+
+ const override = SwappableComponentBlueprint.make({
+ params: define =>
+ define({
+ component: MockComponent,
+ loader: () => props => overriden: {props.inner}
,
+ }),
+ });
+
+ renderInTestApp(, {
+ extensions: [api, override],
+ });
+
+ await expect(
+ screen.findByText('overriden: test'),
+ ).resolves.toBeInTheDocument();
+ });
+ });
+ });
});
diff --git a/plugins/app/src/extensions/SwappableComponentsApi.ts b/plugins/app/src/extensions/SwappableComponentsApi.ts
index 5809f90be2..3964fc172a 100644
--- a/plugins/app/src/extensions/SwappableComponentsApi.ts
+++ b/plugins/app/src/extensions/SwappableComponentsApi.ts
@@ -29,10 +29,9 @@ import { DefaultSwappableComponentsApi } from '../../../../packages/frontend-app
export const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({
name: 'swappable-components',
inputs: {
- components: createExtensionInput(
- [SwappableComponentBlueprint.dataRefs.component],
- { replaces: [{ id: 'app', input: 'components' }] },
- ),
+ components: createExtensionInput([
+ SwappableComponentBlueprint.dataRefs.component,
+ ]),
},
factory: (originalFactory, { inputs }) => {
return originalFactory(defineParams =>