diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx index 392cab08ca..b81b5209f0 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx @@ -6,6 +6,8 @@ import Overview, { } from 'components/Topics/Topic/Details/Overview/Overview'; import theme from 'theme/theme'; import { CleanUpPolicy } from 'generated-sources'; +import ClusterContext from 'components/contexts/ClusterContext'; +import userEvent from '@testing-library/user-event'; describe('Overview', () => { const mockClusterName = 'local'; @@ -26,45 +28,52 @@ describe('Overview', () => { offsetMin: 0, }, ]; + const defaultContextValues = { + isReadOnly: false, + hasKafkaConnectConfigured: true, + hasSchemaRegistryConfigured: true, + isTopicDeletionAllowed: true, + }; + const defaultProps: OverviewProps = { + name: mockTopicName, + partitions: [], + internal: true, + clusterName: mockClusterName, + topicName: mockTopicName, + clearTopicMessages: mockClearTopicMessages, + }; const setupComponent = ( - props: OverviewProps, + props = defaultProps, + contextValues = defaultContextValues, underReplicatedPartitions?: number, inSyncReplicas?: number, replicas?: number ) => render( - + + + ); describe('when it has internal flag', () => { it('does not render the Action button a Topic', () => { setupComponent({ - name: mockTopicName, + ...defaultProps, partitions: mockPartitions, internal: false, - clusterName: mockClusterName, - topicName: mockTopicName, cleanUpPolicy: CleanUpPolicy.DELETE, - clearTopicMessages: mockClearTopicMessages, }); - expect(screen.getByRole('menu')).toBeInTheDocument(); + expect(screen.getAllByRole('menu')[0]).toBeInTheDocument(); }); it('does not render Partitions', () => { - setupComponent({ - name: mockTopicName, - partitions: [], - internal: true, - clusterName: mockClusterName, - topicName: mockTopicName, - clearTopicMessages: mockClearTopicMessages, - }); + setupComponent(); expect(screen.getByText('No Partitions found')).toBeInTheDocument(); }); @@ -72,26 +81,14 @@ describe('Overview', () => { describe('should render circular alert', () => { it('should be in document', () => { - setupComponent({ - name: mockTopicName, - partitions: [], - internal: true, - clusterName: mockClusterName, - topicName: mockTopicName, - clearTopicMessages: mockClearTopicMessages, - }); + setupComponent(); const circles = screen.getAllByRole('circle'); expect(circles.length).toEqual(2); }); it('should be the appropriate color', () => { setupComponent({ - name: mockTopicName, - partitions: [], - internal: true, - clusterName: mockClusterName, - topicName: mockTopicName, - clearTopicMessages: mockClearTopicMessages, + ...defaultProps, underReplicatedPartitions: 0, inSyncReplicas: 1, replicas: 2, @@ -105,4 +102,18 @@ describe('Overview', () => { ); }); }); + + describe('when Clear Messages is clicked', () => { + setupComponent({ + ...defaultProps, + partitions: mockPartitions, + internal: false, + cleanUpPolicy: CleanUpPolicy.DELETE, + }); + + const clearMessagesButton = screen.getByText('Clear Messages'); + userEvent.click(clearMessagesButton); + + expect(mockClearTopicMessages).toHaveBeenCalledTimes(1); + }); }); diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/__test__/Details.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/__test__/Details.spec.tsx index 6cae7eecff..4b901d9314 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/__test__/Details.spec.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/__test__/Details.spec.tsx @@ -5,7 +5,13 @@ import ClusterContext from 'components/contexts/ClusterContext'; import Details from 'components/Topics/Topic/Details/Details'; import { internalTopicPayload } from 'redux/reducers/topics/__test__/fixtures'; import { render } from 'lib/testHelpers'; -import { clusterTopicPath } from 'lib/paths'; +import { + clusterTopicEditPath, + clusterTopicPath, + clusterTopicsPath, +} from 'lib/paths'; +import { Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; describe('Details', () => { const mockDelete = jest.fn(); @@ -13,8 +19,20 @@ describe('Details', () => { const mockClearTopicMessages = jest.fn(); const mockInternalTopicPayload = internalTopicPayload.internal; const mockRecreateTopic = jest.fn(); + const defaultPathname = clusterTopicPath( + mockClusterName, + internalTopicPayload.name + ); + const mockHistory = createMemoryHistory({ + initialEntries: [defaultPathname], + }); + jest.spyOn(mockHistory, 'push'); - const setupComponent = (pathname: string) => + const setupComponent = ( + pathname = defaultPathname, + history = mockHistory, + props = {} + ) => render( { isTopicDeletionAllowed: true, }} > -
+ +
+ , { pathname } ); @@ -68,10 +89,83 @@ describe('Details', () => { }); }); + describe('when remove topic modal is open', () => { + beforeEach(() => { + setupComponent(); + + const openModalButton = screen.getAllByText('Remove topic')[0]; + userEvent.click(openModalButton); + }); + + it('calls deleteTopic on confirm', () => { + const submitButton = screen.getAllByText('Submit')[0]; + userEvent.click(submitButton); + + expect(mockDelete).toHaveBeenCalledWith( + mockClusterName, + internalTopicPayload.name + ); + }); + + it('closes the modal when cancel button is clicked', () => { + const cancelButton = screen.getAllByText('Cancel')[0]; + userEvent.click(cancelButton); + + expect(cancelButton).not.toBeInTheDocument(); + }); + }); + + describe('when clear messages modal is open', () => { + beforeEach(() => { + setupComponent(); + + const confirmButton = screen.getAllByText('Clear messages')[0]; + userEvent.click(confirmButton); + }); + + it('it calls clearTopicMessages on confirm', () => { + const submitButton = screen.getAllByText('Submit')[0]; + userEvent.click(submitButton); + + expect(mockClearTopicMessages).toHaveBeenCalledWith( + mockClusterName, + internalTopicPayload.name + ); + }); + + it('closes the modal when cancel button is clicked', () => { + const cancelButton = screen.getAllByText('Cancel')[0]; + userEvent.click(cancelButton); + + expect(cancelButton).not.toBeInTheDocument(); + }); + }); + + describe('when edit settings is clicked', () => { + it('redirects to the edit page', () => { + setupComponent(); + + const button = screen.getAllByText('Edit settings')[0]; + userEvent.click(button); + + const redirectRoute = clusterTopicEditPath( + mockClusterName, + internalTopicPayload.name + ); + + expect(mockHistory.push).toHaveBeenCalledWith(redirectRoute); + }); + }); + + it('redirects to the correct route if topic is deleted', () => { + setupComponent(defaultPathname, mockHistory, { isDeleted: true }); + const redirectRoute = clusterTopicsPath(mockClusterName); + + expect(mockHistory.push).toHaveBeenCalledWith(redirectRoute); + }); + it('shows a confirmation popup on deleting topic messages', () => { - setupComponent( - clusterTopicPath(mockClusterName, internalTopicPayload.name) - ); + setupComponent(); const { getByText } = screen; const clearMessagesButton = getByText(/Clear messages/i); userEvent.click(clearMessagesButton); @@ -82,9 +176,7 @@ describe('Details', () => { }); it('shows a confirmation popup on recreating topic', () => { - setupComponent( - clusterTopicPath(mockClusterName, internalTopicPayload.name) - ); + setupComponent(); const recreateTopicButton = screen.getByText(/Recreate topic/i); userEvent.click(recreateTopicButton); @@ -94,9 +186,7 @@ describe('Details', () => { }); it('calling recreation function after click on Submit button', () => { - setupComponent( - clusterTopicPath(mockClusterName, internalTopicPayload.name) - ); + setupComponent(); const recreateTopicButton = screen.getByText(/Recreate topic/i); userEvent.click(recreateTopicButton); const confirmBtn = screen.getByRole('button', { name: /submit/i }); @@ -105,9 +195,7 @@ describe('Details', () => { }); it('close popup confirmation window after click on Cancel button', () => { - setupComponent( - clusterTopicPath(mockClusterName, internalTopicPayload.name) - ); + setupComponent(); const recreateTopicButton = screen.getByText(/Recreate topic/i); userEvent.click(recreateTopicButton); const cancelBtn = screen.getByRole('button', { name: /cancel/i });