diff --git a/.changeset/purple-times-deny.md b/.changeset/purple-times-deny.md new file mode 100644 index 0000000000..7cf4d2c3c3 --- /dev/null +++ b/.changeset/purple-times-deny.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Added appropriate message when global templating function metadata is absent. diff --git a/plugins/scaffolder/report-alpha.api.md b/plugins/scaffolder/report-alpha.api.md index 54acadd561..509cfa8497 100644 --- a/plugins/scaffolder/report-alpha.api.md +++ b/plugins/scaffolder/report-alpha.api.md @@ -430,6 +430,7 @@ export const scaffolderTranslationRef: TranslationRef< readonly 'templatingExtensions.content.functions.schema.arguments': 'Arguments'; readonly 'templatingExtensions.content.functions.examples': 'Examples'; readonly 'templatingExtensions.content.functions.notAvailable': 'There are no global template functions defined.'; + readonly 'templatingExtensions.content.functions.metadataAbsent': 'Function metadata unavailable'; readonly 'templatingExtensions.title': 'Templating Extensions'; readonly 'templatingExtensions.subtitle': 'This is the collection of available templating extensions'; readonly 'templatingExtensions.pageTitle': 'Templating Extensions'; diff --git a/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplateGlobals.tsx b/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplateGlobals.tsx index 329f7b9742..868a869be3 100644 --- a/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplateGlobals.tsx +++ b/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplateGlobals.tsx @@ -48,8 +48,11 @@ const FunctionDetailContent = ({ const expanded = useState({}); if (!Object.keys(fn).length) { return ( - - {t('templatingExtensions.content.functions.notAvailable')} + + {t('templatingExtensions.content.functions.metadataAbsent')} ); } diff --git a/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplatingExtensionsPage.test.tsx b/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplatingExtensionsPage.test.tsx index d3d0eb7370..2c0680b5f8 100644 --- a/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplatingExtensionsPage.test.tsx +++ b/plugins/scaffolder/src/components/TemplatingExtensionsPage/TemplatingExtensionsPage.test.tsx @@ -315,76 +315,112 @@ describe('TemplatingExtensionsPage', () => { }); }); describe('renders global', () => { - it('renders global functions', async () => { - listTemplatingExtensions.mockResolvedValue({ - ...emptyExtensions, - globals: { - ...emptyExtensions.globals, - functions: { - truthy: { - description: 'evaluate truthiness', - schema: { - arguments: [ - { - title: 'input', - }, - ], - output: { - type: 'boolean', - }, - }, - examples: [ - { - description: 'basic usage', - example: "truthy('foo')", - notes: 'yields `true`', - }, - ], + describe('renders global functions', () => { + it('without metadata', async () => { + listTemplatingExtensions.mockResolvedValue({ + ...emptyExtensions, + globals: { + ...emptyExtensions.globals, + functions: { + anything: {}, }, }, - }, + }); + const { findByTestId, getByRole } = await r(); + + fireEvent.click(within(getByRole('tablist')).getByText('Functions')); + + const functions = await findByTestId('functions'); + + const anything = within(functions).getByTestId('anything'); + const title = within(anything).getByText('anything'); + expect(title).toBeInTheDocument(); + expect(title.id).toBe('function_anything'); + + const link = within(anything).getByRole('link'); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute( + 'href', + expect.stringMatching(new RegExp(`#${title.id}$`)), + ); + expect( + within(anything).getByTestId('anything.metadataAbsent'), + ).toBeInTheDocument(); }); - const { findByTestId, getByRole } = await r(); + it('with metadata', async () => { + listTemplatingExtensions.mockResolvedValue({ + ...emptyExtensions, + globals: { + ...emptyExtensions.globals, + functions: { + truthy: { + description: 'evaluate truthiness', + schema: { + arguments: [ + { + title: 'input', + }, + ], + output: { + type: 'boolean', + }, + }, + examples: [ + { + description: 'basic usage', + example: "truthy('foo')", + notes: 'yields `true`', + }, + ], + }, + }, + }, + }); + const { findByTestId, getByRole } = await r(); - fireEvent.click(within(getByRole('tablist')).getByText('Functions')); + fireEvent.click(within(getByRole('tablist')).getByText('Functions')); - const functions = await findByTestId('functions'); + const functions = await findByTestId('functions'); - const truthy = within(functions).getByTestId('truthy'); - const title = within(truthy).getByText('truthy'); - expect(title).toBeInTheDocument(); - expect(title.id).toBe('function_truthy'); + const truthy = within(functions).getByTestId('truthy'); + const title = within(truthy).getByText('truthy'); + expect(title).toBeInTheDocument(); + expect(title.id).toBe('function_truthy'); - const link = within(truthy).getByRole('link'); - expect(link).toBeInTheDocument(); - expect(link).toHaveAttribute( - 'href', - expect.stringMatching(new RegExp(`#${title.id}$`)), - ); + const link = within(truthy).getByRole('link'); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute( + 'href', + expect.stringMatching(new RegExp(`#${title.id}$`)), + ); + expect( + within(truthy).queryByTestId('truthy.metadataAbsent'), + ).not.toBeInTheDocument(); - expect( - within(truthy).getByText('evaluate truthiness'), - ).toBeInTheDocument(); + expect( + within(truthy).getByText('evaluate truthiness'), + ).toBeInTheDocument(); - expect(within(truthy).getByText('[0]')).toBeInTheDocument(); - expect( - within(truthy).getByTestId('root_truthy.arg0'), - ).toBeInTheDocument(); - expect( - within(truthy).queryByTestId('root_truthy.arg1'), - ).not.toBeInTheDocument(); - expect( - within(truthy).getByTestId('root_truthy.output'), - ).toBeInTheDocument(); + expect(within(truthy).getByText('[0]')).toBeInTheDocument(); + expect( + within(truthy).getByTestId('root_truthy.arg0'), + ).toBeInTheDocument(); + expect( + within(truthy).queryByTestId('root_truthy.arg1'), + ).not.toBeInTheDocument(); + expect( + within(truthy).getByTestId('root_truthy.output'), + ).toBeInTheDocument(); - const x = within(truthy).getByTestId('examples'); - expect(x).toBeInTheDocument(); - const xd0 = within(x).getByTestId('example_desc0'); - expect(xd0).toBeInTheDocument(); - expect(xd0).toHaveTextContent(/basic usage\s*yields\s*true/); + const x = within(truthy).getByTestId('examples'); + expect(x).toBeInTheDocument(); + const xd0 = within(x).getByTestId('example_desc0'); + expect(xd0).toBeInTheDocument(); + expect(xd0).toHaveTextContent(/basic usage\s*yields\s*true/); - const xc0 = within(x).getByTestId('example_code0'); - expect(within(xc0).getByText("truthy('foo')")).toBeInTheDocument(); + const xc0 = within(x).getByTestId('example_code0'); + expect(within(xc0).getByText("truthy('foo')")).toBeInTheDocument(); + }); }); it('renders global values', async () => { const msvValue = ['foo', 'bar', 'baz']; diff --git a/plugins/scaffolder/src/translation.ts b/plugins/scaffolder/src/translation.ts index fc0f0a6889..78ca15e2ff 100644 --- a/plugins/scaffolder/src/translation.ts +++ b/plugins/scaffolder/src/translation.ts @@ -226,6 +226,7 @@ export const scaffolderTranslationRef = createTranslationRef({ functions: { title: 'Functions', notAvailable: 'There are no global template functions defined.', + metadataAbsent: 'Function metadata unavailable', schema: { arguments: 'Arguments', output: 'Output',