From 85840e0a1f3de29aaa6e4d163c6d614015fcb938 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 9 Oct 2023 19:42:52 +0200 Subject: [PATCH] frontend-app-api: add tests for extension overrides Signed-off-by: Patrik Oldsberg --- .../src/wiring/createApp.test.tsx | 28 ++++++++ .../src/wiring/parameters.test.ts | 69 ++++++++++++++++++- 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index 1a5aca673a..b4107f0249 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -16,6 +16,7 @@ import { createExtension, + createExtensionOverrides, createPageExtension, createPlugin, createThemeExtension, @@ -27,6 +28,13 @@ import React from 'react'; import { createRouteRef } from '@backstage/core-plugin-api'; import { createExtensionInstance } from './createExtensionInstance'; +const extBaseConfig = { + id: 'test', + attachTo: { id: 'root', input: 'default' }, + output: {}, + factory() {}, +}; + describe('createInstances', () => { it('throws an error when a root extension is parametrized', () => { const config = new MockConfigApi({ @@ -103,6 +111,26 @@ describe('createInstances', () => { "The following extensions are duplicated: The extension 'A' was provided 2 time(s) by the plugin 'A' and 1 time(s) by the plugin 'B', The extension 'B' was provided 2 time(s) by the plugin 'B'", ); }); + + it('throws an error when duplicated extension overrides are detected', () => { + expect(() => + createInstances({ + config: new MockConfigApi({}), + features: [ + createExtensionOverrides({ + extensions: [ + createExtension({ ...extBaseConfig, id: 'a' }), + createExtension({ ...extBaseConfig, id: 'a' }), + createExtension({ ...extBaseConfig, id: 'b' }), + ], + }), + createExtensionOverrides({ + extensions: [createExtension({ ...extBaseConfig, id: 'b' })], + }), + ], + }), + ).toThrow('The following extensions had duplicate overrides: a, b'); + }); }); describe('createApp', () => { diff --git a/packages/frontend-app-api/src/wiring/parameters.test.ts b/packages/frontend-app-api/src/wiring/parameters.test.ts index 24d68301f1..4ee420f667 100644 --- a/packages/frontend-app-api/src/wiring/parameters.test.ts +++ b/packages/frontend-app-api/src/wiring/parameters.test.ts @@ -15,7 +15,11 @@ */ import { ConfigReader } from '@backstage/config'; -import { createPlugin, Extension } from '@backstage/frontend-plugin-api'; +import { + createExtensionOverrides, + createPlugin, + Extension, +} from '@backstage/frontend-plugin-api'; import { JsonValue } from '@backstage/types'; import { expandShorthandExtensionParameters, @@ -23,10 +27,14 @@ import { readAppExtensionParameters, } from './parameters'; -function makeExt(id: string, status: 'disabled' | 'enabled' = 'enabled') { +function makeExt( + id: string, + status: 'disabled' | 'enabled' = 'enabled', + attachId: string = 'root', +) { return { id, - attachTo: { id: 'root', input: 'default' }, + attachTo: { id: attachId, input: 'default' }, disabled: status === 'disabled', } as Extension; } @@ -144,6 +152,61 @@ describe('mergeExtensionParameters', () => { { extension: a, attachTo: { id: 'root', input: 'default' } }, ]); }); + + it('should apply extension overrides', () => { + const a = makeExt('a'); + const b = makeExt('b'); + const plugin = createPlugin({ id: 'test', extensions: [a, b] }); + const aOverride = makeExt('a', 'enabled', 'other'); + const bOverride = makeExt('b', 'disabled', 'other'); + const cOverride = makeExt('c'); + + const result = mergeExtensionParameters({ + features: [ + plugin, + createExtensionOverrides({ + extensions: [aOverride, bOverride, cOverride], + }), + ], + builtinExtensions: [], + parameters: [], + }); + + expect(result.length).toBe(2); + expect(result[0].extension).toBe(aOverride); + expect(result[0].attachTo).toEqual({ id: 'other', input: 'default' }); + expect(result[0].config).toEqual(undefined); + expect(result[0].source).toBe(plugin); + + expect(result[1]).toEqual({ + extension: cOverride, + attachTo: { id: 'root', input: 'default' }, + config: undefined, + source: undefined, + }); + }); + + it('should use order from configuration when rather than overrides', () => { + const a = makeExt('a', 'disabled'); + const b = makeExt('b', 'disabled'); + const c = makeExt('c', 'disabled'); + const aOverride = makeExt('c', 'disabled'); + const bOverride = makeExt('b', 'disabled'); + const cOverride = makeExt('a', 'disabled'); + + const result = mergeExtensionParameters({ + features: [ + createPlugin({ id: 'test', extensions: [a, b, c] }), + createExtensionOverrides({ + extensions: [cOverride, bOverride, aOverride], + }), + ], + builtinExtensions: [], + parameters: ['b', 'c', 'a'].map(id => ({ id, disabled: false })), + }); + + expect(result.map(r => r.extension.id)).toEqual(['b', 'c', 'a']); + }); }); describe('readAppExtensionParameters', () => {