diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx index 2e2a147ad1..9ff1dd1b17 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx @@ -70,7 +70,7 @@ describe('TemplateCard', () => { }, }; - const { getByText } = await renderInTestApp( + const { getByText, getByTestId } = await renderInTestApp( { const description = getByText('hello'); expect(description.querySelector('strong')).toBeInTheDocument(); + expect(getByTestId('template-card-separator')).toBeInTheDocument(); }); it('should render no description if none is provided through the template', async () => { @@ -118,6 +119,41 @@ describe('TemplateCard', () => { expect(getByText('No description')).toBeInTheDocument(); }); + it('should not render extra separators when tags or links are not present', async () => { + const mockTemplate: TemplateEntityV1beta3 = { + apiVersion: 'scaffolder.backstage.io/v1beta3', + kind: 'Template', + metadata: { name: 'bob' }, + spec: { + steps: [], + type: 'service', + }, + }; + + const { queryByTestId } = await renderInTestApp( + + + , + ); + + expect(queryByTestId('template-card-separator')).toBeInTheDocument(); + expect( + queryByTestId('template-card-separator--tags'), + ).not.toBeInTheDocument(); + expect( + queryByTestId('template-card-separator--links'), + ).not.toBeInTheDocument(); + }); + it('should render the tags', async () => { const mockTemplate: TemplateEntityV1beta3 = { apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -129,7 +165,7 @@ describe('TemplateCard', () => { }, }; - const { getByText } = await renderInTestApp( + const { getByText, queryByTestId } = await renderInTestApp( { for (const tag of mockTemplate.metadata.tags!) { expect(getByText(tag)).toBeInTheDocument(); } + expect(queryByTestId('template-card-separator')).not.toBeInTheDocument(); + expect(queryByTestId('template-card-separator--tags')).toBeInTheDocument(); }); it('should not render links section when empty links are defined', async () => { @@ -166,7 +204,7 @@ describe('TemplateCard', () => { ], }; - const { queryByRole, queryByText } = await renderInTestApp( + const { queryByTestId, queryByText } = await renderInTestApp( { }, ); - expect(queryByRole('separator')).not.toBeInTheDocument(); + expect(queryByTestId('template-card-separator')).toBeInTheDocument(); + expect( + queryByTestId('template-card-separator--links'), + ).not.toBeInTheDocument(); expect(queryByText('0')).not.toBeInTheDocument(); }); @@ -207,7 +248,7 @@ describe('TemplateCard', () => { ], }; - const { queryByRole, queryByText } = await renderInTestApp( + const { queryByTestId, queryByText } = await renderInTestApp( { }, ); - expect(queryByRole('separator')).not.toBeInTheDocument(); + expect(queryByTestId('template-card-separator')).toBeInTheDocument(); + expect( + queryByTestId('template-card-separator--links'), + ).not.toBeInTheDocument(); expect(queryByText('0')).not.toBeInTheDocument(); }); + it('should render links section when links are defined', async () => { + const mockTemplate: TemplateEntityV1beta3 = { + apiVersion: 'scaffolder.backstage.io/v1beta3', + kind: 'Template', + metadata: { + name: 'bob', + tags: [], + links: [{ url: '/some/url', title: 'Learn More' }], + }, + spec: { + steps: [], + type: 'service', + }, + relations: [ + { + targetRef: 'group:default/my-test-user', + type: RELATION_OWNED_BY, + }, + ], + }; + + const { queryByTestId, getByRole } = await renderInTestApp( + + + , + { + mountedRoutes: { + '/catalog/:kind/:namespace/:name': entityRouteRef, + }, + }, + ); + + expect(queryByTestId('template-card-separator')).not.toBeInTheDocument(); + expect(queryByTestId('template-card-separator--links')).toBeInTheDocument(); + expect(getByRole('link', { name: 'Learn More' })).toBeInTheDocument(); + }); + it('should render a link to the owner', async () => { const mockTemplate: TemplateEntityV1beta3 = { apiVersion: 'scaffolder.backstage.io/v1beta3', diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx index 6bcff0b0ce..2d8ff1e458 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx @@ -101,6 +101,10 @@ export const TemplateCard = (props: TemplateCardProps) => { const app = useApp(); const iconResolver = (key?: string): IconComponent => key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; + const hasTags = !!template.metadata.tags?.length; + const hasLinks = + !!props.additionalLinks?.length || !!template.metadata.links?.length; + const displayDefaultDivider = !hasTags && !hasLinks; return ( @@ -115,15 +119,20 @@ export const TemplateCard = (props: TemplateCardProps) => { /> - {(template.metadata.tags?.length ?? 0) > 0 && ( + {displayDefaultDivider && ( + + + + )} + {hasTags && ( <> - + {template.metadata.tags?.map(tag => ( - + { )} - {(!!props.additionalLinks?.length || - !!template.metadata.links?.length) && ( + {hasLinks && ( <> - +