|
@@ -4,7 +4,15 @@ import userEvent from '@testing-library/user-event';
|
|
|
import ClusterContext from 'components/contexts/ClusterContext';
|
|
|
import Details from 'components/Topics/Topic/Details/Details';
|
|
|
import { render, WithRoute } from 'lib/testHelpers';
|
|
|
-import { clusterTopicEditRelativePath, clusterTopicPath } from 'lib/paths';
|
|
|
+import {
|
|
|
+ clusterTopicConsumerGroupsPath,
|
|
|
+ clusterTopicEditRelativePath,
|
|
|
+ clusterTopicMessagesPath,
|
|
|
+ clusterTopicPath,
|
|
|
+ clusterTopicSettingsPath,
|
|
|
+ clusterTopicStatisticsPath,
|
|
|
+ getNonExactPath,
|
|
|
+} from 'lib/paths';
|
|
|
import { CleanUpPolicy, Topic } from 'generated-sources';
|
|
|
import { externalTopicPayload } from 'lib/fixtures/topics';
|
|
|
import {
|
|
@@ -32,19 +40,34 @@ jest.mock('lib/hooks/redux', () => ({
|
|
|
useAppDispatch: useDispatchMock,
|
|
|
}));
|
|
|
|
|
|
+jest.mock('components/Topics/Topic/Details/Overview/Overview', () => () => (
|
|
|
+ <>OverviewMock</>
|
|
|
+));
|
|
|
+jest.mock('components/Topics/Topic/Details/Messages/Messages', () => () => (
|
|
|
+ <>MessagesMock</>
|
|
|
+));
|
|
|
+jest.mock('components/Topics/Topic/Details/Settings/Settings', () => () => (
|
|
|
+ <>SettingsMock</>
|
|
|
+));
|
|
|
+jest.mock(
|
|
|
+ 'components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups',
|
|
|
+ () => () => <>ConsumerGroupsMock</>
|
|
|
+);
|
|
|
+jest.mock('components/Topics/Topic/Details/Statistics/Statistics', () => () => (
|
|
|
+ <>StatisticsMock</>
|
|
|
+));
|
|
|
+
|
|
|
const mockDelete = jest.fn();
|
|
|
const mockRecreate = jest.fn();
|
|
|
+const mockClusterName = 'local';
|
|
|
+const topic: Topic = {
|
|
|
+ ...externalTopicPayload,
|
|
|
+ cleanUpPolicy: CleanUpPolicy.DELETE,
|
|
|
+};
|
|
|
+const defaultPath = clusterTopicPath(mockClusterName, topic.name);
|
|
|
|
|
|
describe('Details', () => {
|
|
|
- const mockClusterName = 'local';
|
|
|
-
|
|
|
- const topic: Topic = {
|
|
|
- ...externalTopicPayload,
|
|
|
- cleanUpPolicy: CleanUpPolicy.DELETE,
|
|
|
- };
|
|
|
-
|
|
|
- const renderComponent = (isReadOnly = false) => {
|
|
|
- const path = clusterTopicPath(mockClusterName, topic.name);
|
|
|
+ const renderComponent = (isReadOnly = false, path = defaultPath) => {
|
|
|
render(
|
|
|
<ClusterContext.Provider
|
|
|
value={{
|
|
@@ -54,7 +77,7 @@ describe('Details', () => {
|
|
|
isTopicDeletionAllowed: true,
|
|
|
}}
|
|
|
>
|
|
|
- <WithRoute path={clusterTopicPath()}>
|
|
|
+ <WithRoute path={getNonExactPath(clusterTopicPath())}>
|
|
|
<Details />
|
|
|
</WithRoute>
|
|
|
</ClusterContext.Provider>,
|
|
@@ -73,113 +96,160 @@ describe('Details', () => {
|
|
|
mutateAsync: mockRecreate,
|
|
|
}));
|
|
|
});
|
|
|
-
|
|
|
- describe('when it has readonly flag', () => {
|
|
|
- it('does not render the Action button a Topic', () => {
|
|
|
- renderComponent(true);
|
|
|
- expect(screen.queryByText('Produce Message')).not.toBeInTheDocument();
|
|
|
+ describe('Action Bar', () => {
|
|
|
+ describe('when it has readonly flag', () => {
|
|
|
+ it('does not render the Action button a Topic', () => {
|
|
|
+ renderComponent(true);
|
|
|
+ expect(screen.queryByText('Produce Message')).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- describe('when remove topic modal is open', () => {
|
|
|
- beforeEach(() => {
|
|
|
- renderComponent();
|
|
|
- const openModalButton = screen.getAllByText('Remove Topic')[0];
|
|
|
- userEvent.click(openModalButton);
|
|
|
+ describe('when remove topic modal is open', () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ renderComponent();
|
|
|
+ const openModalButton = screen.getAllByText('Remove Topic')[0];
|
|
|
+ userEvent.click(openModalButton);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('calls deleteTopic on confirm', async () => {
|
|
|
+ const submitButton = screen.getAllByRole('button', {
|
|
|
+ name: 'Confirm',
|
|
|
+ })[0];
|
|
|
+ await act(() => userEvent.click(submitButton));
|
|
|
+ expect(mockDelete).toHaveBeenCalledWith(topic.name);
|
|
|
+ });
|
|
|
+ it('closes the modal when cancel button is clicked', async () => {
|
|
|
+ const cancelButton = screen.getAllByText('Cancel')[0];
|
|
|
+ await waitFor(() => userEvent.click(cancelButton));
|
|
|
+ expect(cancelButton).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
- it('calls deleteTopic on confirm', async () => {
|
|
|
- const submitButton = screen.getAllByRole('button', {
|
|
|
- name: 'Confirm',
|
|
|
- })[0];
|
|
|
- await act(() => userEvent.click(submitButton));
|
|
|
- expect(mockDelete).toHaveBeenCalledWith(topic.name);
|
|
|
- });
|
|
|
- it('closes the modal when cancel button is clicked', async () => {
|
|
|
- const cancelButton = screen.getAllByText('Cancel')[0];
|
|
|
- await waitFor(() => userEvent.click(cancelButton));
|
|
|
- expect(cancelButton).not.toBeInTheDocument();
|
|
|
+ describe('when clear messages modal is open', () => {
|
|
|
+ beforeEach(async () => {
|
|
|
+ await renderComponent();
|
|
|
+ const confirmButton = screen.getAllByText('Clear messages')[0];
|
|
|
+ await act(() => userEvent.click(confirmButton));
|
|
|
+ });
|
|
|
+
|
|
|
+ it('it calls clearTopicMessages on confirm', async () => {
|
|
|
+ const submitButton = screen.getAllByRole('button', {
|
|
|
+ name: 'Confirm',
|
|
|
+ })[0];
|
|
|
+ await waitFor(() => userEvent.click(submitButton));
|
|
|
+ expect(mockUnwrap).toHaveBeenCalledTimes(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('closes the modal when cancel button is clicked', async () => {
|
|
|
+ const cancelButton = screen.getAllByText('Cancel')[0];
|
|
|
+ await waitFor(() => userEvent.click(cancelButton));
|
|
|
+
|
|
|
+ expect(cancelButton).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- describe('when clear messages modal is open', () => {
|
|
|
- beforeEach(async () => {
|
|
|
- await renderComponent();
|
|
|
- const confirmButton = screen.getAllByText('Clear messages')[0];
|
|
|
- await act(() => userEvent.click(confirmButton));
|
|
|
+ describe('when edit settings is clicked', () => {
|
|
|
+ it('redirects to the edit page', () => {
|
|
|
+ renderComponent();
|
|
|
+ const button = screen.getAllByText('Edit settings')[0];
|
|
|
+ userEvent.click(button);
|
|
|
+ expect(mockNavigate).toHaveBeenCalledWith(clusterTopicEditRelativePath);
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
- it('it calls clearTopicMessages on confirm', async () => {
|
|
|
- const submitButton = screen.getAllByRole('button', {
|
|
|
+ it('redirects to the correct route if topic is deleted', async () => {
|
|
|
+ renderComponent();
|
|
|
+ const deleteTopicButton = screen.getByText(/Remove topic/i);
|
|
|
+ await waitFor(() => userEvent.click(deleteTopicButton));
|
|
|
+ const submitDeleteButton = screen.getByRole('button', {
|
|
|
name: 'Confirm',
|
|
|
- })[0];
|
|
|
- await waitFor(() => userEvent.click(submitButton));
|
|
|
- expect(mockUnwrap).toHaveBeenCalledTimes(1);
|
|
|
+ });
|
|
|
+ await act(() => userEvent.click(submitDeleteButton));
|
|
|
+ expect(mockNavigate).toHaveBeenCalledWith('../..');
|
|
|
});
|
|
|
|
|
|
- it('closes the modal when cancel button is clicked', async () => {
|
|
|
- const cancelButton = screen.getAllByText('Cancel')[0];
|
|
|
- await waitFor(() => userEvent.click(cancelButton));
|
|
|
+ it('shows a confirmation popup on deleting topic messages', () => {
|
|
|
+ renderComponent();
|
|
|
+ const clearMessagesButton = screen.getAllByText(/Clear messages/i)[0];
|
|
|
+ userEvent.click(clearMessagesButton);
|
|
|
|
|
|
- expect(cancelButton).not.toBeInTheDocument();
|
|
|
+ expect(
|
|
|
+ screen.getByText(/Are you sure want to clear topic messages?/i)
|
|
|
+ ).toBeInTheDocument();
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- describe('when edit settings is clicked', () => {
|
|
|
- it('redirects to the edit page', () => {
|
|
|
+ it('shows a confirmation popup on recreating topic', () => {
|
|
|
renderComponent();
|
|
|
- const button = screen.getAllByText('Edit settings')[0];
|
|
|
- userEvent.click(button);
|
|
|
- expect(mockNavigate).toHaveBeenCalledWith(clusterTopicEditRelativePath);
|
|
|
+ const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
+ userEvent.click(recreateTopicButton);
|
|
|
+ expect(
|
|
|
+ screen.getByText(/Are you sure want to recreate topic?/i)
|
|
|
+ ).toBeInTheDocument();
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- it('redirects to the correct route if topic is deleted', async () => {
|
|
|
- renderComponent();
|
|
|
- const deleteTopicButton = screen.getByText(/Remove topic/i);
|
|
|
- await waitFor(() => userEvent.click(deleteTopicButton));
|
|
|
- const submitDeleteButton = screen.getByRole('button', { name: 'Confirm' });
|
|
|
- await act(() => userEvent.click(submitDeleteButton));
|
|
|
- expect(mockNavigate).toHaveBeenCalledWith('../..');
|
|
|
- });
|
|
|
-
|
|
|
- it('shows a confirmation popup on deleting topic messages', () => {
|
|
|
- renderComponent();
|
|
|
- const clearMessagesButton = screen.getAllByText(/Clear messages/i)[0];
|
|
|
- userEvent.click(clearMessagesButton);
|
|
|
-
|
|
|
- expect(
|
|
|
- screen.getByText(/Are you sure want to clear topic messages?/i)
|
|
|
- ).toBeInTheDocument();
|
|
|
- });
|
|
|
-
|
|
|
- it('shows a confirmation popup on recreating topic', () => {
|
|
|
- renderComponent();
|
|
|
- const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
- userEvent.click(recreateTopicButton);
|
|
|
- expect(
|
|
|
- screen.getByText(/Are you sure want to recreate topic?/i)
|
|
|
- ).toBeInTheDocument();
|
|
|
- });
|
|
|
+ it('is calling recreation function after click on Submit button', async () => {
|
|
|
+ renderComponent();
|
|
|
+ const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
+ userEvent.click(recreateTopicButton);
|
|
|
+ const confirmBtn = screen.getByRole('button', { name: /Confirm/i });
|
|
|
|
|
|
- it('calling recreation function after click on Submit button', async () => {
|
|
|
- renderComponent();
|
|
|
- const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
- userEvent.click(recreateTopicButton);
|
|
|
- const confirmBtn = screen.getByRole('button', { name: /Confirm/i });
|
|
|
+ await waitFor(() => userEvent.click(confirmBtn));
|
|
|
+ expect(mockRecreate).toBeCalledTimes(1);
|
|
|
+ });
|
|
|
|
|
|
- await waitFor(() => userEvent.click(confirmBtn));
|
|
|
- expect(mockRecreate).toBeCalledTimes(1);
|
|
|
+ it('closes popup confirmation window after click on Cancel button', () => {
|
|
|
+ renderComponent();
|
|
|
+ const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
+ userEvent.click(recreateTopicButton);
|
|
|
+ const cancelBtn = screen.getByRole('button', { name: /cancel/i });
|
|
|
+ userEvent.click(cancelBtn);
|
|
|
+ expect(
|
|
|
+ screen.queryByText(/Are you sure want to recreate topic?/i)
|
|
|
+ ).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
- it('close popup confirmation window after click on Cancel button', () => {
|
|
|
- renderComponent();
|
|
|
- const recreateTopicButton = screen.getByText(/Recreate topic/i);
|
|
|
- userEvent.click(recreateTopicButton);
|
|
|
- const cancelBtn = screen.getByRole('button', { name: /cancel/i });
|
|
|
- userEvent.click(cancelBtn);
|
|
|
- expect(
|
|
|
- screen.queryByText(/Are you sure want to recreate topic?/i)
|
|
|
- ).not.toBeInTheDocument();
|
|
|
+ describe('Internal routing', () => {
|
|
|
+ const itExpectsCorrectPageRendered = (
|
|
|
+ path: string,
|
|
|
+ tab: string,
|
|
|
+ selector: string
|
|
|
+ ) => {
|
|
|
+ renderComponent(false, path);
|
|
|
+ expect(screen.getByText(tab)).toHaveClass('is-active');
|
|
|
+ expect(screen.getByText(selector)).toBeInTheDocument();
|
|
|
+ };
|
|
|
+
|
|
|
+ it('renders Overview tab by default', () => {
|
|
|
+ itExpectsCorrectPageRendered(defaultPath, 'Overview', 'OverviewMock');
|
|
|
+ });
|
|
|
+ it('renders Messages tabs', () => {
|
|
|
+ itExpectsCorrectPageRendered(
|
|
|
+ clusterTopicMessagesPath(),
|
|
|
+ 'Messages',
|
|
|
+ 'MessagesMock'
|
|
|
+ );
|
|
|
+ });
|
|
|
+ it('renders Consumers tab', () => {
|
|
|
+ itExpectsCorrectPageRendered(
|
|
|
+ clusterTopicConsumerGroupsPath(),
|
|
|
+ 'Consumers',
|
|
|
+ 'ConsumerGroupsMock'
|
|
|
+ );
|
|
|
+ });
|
|
|
+ it('renders Settings tab', () => {
|
|
|
+ itExpectsCorrectPageRendered(
|
|
|
+ clusterTopicSettingsPath(),
|
|
|
+ 'Settings',
|
|
|
+ 'SettingsMock'
|
|
|
+ );
|
|
|
+ });
|
|
|
+ it('renders Statistics tab', () => {
|
|
|
+ itExpectsCorrectPageRendered(
|
|
|
+ clusterTopicStatisticsPath(),
|
|
|
+ 'Statistics',
|
|
|
+ 'StatisticsMock'
|
|
|
+ );
|
|
|
+ });
|
|
|
});
|
|
|
});
|