From 540a03171cbd0ee8140e8abbe7ec76de9801531f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Apr 2026 11:28:38 +0200 Subject: [PATCH] Add missing changeset and test coverage for PR review gaps Add changeset for catalog-react blueprint migration. Add tests for cross-style config merge (configSchema + deprecated config.schema), deprecation warning emission, and empty configSchema edge case. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- .../catalog-react-configschema-migration.md | 5 ++ .../src/schema/createPortableSchema.test.ts | 16 +++++ .../wiring/createExtensionBlueprint.test.tsx | 64 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 .changeset/catalog-react-configschema-migration.md diff --git a/.changeset/catalog-react-configschema-migration.md b/.changeset/catalog-react-configschema-migration.md new file mode 100644 index 0000000000..766dbef24f --- /dev/null +++ b/.changeset/catalog-react-configschema-migration.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Migrated alpha entity blueprints to use the new `configSchema` option with direct zod schema values. diff --git a/packages/frontend-plugin-api/src/schema/createPortableSchema.test.ts b/packages/frontend-plugin-api/src/schema/createPortableSchema.test.ts index 81b3ce3dc8..d612578f32 100644 --- a/packages/frontend-plugin-api/src/schema/createPortableSchema.test.ts +++ b/packages/frontend-plugin-api/src/schema/createPortableSchema.test.ts @@ -334,4 +334,20 @@ describe('createConfigSchema', () => { ); }); }); + + describe('edge cases', () => { + it('should handle an empty configSchema', () => { + const schema = createConfigSchema({}); + + expect(schema.parse({})).toEqual({}); + expect(schema.parse(undefined)).toEqual({}); + + const result = schema.schema(); + expect(result.schema).toEqual({ + type: 'object', + properties: {}, + additionalProperties: false, + }); + }); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index a76fafac89..e2d420bb38 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -309,6 +309,70 @@ describe('createExtensionBlueprint', () => { ); }); + it('should merge configSchema from blueprint with deprecated config.schema from override', () => { + const TestBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [coreExtensionData.reactElement], + configSchema: { + title: z => z.string().default('default title'), + }, + factory(_, { config }) { + return [coreExtensionData.reactElement(
{config.title}
)]; + }, + }); + + const extension = TestBlueprint.makeWithOverrides({ + name: 'my-extension', + config: { + schema: { + extra: z => z.string(), + }, + }, + factory(origFactory, { config }) { + expect(config.title).toBe('default title'); + expect(config.extra).toBe('extra value'); + return origFactory({}); + }, + }); + + expect.assertions(2); + + renderInTestApp( + createExtensionTester(extension, { + config: { extra: 'extra value' }, + }).reactElement(), + ); + }); + + it('should emit a deprecation warning when using config.schema', () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); + + try { + createExtension({ + name: 'test-deprecated-warning', + attachTo: { id: 'test', input: 'default' }, + output: [coreExtensionData.reactElement], + config: { + schema: { + title: z => z.string().default('hello'), + }, + }, + factory() { + return [coreExtensionData.reactElement(
)]; + }, + }); + + expect(warnSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'DEPRECATION WARNING: The `config.schema` option for extension config is deprecated', + ), + ); + } finally { + warnSpy.mockRestore(); + } + }); + it('should allow getting inputs properly', () => { createExtensionBlueprint({ kind: 'test-extension',