diff --git a/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx b/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx index 22a47c192e..aeb9fc543b 100644 --- a/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx +++ b/plugins/catalog/src/components/EntityPage/EntityPage.test.tsx @@ -14,32 +14,38 @@ * limitations under the License. */ +jest.mock('react-router-dom', () => { + const actual = jest.requireActual('react-router-dom'); + const mockNavigate = jest.fn(); + return { + ...actual, + useNavigate: jest.fn(() => mockNavigate), + useParams: jest.fn(), + }; +}); + import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core'; import { wrapInTestApp } from '@backstage/test-utils'; import { render, wait } from '@testing-library/react'; import * as React from 'react'; import { CatalogApi, catalogApiRef } from '../../api/types'; import { EntityPage } from './EntityPage'; - -const getTestProps = (name: string) => { - return { - match: { - params: { - optionalNamespaceAndName: name, - kind: 'Component', - }, - }, - history: { - push: jest.fn(), - }, - }; -}; +const { + useParams, + useNavigate, +}: { useParams: jest.Mock; useNavigate: () => jest.Mock } = jest.requireMock( + 'react-router-dom', +); const errorApi = { post: () => {} }; describe('EntityPage', () => { it('should redirect to catalog page when name is not provided', async () => { - const props = getTestProps(''); + useParams.mockReturnValue({ + kind: 'Component', + optionalNamespaceAndName: '', + }); + render( wrapInTestApp( { ], ])} > - + , ), ); - await wait(() => - expect(props.history.push).toHaveBeenCalledWith('/catalog'), - ); + await wait(() => expect(useNavigate()).toHaveBeenCalledWith('/catalog')); }); }); diff --git a/plugins/catalog/src/components/EntityPage/EntityPage.tsx b/plugins/catalog/src/components/EntityPage/EntityPage.tsx index 96132819e8..e74276697b 100644 --- a/plugins/catalog/src/components/EntityPage/EntityPage.tsx +++ b/plugins/catalog/src/components/EntityPage/EntityPage.tsx @@ -34,21 +34,9 @@ import { catalogApiRef } from '../..'; import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu'; import { EntityMetadataCard } from '../EntityMetadataCard/EntityMetadataCard'; import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog'; +import { useParams, useNavigate } from 'react-router-dom'; const REDIRECT_DELAY = 1000; - -type Props = { - match: { - params: { - optionalNamespaceAndName: string; - kind: string; - }; - }; - history: { - push: (url: string) => void; - }; -}; - function headerProps( kind: string, namespace: string | undefined, @@ -68,8 +56,12 @@ function headerProps( }; } -export const EntityPage: FC = ({ match, history }) => { - const { optionalNamespaceAndName, kind } = match.params; +export const EntityPage: FC<{}> = () => { + const { optionalNamespaceAndName, kind } = useParams() as { + optionalNamespaceAndName: string; + kind: string; + }; + const navigate = useNavigate(); const [name, namespace] = optionalNamespaceAndName.split(':').reverse(); const errorApi = useApi(errorApiRef); @@ -85,19 +77,19 @@ export const EntityPage: FC = ({ match, history }) => { if (!error && !loading && !entity) { errorApi.post(new Error('Entity not found!')); setTimeout(() => { - history.push('/'); + navigate('/'); }, REDIRECT_DELAY); } - }, [errorApi, history, error, loading, entity]); + }, [errorApi, navigate, error, loading, entity]); if (!name) { - history.push('/catalog'); + navigate('/catalog'); return null; } const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); - history.push('/'); + navigate('/'); }; const showRemovalDialog = () => setConfirmationDialogOpen(true);