diff --git a/plugins/catalog/src/alpha/pages.test.tsx b/plugins/catalog/src/alpha/pages.test.tsx index ab81d93342..0d18dd9dfa 100644 --- a/plugins/catalog/src/alpha/pages.test.tsx +++ b/plugins/catalog/src/alpha/pages.test.tsx @@ -24,6 +24,7 @@ import { import { catalogEntityPage } from './pages'; import { EntityContentBlueprint, + EntityContextMenuItemBlueprint, EntityHeaderBlueprint, } from '@backstage/plugin-catalog-react/alpha'; import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; @@ -596,4 +597,121 @@ describe('Entity page', () => { ); }); }); + + describe('Entity Page Context Menu', () => { + const onClickMock = jest.fn(); + beforeEach(() => { + onClickMock.mockReset(); + }); + + it.each([ + { useIsDisabled: () => true, href: '/somewhere' }, + { useIsDisabled: () => false, href: '/somewhere' }, + { useIsDisabled: () => true, useHref: () => '/somewhere' }, + { useIsDisabled: () => false, useHref: () => '/somewhere' }, + ])('should render an href based context menu item', async params => { + const menuItem = EntityContextMenuItemBlueprint.make({ + name: 'test-href', + params: { + useTitle: () => 'Test Title', + icon: Test Icon, + ...params, + }, + }); + const tester = createExtensionTester( + Object.assign({ namespace: 'catalog' }, catalogEntityPage), + ).add(menuItem); + + renderInTestApp( + + {tester.reactElement()} + , + { + config: { + app: { + title: 'Custom app', + }, + backend: { baseUrl: 'http://localhost:7000' }, + }, + mountedRoutes: { + '/catalog': convertLegacyRouteRef(rootRouteRef), + '/catalog/:namespace/:kind/:name': + convertLegacyRouteRef(entityRouteRef), + }, + }, + ); + + await waitFor(async () => { + await userEvent.click(screen.getByTestId('menu-button')); + expect(screen.getByText('Test Title')).toBeInTheDocument(); + expect(screen.getByText('Test Icon')).toBeInTheDocument(); + const anchor = screen.getByText('Test Title').closest('a'); + expect(anchor).toHaveAttribute('href', '/somewhere'); + expect(anchor).toHaveAttribute( + 'aria-disabled', + params.useIsDisabled().toString(), + ); + }); + }); + + it.each([ + { useIsDisabled: () => true, useOnClick: () => onClickMock }, + { useIsDisabled: () => false, useOnClick: () => onClickMock }, + ])('should render a useOnClick based context menu item', async params => { + const menuItem = EntityContextMenuItemBlueprint.make({ + name: 'test-href', + params: { + useTitle: () => 'Test Title', + icon: Test Icon, + ...params, + }, + }); + const tester = createExtensionTester( + Object.assign({ namespace: 'catalog' }, catalogEntityPage), + ).add(menuItem); + const disabled = params.useIsDisabled(); + + renderInTestApp( + + {tester.reactElement()} + , + { + config: { + app: { + title: 'Custom app', + }, + backend: { baseUrl: 'http://localhost:7000' }, + }, + mountedRoutes: { + '/catalog': convertLegacyRouteRef(rootRouteRef), + '/catalog/:namespace/:kind/:name': + convertLegacyRouteRef(entityRouteRef), + }, + }, + ); + + await waitFor(async () => { + await userEvent.click(screen.getByTestId('menu-button')); + expect(screen.getByText('Test Title')).toBeInTheDocument(); + expect(screen.getByText('Test Icon')).toBeInTheDocument(); + const listItem = screen.getByText('Test Title').closest('li'); + expect(listItem).toHaveAttribute('aria-disabled', disabled.toString()); + if (!disabled) { + await userEvent.click(screen.getByText('Test Title')); + } + + expect(onClickMock).toHaveBeenCalledTimes(disabled ? 0 : 1); + }); + }); + }); });