Upgrade to React 18 (#1955)
* Upgrade deps * migration * Fix specs * exclude index.tsx from sonar metrics * Update deps
This commit is contained in:
parent
1e3561ea28
commit
eb47ec012d
76 changed files with 6635 additions and 5786 deletions
11106
kafka-ui-react-app/package-lock.json
generated
11106
kafka-ui-react-app/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"name": "kafka-ui",
|
||||
"version": "0.1.0",
|
||||
"version": "0.4.0",
|
||||
"homepage": "./",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@hookform/error-message": "^2.0.0",
|
||||
"@hookform/resolvers": "^2.7.1",
|
||||
"@reduxjs/toolkit": "^1.7.1",
|
||||
"@reduxjs/toolkit": "^1.8.1",
|
||||
"@rooks/use-outside-click-ref": "^4.10.1",
|
||||
"@testing-library/react": "^12.0.0",
|
||||
"@testing-library/react": "^13.2.0",
|
||||
"@types/eventsource": "^1.1.6",
|
||||
"@types/yup": "^0.29.13",
|
||||
"ace-builds": "^1.4.12",
|
||||
|
@ -17,22 +17,22 @@
|
|||
"bulma": "^0.9.3",
|
||||
"classnames": "^2.2.6",
|
||||
"dayjs": "^1.10.6",
|
||||
"eslint-import-resolver-node": "^0.3.5",
|
||||
"eslint-import-resolver-typescript": "^2.4.0",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
"eslint-import-resolver-typescript": "^2.7.1",
|
||||
"fetch-mock": "^9.11.0",
|
||||
"json-schema-faker": "^0.5.0-rcv.39",
|
||||
"lodash": "^4.17.21",
|
||||
"node-fetch": "^2.6.1",
|
||||
"pretty-ms": "^7.0.1",
|
||||
"react": "^17.0.1",
|
||||
"react": "^18.1.0",
|
||||
"react-ace": "^9.4.3",
|
||||
"react-datepicker": "^4.2.0",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-hook-form": "7.6.9",
|
||||
"react-multi-select-component": "^4.0.6",
|
||||
"react-redux": "^7.2.6",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-router-dom": "^5.3.1",
|
||||
"redux": "^4.1.1",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"sass": "^1.43.4",
|
||||
|
@ -79,39 +79,36 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@openapitools/openapi-generator-cli": "^2.4.15",
|
||||
"@openapitools/openapi-generator-cli": "^2.5.1",
|
||||
"@testing-library/dom": "^8.11.1",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/classnames": "^2.2.11",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash": "^4.14.172",
|
||||
"@types/node": "^16.4.13",
|
||||
"@types/node-fetch": "^3.0.3",
|
||||
"@types/react": "^17.0.16",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react-datepicker": "^4.1.4",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react-dom": "^18.0.3",
|
||||
"@types/react-redux": "^7.1.18",
|
||||
"@types/react-router-dom": "^5.1.8",
|
||||
"@types/react-test-renderer": "^17.0.1",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/redux-mock-store": "^1.0.3",
|
||||
"@types/styled-components": "^5.1.13",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"dotenv": "^15.0.0",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-airbnb": "^19.0.0",
|
||||
"eslint-config-airbnb-typescript": "^16.1.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"dotenv": "^16.0.1",
|
||||
"eslint": "^8.15.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jest-dom": "^4.0.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"esprint": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.5.0",
|
||||
"fetch-mock-jest": "^1.5.1",
|
||||
"history": "^5.0.0",
|
||||
"http-proxy-middleware": "^2.0.1",
|
||||
|
@ -120,8 +117,7 @@
|
|||
"jest-styled-components": "^7.0.6",
|
||||
"lint-staged": "^12.1.2",
|
||||
"prettier": "^2.3.1",
|
||||
"react-scripts": "5.0.0",
|
||||
"react-test-renderer": "^17.0.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"redux-mock-store": "^1.5.4",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^26.5.4",
|
||||
|
|
|
@ -2,7 +2,7 @@ sonar.projectKey=com.provectus:kafka-ui_frontend
|
|||
sonar.organization=provectus
|
||||
|
||||
sonar.sources=.
|
||||
sonar.exclusions=**/__tests__/**,**/__test__/**,src/serviceWorker.ts,src/setupTests.ts,src/setupProxy.js,**/fixtures.ts,src/lib/testHelpers.tsx
|
||||
sonar.exclusions=**/__tests__/**,**/__test__/**,src/serviceWorker.ts,src/setupTests.ts,src/setupProxy.js,**/fixtures.ts,src/lib/testHelpers.tsx,src/index.tsx
|
||||
|
||||
sonar.typescript.lcov.reportPaths=./coverage/lcov.info
|
||||
sonar.testExecutionReportPaths=./test-report.xml
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import React from 'react';
|
||||
import { Action, FailurePayload, ServerResponse } from 'redux/interfaces';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import Alerts from 'components/Alerts/Alerts';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { store } from 'redux/store';
|
||||
import { UnknownAsyncThunkRejectedWithValueAction } from '@reduxjs/toolkit/dist/matchers';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
describe('Alerts', () => {
|
||||
beforeEach(() => render(<Alerts />, { store }));
|
||||
|
||||
it('renders alerts', async () => {
|
||||
const payload: ServerResponse = {
|
||||
status: 422,
|
||||
statusText: 'Unprocessable Entity',
|
||||
|
@ -30,8 +26,6 @@ describe('Alerts', () => {
|
|||
},
|
||||
error: { message: 'Rejected' },
|
||||
};
|
||||
store.dispatch(action);
|
||||
|
||||
const alert: FailurePayload = {
|
||||
title: '404 - Not Found',
|
||||
message: 'Item is not found',
|
||||
|
@ -41,8 +35,16 @@ describe('Alerts', () => {
|
|||
type: 'CLEAR_TOPIC_MESSAGES__FAILURE',
|
||||
payload: { alert },
|
||||
};
|
||||
|
||||
describe('Alerts', () => {
|
||||
it('renders alerts', async () => {
|
||||
store.dispatch(action);
|
||||
store.dispatch(legacyAction);
|
||||
|
||||
await act(() => {
|
||||
render(<Alerts />, { store });
|
||||
});
|
||||
|
||||
expect(screen.getAllByRole('alert').length).toEqual(2);
|
||||
|
||||
const dissmissAlertButtons = screen.getAllByRole('button');
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { ClusterName } from 'redux/interfaces';
|
||||
import useInterval from 'lib/hooks/useInterval';
|
||||
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
|
||||
import { useParams } from 'react-router';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
|
||||
import { Table } from 'components/common/table/Table/Table.styled';
|
||||
import PageHeading from 'components/common/PageHeading/PageHeading';
|
||||
|
|
|
@ -2,10 +2,11 @@ import React from 'react';
|
|||
import Brokers from 'components/Brokers/Brokers';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { clusterBrokersPath } from 'lib/paths';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { clusterStatsPayload } from 'redux/reducers/brokers/__test__/fixtures';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
describe('Brokers Component', () => {
|
||||
afterEach(() => fetchMock.reset());
|
||||
|
@ -41,23 +42,26 @@ describe('Brokers Component', () => {
|
|||
fetchStatsUrl,
|
||||
clusterStatsPayload
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => {
|
||||
expect(fetchStatsMock.called()).toBeTruthy();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(fetchBrokersMock.called()).toBeTruthy();
|
||||
});
|
||||
|
||||
await waitFor(() => expect(fetchStatsMock.called()).toBeTruthy());
|
||||
await waitFor(() => expect(fetchBrokersMock.called()).toBeTruthy());
|
||||
|
||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||
const rows = screen.getAllByRole('row');
|
||||
expect(rows.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('shows warning when offlinePartitionCount > 0', async () => {
|
||||
const fetchStatsMock = fetchMock.getOnce(fetchStatsUrl, {
|
||||
...clusterStatsPayload,
|
||||
offlinePartitionCount: 1345,
|
||||
});
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(fetchStatsMock.called()).toBeTruthy();
|
||||
});
|
||||
|
@ -76,7 +80,9 @@ describe('Brokers Component', () => {
|
|||
inSyncReplicasCount: testInSyncReplicasCount,
|
||||
outOfSyncReplicasCount: testOutOfSyncReplicasCount,
|
||||
});
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(fetchStatsMock.called()).toBeTruthy();
|
||||
});
|
||||
|
@ -94,7 +100,9 @@ describe('Brokers Component', () => {
|
|||
inSyncReplicasCount: undefined,
|
||||
outOfSyncReplicasCount: testOutOfSyncReplicasCount,
|
||||
});
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(fetchStatsMock.called()).toBeTruthy();
|
||||
});
|
||||
|
@ -108,7 +116,9 @@ describe('Brokers Component', () => {
|
|||
inSyncReplicasCount: testInSyncReplicasCount,
|
||||
outOfSyncReplicasCount: undefined,
|
||||
});
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(fetchStatsMock.called()).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -85,7 +85,7 @@ const Actions: React.FC<ActionsProps> = ({
|
|||
}, [restartConnector, clusterName, connectName, connectorName]);
|
||||
|
||||
const restartTasksHandler = React.useCallback(
|
||||
(actionType) => {
|
||||
(actionType: ConnectorAction) => {
|
||||
restartTasks({
|
||||
clusterName,
|
||||
connectName,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { useParams } from 'react-router';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import {
|
||||
ClusterName,
|
||||
ConnectName,
|
||||
|
|
|
@ -6,9 +6,9 @@ import {
|
|||
} from 'lib/paths';
|
||||
import Edit, { EditProps } from 'components/Connect/Edit/Edit';
|
||||
import { connector } from 'redux/reducers/connect/__test__/fixtures';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { waitFor } from '@testing-library/dom';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { act, fireEvent, screen } from '@testing-library/react';
|
||||
|
||||
jest.mock('components/common/PageLoader/PageLoader', () => 'mock-PageLoader');
|
||||
|
||||
|
@ -52,9 +52,9 @@ describe('Edit', () => {
|
|||
}
|
||||
);
|
||||
|
||||
it('fetches config on mount', () => {
|
||||
it('fetches config on mount', async () => {
|
||||
const fetchConfig = jest.fn();
|
||||
renderComponent({ fetchConfig });
|
||||
await waitFor(() => renderComponent({ fetchConfig }));
|
||||
expect(fetchConfig).toHaveBeenCalledTimes(1);
|
||||
expect(fetchConfig).toHaveBeenCalledWith({
|
||||
clusterName,
|
||||
|
@ -65,9 +65,9 @@ describe('Edit', () => {
|
|||
|
||||
it('calls updateConfig on form submit', async () => {
|
||||
const updateConfig = jest.fn();
|
||||
renderComponent({ updateConfig });
|
||||
await waitFor(() => fireEvent.submit(screen.getByRole('form')));
|
||||
expect(updateConfig).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => renderComponent({ updateConfig }));
|
||||
fireEvent.submit(screen.getByRole('form'));
|
||||
await waitFor(() => expect(updateConfig).toHaveBeenCalledTimes(1));
|
||||
expect(updateConfig).toHaveBeenCalledWith({
|
||||
clusterName,
|
||||
connectName,
|
||||
|
@ -78,9 +78,10 @@ describe('Edit', () => {
|
|||
|
||||
it('redirects to connector config view on successful submit', async () => {
|
||||
const updateConfig = jest.fn().mockResolvedValueOnce(connector);
|
||||
renderComponent({ updateConfig });
|
||||
await waitFor(() => fireEvent.submit(screen.getByRole('form')));
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => renderComponent({ updateConfig }));
|
||||
fireEvent.submit(screen.getByRole('form'));
|
||||
|
||||
await waitFor(() => expect(mockHistoryPush).toHaveBeenCalledTimes(1));
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith(
|
||||
clusterConnectConnectorConfigPath(clusterName, connectName, connectorName)
|
||||
);
|
||||
|
@ -88,8 +89,10 @@ describe('Edit', () => {
|
|||
|
||||
it('does not redirect to connector config view on unsuccessful submit', async () => {
|
||||
const updateConfig = jest.fn().mockResolvedValueOnce(undefined);
|
||||
renderComponent({ updateConfig });
|
||||
await waitFor(() => fireEvent.submit(screen.getByRole('form')));
|
||||
await waitFor(() => renderComponent({ updateConfig }));
|
||||
await act(() => {
|
||||
fireEvent.submit(screen.getByRole('form'));
|
||||
});
|
||||
expect(mockHistoryPush).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,13 +6,15 @@ import ClusterContext, {
|
|||
} from 'components/contexts/ClusterContext';
|
||||
import ListContainer from 'components/Connect/List/ListContainer';
|
||||
import List, { ListProps } from 'components/Connect/List/List';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
|
||||
describe('Connectors List', () => {
|
||||
describe('Container', () => {
|
||||
it('renders view with initial state of storage', () => {
|
||||
it('renders view with initial state of storage', async () => {
|
||||
await act(() => {
|
||||
render(<ListContainer />);
|
||||
});
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Connectors');
|
||||
});
|
||||
});
|
||||
|
@ -21,10 +23,11 @@ describe('Connectors List', () => {
|
|||
const fetchConnects = jest.fn();
|
||||
const fetchConnectors = jest.fn();
|
||||
const setConnectorSearch = jest.fn();
|
||||
const setupComponent = (
|
||||
const renderComponent = (
|
||||
props: Partial<ListProps> = {},
|
||||
contextValue: ContextProps = initialValue
|
||||
) => (
|
||||
) => {
|
||||
render(
|
||||
<ClusterContext.Provider value={contextValue}>
|
||||
<List
|
||||
areConnectorsFetching
|
||||
|
@ -39,45 +42,44 @@ describe('Connectors List', () => {
|
|||
/>
|
||||
</ClusterContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
it('renders PageLoader', () => {
|
||||
render(setupComponent({ areConnectorsFetching: true }));
|
||||
it('renders PageLoader', async () => {
|
||||
await act(() => renderComponent({ areConnectorsFetching: true }));
|
||||
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('row')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders table', () => {
|
||||
render(setupComponent({ areConnectorsFetching: false }));
|
||||
renderComponent({ areConnectorsFetching: false });
|
||||
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders connectors list', () => {
|
||||
render(
|
||||
setupComponent({
|
||||
renderComponent({
|
||||
areConnectorsFetching: false,
|
||||
connectors,
|
||||
})
|
||||
);
|
||||
});
|
||||
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||
expect(screen.getAllByRole('row').length).toEqual(3);
|
||||
});
|
||||
|
||||
it('handles fetchConnects and fetchConnectors', () => {
|
||||
render(setupComponent());
|
||||
renderComponent();
|
||||
expect(fetchConnects).toHaveBeenCalledTimes(1);
|
||||
expect(fetchConnectors).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('renders actions if cluster is not readonly', () => {
|
||||
render(setupComponent({}, { ...initialValue, isReadOnly: false }));
|
||||
renderComponent({}, { ...initialValue, isReadOnly: false });
|
||||
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('readonly cluster', () => {
|
||||
it('does not render actions if cluster is readonly', () => {
|
||||
render(setupComponent({}, { ...initialValue, isReadOnly: true }));
|
||||
renderComponent({}, { ...initialValue, isReadOnly: true });
|
||||
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,8 +6,8 @@ import {
|
|||
} from 'lib/paths';
|
||||
import New, { NewProps } from 'components/Connect/New/New';
|
||||
import { connects, connector } from 'redux/reducers/connect/__test__/fixtures';
|
||||
import { Route } from 'react-router';
|
||||
import { waitFor, fireEvent, screen } from '@testing-library/react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { fireEvent, screen, act } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { ControllerRenderProps } from 'react-hook-form';
|
||||
|
||||
|
@ -30,6 +30,7 @@ jest.mock('react-router-dom', () => ({
|
|||
describe('New', () => {
|
||||
const clusterName = 'my-cluster';
|
||||
const simulateFormSubmit = async () => {
|
||||
await act(() => {
|
||||
userEvent.type(
|
||||
screen.getByPlaceholderText('Connector Name'),
|
||||
'my-connector'
|
||||
|
@ -38,10 +39,12 @@ describe('New', () => {
|
|||
screen.getByPlaceholderText('json'),
|
||||
'{"class":"MyClass"}'.replace(/[{[]/g, '$&$&')
|
||||
);
|
||||
});
|
||||
|
||||
expect(screen.getByPlaceholderText('json')).toHaveValue(
|
||||
'{"class":"MyClass"}'
|
||||
);
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
fireEvent.submit(screen.getByRole('form'));
|
||||
});
|
||||
};
|
||||
|
@ -62,7 +65,9 @@ describe('New', () => {
|
|||
|
||||
it('fetches connects on mount', async () => {
|
||||
const fetchConnects = jest.fn();
|
||||
await waitFor(() => renderComponent({ fetchConnects }));
|
||||
await act(() => {
|
||||
renderComponent({ fetchConnects });
|
||||
});
|
||||
expect(fetchConnects).toHaveBeenCalledTimes(1);
|
||||
expect(fetchConnects).toHaveBeenCalledWith(clusterName);
|
||||
});
|
||||
|
@ -71,6 +76,7 @@ describe('New', () => {
|
|||
const createConnector = jest.fn();
|
||||
renderComponent({ createConnector });
|
||||
await simulateFormSubmit();
|
||||
|
||||
expect(createConnector).toHaveBeenCalledTimes(1);
|
||||
expect(createConnector).toHaveBeenCalledWith({
|
||||
clusterName,
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
import { ConsumerGroupID } from 'redux/interfaces/consumerGroup';
|
||||
import PageLoader from 'components/common/PageLoader/PageLoader';
|
||||
import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import ClusterContext from 'components/contexts/ClusterContext';
|
||||
import PageHeading from 'components/common/PageHeading/PageHeading';
|
||||
import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon';
|
||||
|
|
|
@ -15,7 +15,7 @@ import 'react-datepicker/dist/react-datepicker.css';
|
|||
import { groupBy } from 'lodash';
|
||||
import PageLoader from 'components/common/PageLoader/PageLoader';
|
||||
import { ErrorMessage } from '@hookform/error-message';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import Select from 'components/common/Select/Select';
|
||||
import { InputLabel } from 'components/common/Input/InputLabel.styled';
|
||||
import { Button } from 'components/common/Button/Button';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { Route } from 'react-router';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { act, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { clusterConsumerGroupResetOffsetsPath } from 'lib/paths';
|
||||
|
@ -77,12 +77,12 @@ describe('ResetOffsets', () => {
|
|||
fetchMock.reset();
|
||||
});
|
||||
|
||||
it('renders progress bar for initial state', () => {
|
||||
it('renders progress bar for initial state', async () => {
|
||||
fetchMock.getOnce(
|
||||
`/api/clusters/${clusterName}/consumer-groups/${groupId}`,
|
||||
404
|
||||
);
|
||||
renderComponent();
|
||||
await waitFor(() => renderComponent());
|
||||
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
@ -93,11 +93,10 @@ describe('ResetOffsets', () => {
|
|||
`/api/clusters/${clusterName}/consumer-groups/${groupId}`,
|
||||
consumerGroupPayload
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() =>
|
||||
expect(fetchConsumerGroupMock.called()).toBeTruthy()
|
||||
);
|
||||
await waitFor(() => screen.queryByRole('form'));
|
||||
});
|
||||
expect(fetchConsumerGroupMock.called()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calls resetConsumerGroupOffsets with EARLIEST', async () => {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { screen } from '@testing-library/react';
|
|||
import TopicContents from 'components/ConsumerGroups/Details/TopicContents/TopicContents';
|
||||
import { consumerGroupPayload } from 'redux/reducers/consumerGroups/__test__/fixtures';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { ConsumerGroupTopicPartition } from 'generated-sources';
|
||||
|
||||
const clusterName = 'cluster1';
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route, Router } from 'react-router';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import {
|
||||
clusterConsumerGroupDetailsPath,
|
||||
clusterConsumerGroupResetOffsetsPath,
|
||||
|
@ -16,6 +16,7 @@ import {
|
|||
waitForElementToBeRemoved,
|
||||
} from '@testing-library/dom';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
const clusterName = 'cluster1';
|
||||
const { groupId } = consumerGroupPayload;
|
||||
|
@ -92,20 +93,18 @@ describe('Details component', () => {
|
|||
|
||||
it('handles [Delete consumer group] click', async () => {
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||
await act(() => {
|
||||
userEvent.click(screen.getByText('Delete consumer group'));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByRole('dialog')).toBeInTheDocument()
|
||||
);
|
||||
|
||||
});
|
||||
expect(screen.queryByRole('dialog')).toBeInTheDocument();
|
||||
const deleteConsumerGroupMock = fetchMock.deleteOnce(
|
||||
`/api/clusters/${clusterName}/consumer-groups/${groupId}`,
|
||||
200
|
||||
);
|
||||
await act(() => {
|
||||
userEvent.click(screen.getByText('Submit'));
|
||||
await waitFor(() =>
|
||||
expect(deleteConsumerGroupMock.called()).toBeTruthy()
|
||||
);
|
||||
});
|
||||
expect(deleteConsumerGroupMock.called()).toBeTruthy();
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||
expect(history.location.pathname).toEqual(
|
||||
clusterConsumerGroupsPath(clusterName)
|
||||
|
|
|
@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import ListItem from 'components/ConsumerGroups/Details/ListItem';
|
||||
import { consumerGroupPayload } from 'redux/reducers/consumerGroups/__test__/fixtures';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { ConsumerGroupTopicPartition } from 'generated-sources';
|
||||
|
||||
const clusterName = 'cluster1';
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { clusterConsumerGroupsPath } from 'lib/paths';
|
||||
import {
|
||||
act,
|
||||
screen,
|
||||
waitFor,
|
||||
waitForElementToBeRemoved,
|
||||
|
@ -12,7 +13,7 @@ import {
|
|||
} from 'redux/reducers/consumerGroups/__test__/fixtures';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { Route, Router } from 'react-router';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import { ConsumerGroupOrdering, SortOrder } from 'generated-sources';
|
||||
import { createMemoryHistory } from 'history';
|
||||
|
||||
|
@ -37,7 +38,6 @@ const renderComponent = (history = historyMock) =>
|
|||
describe('ConsumerGroups', () => {
|
||||
it('renders with initial state', async () => {
|
||||
renderComponent();
|
||||
|
||||
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
@ -54,10 +54,10 @@ describe('ConsumerGroups', () => {
|
|||
sortOrder: SortOrder.ASC,
|
||||
},
|
||||
});
|
||||
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => expect(fetchMock.calls().length).toBe(1));
|
||||
|
||||
});
|
||||
expect(fetchMock.calls().length).toBe(1);
|
||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||
expect(screen.getByText('No active consumer groups')).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import PageLoader from 'components/common/PageLoader/PageLoader';
|
|||
import ListItem from 'components/KsqlDb/List/ListItem';
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useParams } from 'react-router';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { fetchKsqlDbTables } from 'redux/reducers/ksqlDb/ksqlDbSlice';
|
||||
import { getKsqlDbTables } from 'redux/reducers/ksqlDb/selectors';
|
||||
import { clusterKsqlDbQueryPath } from 'lib/paths';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import List from 'components/KsqlDb/List/List';
|
||||
import { Route, Router } from 'react-router';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { clusterKsqlDbPath } from 'lib/paths';
|
||||
import { render } from 'lib/testHelpers';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useCallback, useEffect, FC, useState } from 'react';
|
||||
import { useParams } from 'react-router';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import TableRenderer from 'components/KsqlDb/Query/renderer/TableRenderer/TableRenderer';
|
||||
import {
|
||||
executeKsql,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { render } from 'lib/testHelpers';
|
||||
import React from 'react';
|
||||
import QueryForm, { Props } from 'components/KsqlDb/Query/QueryForm/QueryForm';
|
||||
import { screen, waitFor, within } from '@testing-library/dom';
|
||||
import { screen, within } from '@testing-library/dom';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
const renderComponent = (props: Props) => render(<QueryForm {...props} />);
|
||||
|
||||
|
@ -65,7 +66,7 @@ describe('QueryForm', () => {
|
|||
submitHandler: submitFn,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
expect(screen.getByText('ksql is a required field')).toBeInTheDocument();
|
||||
|
@ -81,7 +82,7 @@ describe('QueryForm', () => {
|
|||
submitHandler: jest.fn(),
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
// the use of `paste` is a hack that i found somewhere,
|
||||
// `type` won't work
|
||||
userEvent.paste(
|
||||
|
@ -89,12 +90,10 @@ describe('QueryForm', () => {
|
|||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'not-a-JSON-string'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.getByText('streamsProperties is not JSON object')
|
||||
|
@ -110,19 +109,15 @@ describe('QueryForm', () => {
|
|||
submitHandler: jest.fn(),
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"totallyJSON": "string"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
expect(
|
||||
screen.queryByText('streamsProperties is not JSON object')
|
||||
).not.toBeInTheDocument();
|
||||
|
@ -138,25 +133,21 @@ describe('QueryForm', () => {
|
|||
submitHandler: submitFn,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"totallyJSON": "string"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.queryByText('ksql is a required field')
|
||||
|
@ -181,7 +172,7 @@ describe('QueryForm', () => {
|
|||
|
||||
expect(screen.getByRole('button', { name: 'Clear results' })).toBeEnabled();
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Clear results' }))
|
||||
);
|
||||
|
||||
|
@ -200,7 +191,7 @@ describe('QueryForm', () => {
|
|||
|
||||
expect(screen.getByRole('button', { name: 'Stop query' })).toBeEnabled();
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Stop query' }))
|
||||
);
|
||||
|
||||
|
@ -217,19 +208,17 @@ describe('QueryForm', () => {
|
|||
submitHandler: submitFn,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.type(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'{ctrl}{enter}'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
expect(submitFn.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
@ -244,30 +233,26 @@ describe('QueryForm', () => {
|
|||
submitHandler: submitFn,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"some":"json"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.type(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{ctrl}{enter}'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
expect(submitFn.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
@ -281,20 +266,17 @@ describe('QueryForm', () => {
|
|||
submitHandler: jest.fn(),
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('button', {
|
||||
name: 'Clear',
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
expect(screen.queryByText('show tables;')).not.toBeInTheDocument();
|
||||
});
|
||||
|
@ -308,25 +290,21 @@ describe('QueryForm', () => {
|
|||
submitHandler: jest.fn(),
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"some":"json"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('button', {
|
||||
name: 'Clear',
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
expect(screen.queryByText('{"some":"json"}')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,11 +3,12 @@ import React from 'react';
|
|||
import Query, {
|
||||
getFormattedErrorFromTableData,
|
||||
} from 'components/KsqlDb/Query/Query';
|
||||
import { screen, waitFor, within } from '@testing-library/dom';
|
||||
import { screen, within } from '@testing-library/dom';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { clusterKsqlDbQueryPath } from 'lib/paths';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
const clusterName = 'testLocal';
|
||||
const renderComponent = () =>
|
||||
|
@ -42,16 +43,14 @@ describe('Query', () => {
|
|||
value: EventSourceMock,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
expect(mock.calls().length).toBe(1);
|
||||
});
|
||||
|
||||
|
@ -66,25 +65,19 @@ describe('Query', () => {
|
|||
value: EventSourceMock,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"some":"json"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
expect(mock.calls().length).toBe(1);
|
||||
});
|
||||
|
||||
|
@ -99,25 +92,19 @@ describe('Query', () => {
|
|||
value: EventSourceMock,
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
within(screen.getByLabelText('KSQL')).getByRole('textbox'),
|
||||
'show tables;'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.paste(
|
||||
within(
|
||||
screen.getByLabelText('Stream properties (JSON format)')
|
||||
).getByRole('textbox'),
|
||||
'{"some":"json"}'
|
||||
)
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }))
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Execute' }));
|
||||
});
|
||||
expect(mock.calls().length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ const ClusterMenu: React.FC<Props> = ({
|
|||
singleMode,
|
||||
}) => {
|
||||
const hasFeatureConfigured = React.useCallback(
|
||||
(key) => features?.includes(key),
|
||||
(key: ClusterFeaturesEnum) => features?.includes(key),
|
||||
[features]
|
||||
);
|
||||
const [isOpen, setIsOpen] = React.useState(!!singleMode);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { NavLinkProps } from 'react-router-dom';
|
||||
|
||||
import * as S from './Nav.styled';
|
||||
|
@ -11,7 +11,9 @@ export interface ClusterMenuItemProps {
|
|||
isActive?: NavLinkProps['isActive'];
|
||||
}
|
||||
|
||||
const ClusterMenuItem: React.FC<ClusterMenuItemProps> = (props) => {
|
||||
const ClusterMenuItem: React.FC<PropsWithChildren<ClusterMenuItemProps>> = (
|
||||
props
|
||||
) => {
|
||||
const { to, title, children, exact, isTopLevel, isActive } = props;
|
||||
|
||||
if (to) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import {
|
||||
clusterSchemasPath,
|
||||
clusterSchemaSchemaDiffPath,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import Details from 'components/Schemas/Details/Details';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { clusterSchemaPath } from 'lib/paths';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import {
|
||||
|
@ -14,6 +14,7 @@ import ClusterContext, {
|
|||
initialValue as contextInitialValue,
|
||||
} from 'components/contexts/ClusterContext';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
import { versionPayload, versionEmptyPayload } from './fixtures';
|
||||
|
||||
|
@ -24,8 +25,8 @@ const schemasAPIVersionsUrl = `/api/clusters/${clusterName}/schemas/${schemaVers
|
|||
const renderComponent = (
|
||||
initialState: RootState['schemas'] = schemasInitialState,
|
||||
context: ContextProps = contextInitialValue
|
||||
) => {
|
||||
return render(
|
||||
) =>
|
||||
render(
|
||||
<Route path={clusterSchemaPath(':clusterName', ':subject')}>
|
||||
<ClusterContext.Provider value={context}>
|
||||
<Details />
|
||||
|
@ -38,7 +39,6 @@ const renderComponent = (
|
|||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
describe('Details', () => {
|
||||
afterEach(() => fetchMock.reset());
|
||||
|
@ -50,7 +50,10 @@ describe('Details', () => {
|
|||
schemasAPIVersionsUrl,
|
||||
404
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(schemasAPILatestMock.called()).toBeTruthy();
|
||||
});
|
||||
|
@ -78,7 +81,9 @@ describe('Details', () => {
|
|||
schemasAPIVersionsUrl,
|
||||
versionPayload
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(schemasAPILatestMock.called()).toBeTruthy();
|
||||
});
|
||||
|
@ -104,7 +109,9 @@ describe('Details', () => {
|
|||
schemasAPIVersionsUrl,
|
||||
versionEmptyPayload
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(schemasAPILatestMock.called()).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import { SchemaSubject } from 'generated-sources';
|
|||
import { clusterSchemaSchemaDiffPath } from 'lib/paths';
|
||||
import PageLoader from 'components/common/PageLoader/PageLoader';
|
||||
import DiffViewer from 'components/common/DiffViewer/DiffViewer';
|
||||
import { useHistory, useParams, useLocation } from 'react-router';
|
||||
import { useHistory, useParams, useLocation } from 'react-router-dom';
|
||||
import {
|
||||
fetchSchemaVersions,
|
||||
SCHEMAS_VERSIONS_FETCH_ACTION,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { useForm, Controller, FormProvider } from 'react-hook-form';
|
||||
import {
|
||||
CompatibilityLevelCompatibilityEnum,
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
schemasInitialState,
|
||||
schemaVersion,
|
||||
} from 'redux/reducers/schemas/__test__/fixtures';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import ClusterContext, {
|
||||
ContextProps,
|
||||
|
@ -14,6 +14,7 @@ import ClusterContext, {
|
|||
} from 'components/contexts/ClusterContext';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
const clusterName = 'testClusterName';
|
||||
const schemasAPILatestUrl = `/api/clusters/${clusterName}/schemas/${schemaVersion.subject}/latest`;
|
||||
|
@ -21,8 +22,8 @@ const schemasAPILatestUrl = `/api/clusters/${clusterName}/schemas/${schemaVersio
|
|||
const renderComponent = (
|
||||
initialState: RootState['schemas'] = schemasInitialState,
|
||||
context: ContextProps = contextInitialValue
|
||||
) => {
|
||||
return render(
|
||||
) =>
|
||||
render(
|
||||
<Route path={clusterSchemaEditPath(':clusterName', ':subject')}>
|
||||
<ClusterContext.Provider value={context}>
|
||||
<Edit />
|
||||
|
@ -35,21 +36,17 @@ const renderComponent = (
|
|||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
describe('Edit', () => {
|
||||
afterEach(() => fetchMock.reset());
|
||||
|
||||
describe('fetch failed', () => {
|
||||
beforeEach(async () => {
|
||||
it('renders pageloader', async () => {
|
||||
const schemasAPILatestMock = fetchMock.getOnce(schemasAPILatestUrl, 404);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => {
|
||||
expect(schemasAPILatestMock.called()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders pageloader', () => {
|
||||
await waitFor(() => expect(schemasAPILatestMock.called()).toBeTruthy());
|
||||
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
||||
expect(screen.queryByText(schemaVersion.subject)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Submit')).not.toBeInTheDocument();
|
||||
|
@ -58,19 +55,15 @@ describe('Edit', () => {
|
|||
|
||||
describe('fetch success', () => {
|
||||
describe('has schema versions', () => {
|
||||
beforeEach(async () => {
|
||||
it('renders component with schema info', async () => {
|
||||
const schemasAPILatestMock = fetchMock.getOnce(
|
||||
schemasAPILatestUrl,
|
||||
schemaVersion
|
||||
);
|
||||
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => {
|
||||
expect(schemasAPILatestMock.called()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders component with schema info', () => {
|
||||
await waitFor(() => expect(schemasAPILatestMock.called()).toBeTruthy());
|
||||
expect(screen.getByText('Submit')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import { act, screen, waitFor, within } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { CompatibilityLevelCompatibilityEnum } from 'generated-sources';
|
||||
import GlobalSchemaSelector from 'components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { clusterSchemasPath } from 'lib/paths';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
const clusterName = 'testClusterName';
|
||||
|
@ -42,7 +42,9 @@ describe('GlobalSchemaSelector', () => {
|
|||
`api/clusters/${clusterName}/schemas/compatibility`,
|
||||
{ compatibility: CompatibilityLevelCompatibilityEnum.FULL }
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(fetchGlobalCompatibilityLevelMock.called()).toBeTruthy()
|
||||
);
|
||||
|
@ -89,7 +91,10 @@ describe('GlobalSchemaSelector', () => {
|
|||
});
|
||||
await waitFor(() => expect(putNewCompatibilityMock.called()).toBeTruthy());
|
||||
await waitFor(() => expect(getSchemasMock.called()).toBeTruthy());
|
||||
expect(screen.queryByText('Confirm the action')).not.toBeInTheDocument();
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByText('Confirm the action')).not.toBeInTheDocument()
|
||||
);
|
||||
expectOptionIsSelected(CompatibilityLevelCompatibilityEnum.FORWARD);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
import List from 'components/Schemas/List/List';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { clusterSchemasPath } from 'lib/paths';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import {
|
||||
schemasFulfilledState,
|
||||
schemasInitialState,
|
||||
|
@ -52,9 +52,11 @@ describe('List', () => {
|
|||
schemasAPICompabilityUrl,
|
||||
404
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => expect(fetchSchemasMock.called()).toBeTruthy());
|
||||
await waitFor(() => expect(fetchCompabilityMock.called()).toBeTruthy());
|
||||
});
|
||||
expect(fetchSchemasMock.called()).toBeTruthy();
|
||||
expect(fetchCompabilityMock.called()).toBeTruthy();
|
||||
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -70,9 +72,11 @@ describe('List', () => {
|
|||
schemasAPICompabilityUrl,
|
||||
200
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
await waitFor(() => expect(fetchSchemasMock.called()).toBeTruthy());
|
||||
await waitFor(() => expect(fetchCompabilityMock.called()).toBeTruthy());
|
||||
});
|
||||
expect(fetchSchemasMock.called()).toBeTruthy();
|
||||
expect(fetchCompabilityMock.called()).toBeTruthy();
|
||||
});
|
||||
it('renders empty table', () => {
|
||||
expect(screen.getByText('No schemas found')).toBeInTheDocument();
|
||||
|
@ -88,9 +92,11 @@ describe('List', () => {
|
|||
schemasAPICompabilityUrl,
|
||||
200
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent(schemasFulfilledState);
|
||||
await waitFor(() => expect(fetchSchemasMock.called()).toBeTruthy());
|
||||
await waitFor(() => expect(fetchCompabilityMock.called()).toBeTruthy());
|
||||
});
|
||||
expect(fetchSchemasMock.called()).toBeTruthy();
|
||||
expect(fetchCompabilityMock.called()).toBeTruthy();
|
||||
});
|
||||
it('renders list', () => {
|
||||
expect(screen.getByText(schemaVersion1.subject)).toBeInTheDocument();
|
||||
|
@ -104,12 +110,13 @@ describe('List', () => {
|
|||
schemasAPIUrl,
|
||||
schemasPayload
|
||||
);
|
||||
|
||||
await act(() => {
|
||||
renderComponent(schemasFulfilledState, {
|
||||
...contextInitialValue,
|
||||
isReadOnly: true,
|
||||
});
|
||||
await waitFor(() => expect(fetchSchemasMock.called()).toBeTruthy());
|
||||
});
|
||||
expect(fetchSchemasMock.called()).toBeTruthy();
|
||||
});
|
||||
it('does not render Create Schema button', () => {
|
||||
expect(screen.queryByText('Create Schema')).not.toBeInTheDocument();
|
||||
|
|
|
@ -5,7 +5,7 @@ import { ErrorMessage } from '@hookform/error-message';
|
|||
import { clusterSchemaPath } from 'lib/paths';
|
||||
import { SchemaType } from 'generated-sources';
|
||||
import { SCHEMA_NAME_VALIDATION_PATTERN } from 'lib/constants';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { InputLabel } from 'components/common/Input/InputLabel.styled';
|
||||
import Input from 'components/common/Input/Input';
|
||||
import { FormError } from 'components/common/Input/Input.styled';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import New from 'components/Schemas/New/New';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { clusterSchemaNewPath } from 'lib/paths';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { screen } from '@testing-library/dom';
|
||||
|
||||
const clusterName = 'local';
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
clusterSchemasPath,
|
||||
} from 'lib/paths';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import { Route } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { schemaVersion } from 'redux/reducers/schemas/__test__/fixtures';
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import React from 'react';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import {
|
||||
TopicWithDetailedInfo,
|
||||
ClusterName,
|
||||
TopicName,
|
||||
} from 'redux/interfaces';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { clusterTopicCopyPath, clusterTopicNewPath } from 'lib/paths';
|
||||
import usePagination from 'lib/hooks/usePagination';
|
||||
import useModal from 'lib/hooks/useModal';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import { Route, Router, StaticRouter } from 'react-router';
|
||||
import { Route, Router, StaticRouter } from 'react-router-dom';
|
||||
import ClusterContext, {
|
||||
ContextProps,
|
||||
} from 'components/contexts/ClusterContext';
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from 'redux/actions';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { getResponse } from 'lib/errorHandling';
|
||||
import { useHistory, useLocation, useParams } from 'react-router';
|
||||
import { useHistory, useLocation, useParams } from 'react-router-dom';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { topicFormValidationSchema } from 'lib/yupExtended';
|
||||
import PageHeading from 'components/common/PageHeading/PageHeading';
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React from 'react';
|
||||
import New from 'components/Topics/New/New';
|
||||
import { Route, Router } from 'react-router';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import { RootState } from 'redux/interfaces';
|
||||
import { Provider } from 'react-redux';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { act, screen, waitFor } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import fetchMock from 'fetch-mock-jest';
|
||||
import {
|
||||
|
@ -139,7 +139,7 @@ describe('New', () => {
|
|||
jest.spyOn(mocked, 'push');
|
||||
renderComponent(mocked);
|
||||
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.type(screen.getByPlaceholderText('Topic Name'), topicName);
|
||||
userEvent.click(screen.getByText(/submit/i));
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from 'generated-sources';
|
||||
import React, { useContext } from 'react';
|
||||
import { omitBy } from 'lodash';
|
||||
import { useHistory, useLocation } from 'react-router';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import DatePicker from 'react-datepicker';
|
||||
import MultiSelect from 'components/common/MultiSelect/MultiSelect.styled';
|
||||
import { Option } from 'react-multi-select-component/dist/lib/interfaces';
|
||||
|
|
|
@ -3,7 +3,7 @@ import AddEditFilterContainer, {
|
|||
AddEditFilterContainerProps,
|
||||
} from 'components/Topics/Topic/Details/Messages/Filters/AddEditFilterContainer';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { MessageFilters } from 'components/Topics/Topic/Details/Messages/Filters/Filters';
|
||||
|
||||
|
@ -15,7 +15,9 @@ describe('AddEditFilterContainer component', () => {
|
|||
code: 'mockCode',
|
||||
};
|
||||
|
||||
const setupComponent = (props: Partial<AddEditFilterContainerProps> = {}) =>
|
||||
const renderComponent = (
|
||||
props: Partial<AddEditFilterContainerProps> = {}
|
||||
) => {
|
||||
render(
|
||||
<AddEditFilterContainer
|
||||
cancelBtnHandler={jest.fn()}
|
||||
|
@ -23,10 +25,11 @@ describe('AddEditFilterContainer component', () => {
|
|||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
describe('default Component Parameters', () => {
|
||||
beforeEach(async () => {
|
||||
await waitFor(() => setupComponent());
|
||||
await act(() => renderComponent());
|
||||
});
|
||||
|
||||
it('should check the default Button text', () => {
|
||||
|
@ -40,39 +43,43 @@ describe('AddEditFilterContainer component', () => {
|
|||
const inputs = screen.getAllByRole('textbox');
|
||||
|
||||
const textAreaElement = inputs[0] as HTMLTextAreaElement;
|
||||
userEvent.paste(textAreaElement, 'Hello World With TextArea');
|
||||
await act(() =>
|
||||
userEvent.paste(textAreaElement, 'Hello World With TextArea')
|
||||
);
|
||||
|
||||
const inputNameElement = inputs[1];
|
||||
userEvent.type(inputNameElement, 'Hello World!');
|
||||
await act(() => userEvent.type(inputNameElement, 'Hello World!'));
|
||||
|
||||
await waitFor(() => expect(submitButtonElem).toBeEnabled());
|
||||
expect(submitButtonElem).toBeEnabled();
|
||||
|
||||
userEvent.clear(inputNameElement);
|
||||
await act(() => userEvent.clear(inputNameElement));
|
||||
|
||||
await waitFor(() => expect(submitButtonElem).toBeDisabled());
|
||||
expect(submitButtonElem).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should view the error message after typing and clearing the input', async () => {
|
||||
const inputs = screen.getAllByRole('textbox');
|
||||
|
||||
const textAreaElement = inputs[0] as HTMLTextAreaElement;
|
||||
userEvent.paste(textAreaElement, 'Hello World With TextArea');
|
||||
await act(() =>
|
||||
userEvent.paste(textAreaElement, 'Hello World With TextArea')
|
||||
);
|
||||
|
||||
const inputNameElement = inputs[1];
|
||||
await act(() => {
|
||||
userEvent.type(inputNameElement, 'Hello World!');
|
||||
|
||||
userEvent.clear(inputNameElement);
|
||||
userEvent.clear(textAreaElement);
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText(/required field/i)).toBeInTheDocument()
|
||||
);
|
||||
expect(screen.getByText(/required field/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom setup for the component', () => {
|
||||
it('should render the input with default data if they are passed', async () => {
|
||||
setupComponent({
|
||||
renderComponent({
|
||||
inputDisplayNameDefaultValue: mockData.name,
|
||||
inputCodeDefaultValue: mockData.code,
|
||||
});
|
||||
|
@ -80,23 +87,24 @@ describe('AddEditFilterContainer component', () => {
|
|||
const inputs = screen.getAllByRole('textbox');
|
||||
const textAreaElement = inputs[0] as HTMLTextAreaElement;
|
||||
const inputNameElement = inputs[1];
|
||||
await waitFor(() => expect(inputNameElement).toHaveValue(mockData.name));
|
||||
expect(inputNameElement).toHaveValue(mockData.name);
|
||||
expect(textAreaElement.value).toEqual('');
|
||||
});
|
||||
|
||||
it('should test whether the cancel callback is being called', async () => {
|
||||
const cancelCallback = jest.fn();
|
||||
setupComponent({
|
||||
renderComponent({
|
||||
cancelBtnHandler: cancelCallback,
|
||||
});
|
||||
const cancelBtnElement = screen.getByText(/cancel/i);
|
||||
userEvent.click(cancelBtnElement);
|
||||
await waitFor(() => expect(cancelCallback).toBeCalled());
|
||||
|
||||
await act(() => userEvent.click(cancelBtnElement));
|
||||
expect(cancelCallback).toBeCalled();
|
||||
});
|
||||
|
||||
it('should test whether the submit Callback is being called', async () => {
|
||||
const submitCallback = jest.fn();
|
||||
setupComponent({
|
||||
renderComponent({
|
||||
submitCallback,
|
||||
});
|
||||
|
||||
|
@ -106,30 +114,30 @@ describe('AddEditFilterContainer component', () => {
|
|||
userEvent.paste(textAreaElement, 'Hello World With TextArea');
|
||||
|
||||
const inputNameElement = inputs[1];
|
||||
userEvent.type(inputNameElement, 'Hello World!');
|
||||
await act(() => userEvent.type(inputNameElement, 'Hello World!'));
|
||||
|
||||
const submitBtnElement = screen.getByText(defaultSubmitBtn);
|
||||
|
||||
await waitFor(() => expect(submitBtnElement).toBeEnabled());
|
||||
expect(submitBtnElement).toBeEnabled();
|
||||
|
||||
userEvent.click(submitBtnElement);
|
||||
await act(() => userEvent.click(submitBtnElement));
|
||||
|
||||
await waitFor(() => expect(submitCallback).toBeCalled());
|
||||
expect(submitCallback).toBeCalled();
|
||||
});
|
||||
|
||||
it('should display the checkbox if the props is passed and initially check state', async () => {
|
||||
setupComponent({ isAdd: true });
|
||||
renderComponent({ isAdd: true });
|
||||
const checkbox = screen.getByRole('checkbox');
|
||||
expect(checkbox).toBeInTheDocument();
|
||||
expect(checkbox).not.toBeChecked();
|
||||
await waitFor(() => userEvent.click(checkbox));
|
||||
await act(() => userEvent.click(checkbox));
|
||||
expect(checkbox).toBeChecked();
|
||||
});
|
||||
|
||||
it('should pass and render the correct button text', async () => {
|
||||
const submitBtnText = 'submitBtnTextTest';
|
||||
await waitFor(() =>
|
||||
setupComponent({
|
||||
await act(() =>
|
||||
renderComponent({
|
||||
submitBtnText,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import AddFilter, {
|
|||
} from 'components/Topics/Topic/Details/Messages/Filters/AddFilter';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { MessageFilters } from 'components/Topics/Topic/Details/Messages/Filters/Filters';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
const filters: MessageFilters[] = [
|
||||
|
@ -14,7 +14,7 @@ const filters: MessageFilters[] = [
|
|||
|
||||
const editFilterMock = jest.fn();
|
||||
|
||||
const setupComponent = (props: Partial<FilterModalProps> = {}) =>
|
||||
const renderComponent = (props: Partial<FilterModalProps> = {}) =>
|
||||
render(
|
||||
<AddFilter
|
||||
toggleIsOpen={jest.fn()}
|
||||
|
@ -30,20 +30,21 @@ const setupComponent = (props: Partial<FilterModalProps> = {}) =>
|
|||
|
||||
describe('AddFilter component', () => {
|
||||
it('should test click on Saved Filters redirects to Saved components', () => {
|
||||
setupComponent();
|
||||
renderComponent();
|
||||
userEvent.click(screen.getByRole('savedFilterText'));
|
||||
expect(screen.getByText('Saved filters')).toBeInTheDocument();
|
||||
expect(screen.getAllByRole('savedFilter')).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should test click on return to custom filter redirects to Add filters', async () => {
|
||||
setupComponent();
|
||||
renderComponent();
|
||||
userEvent.click(screen.getByRole('savedFilterText'));
|
||||
|
||||
expect(screen.getByText('Saved filters')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('savedFilterText')).not.toBeInTheDocument();
|
||||
expect(screen.getAllByRole('savedFilter')).toHaveLength(2);
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(screen.getByText(/back to custom filters/i))
|
||||
);
|
||||
expect(screen.queryByText('Saved filters')).not.toBeInTheDocument();
|
||||
|
@ -52,7 +53,9 @@ describe('AddFilter component', () => {
|
|||
|
||||
describe('Add new filter', () => {
|
||||
beforeEach(async () => {
|
||||
await waitFor(() => setupComponent());
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
});
|
||||
|
||||
it('adding new filter', async () => {
|
||||
|
@ -66,8 +69,12 @@ describe('AddFilter component', () => {
|
|||
const addFilterBtn = screen.getByRole('button', { name: /Add filter/i });
|
||||
expect(addFilterBtn).toBeDisabled();
|
||||
expect(screen.getByPlaceholderText('Enter Name')).toBeInTheDocument();
|
||||
await waitFor(() => userEvent.paste(codeTextBox, codeValue));
|
||||
await waitFor(() => userEvent.type(nameTextBox, nameValue));
|
||||
|
||||
await act(() => {
|
||||
userEvent.paste(codeTextBox, codeValue);
|
||||
userEvent.type(nameTextBox, nameValue);
|
||||
});
|
||||
|
||||
expect(addFilterBtn).toBeEnabled();
|
||||
expect(codeTextBox.value).toEqual(`${codeValue}\n\n`);
|
||||
expect(nameTextBox).toHaveValue(nameValue);
|
||||
|
@ -81,7 +88,7 @@ describe('AddFilter component', () => {
|
|||
const addFilterBtn = screen.getByRole('button', { name: /Add filter/i });
|
||||
expect(addFilterBtn).toBeDisabled();
|
||||
expect(screen.getByPlaceholderText('Enter Name')).toBeInTheDocument();
|
||||
await waitFor(() => userEvent.paste(codeTextBox, code));
|
||||
await act(() => userEvent.paste(codeTextBox, code));
|
||||
expect(addFilterBtn).toBeEnabled();
|
||||
expect(codeTextBox).toHaveValue(`${code}\n\n`);
|
||||
});
|
||||
|
@ -110,13 +117,13 @@ describe('AddFilter component', () => {
|
|||
const nameValue = 'filter name';
|
||||
|
||||
beforeEach(async () => {
|
||||
await waitFor(() =>
|
||||
setupComponent({
|
||||
await act(() => {
|
||||
renderComponent({
|
||||
addFilter: addFilterMock,
|
||||
activeFilterHandler: activeFilterHandlerMock,
|
||||
toggleIsOpen: toggleModelMock,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -127,7 +134,7 @@ describe('AddFilter component', () => {
|
|||
|
||||
describe('OnSubmit conditions with codeValue and nameValue in fields', () => {
|
||||
beforeEach(async () => {
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.paste(
|
||||
screen.getAllByRole('textbox')[0] as HTMLTextAreaElement,
|
||||
codeValue
|
||||
|
@ -142,19 +149,20 @@ describe('AddFilter component', () => {
|
|||
name: /Add filter/i,
|
||||
});
|
||||
expect(addFilterBtn).toBeEnabled();
|
||||
userEvent.click(addFilterBtn);
|
||||
|
||||
await waitFor(() => expect(activeFilterHandlerMock).toHaveBeenCalled());
|
||||
await act(() => userEvent.click(addFilterBtn));
|
||||
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalled();
|
||||
expect(addFilterMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('OnSubmit condition with checkbox on functionality', async () => {
|
||||
await act(() => {
|
||||
userEvent.click(screen.getByRole('checkbox'));
|
||||
|
||||
userEvent.click(screen.getAllByRole('button')[1]);
|
||||
await waitFor(() =>
|
||||
expect(activeFilterHandlerMock).not.toHaveBeenCalled()
|
||||
);
|
||||
});
|
||||
|
||||
expect(activeFilterHandlerMock).not.toHaveBeenCalled();
|
||||
expect(addFilterMock).toHaveBeenCalled();
|
||||
expect(toggleModelMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -169,13 +177,12 @@ describe('AddFilter component', () => {
|
|||
name: /Add filter/i,
|
||||
});
|
||||
|
||||
userEvent.clear(nameTextBox);
|
||||
await act(() => userEvent.clear(nameTextBox));
|
||||
|
||||
expect(nameTextBox).toHaveValue('');
|
||||
|
||||
userEvent.click(addFilterBtn);
|
||||
await waitFor(() =>
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1)
|
||||
);
|
||||
await act(() => userEvent.click(addFilterBtn));
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledWith(
|
||||
{
|
||||
|
@ -189,20 +196,18 @@ describe('AddFilter component', () => {
|
|||
expect(codeTextBox).toHaveValue(``);
|
||||
expect(toggleModelMock).toHaveBeenCalled();
|
||||
|
||||
userEvent.paste(codeTextBox, codeValue);
|
||||
await act(() => userEvent.paste(codeTextBox, codeValue));
|
||||
expect(codeTextBox).toHaveValue(`${codeValue}\n\n`);
|
||||
|
||||
userEvent.click(checkbox);
|
||||
await act(() => userEvent.click(checkbox));
|
||||
expect(addFilterBtn).toBeDisabled();
|
||||
|
||||
userEvent.type(nameTextBox, nameValue);
|
||||
await act(() => userEvent.type(nameTextBox, nameValue));
|
||||
expect(nameTextBox).toHaveValue(nameValue);
|
||||
await waitFor(() => expect(addFilterBtn).toBeEnabled());
|
||||
userEvent.click(addFilterBtn);
|
||||
expect(addFilterBtn).toBeEnabled();
|
||||
await act(() => userEvent.click(addFilterBtn));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1)
|
||||
);
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1);
|
||||
expect(addFilterMock).toHaveBeenCalledWith({
|
||||
name: nameValue,
|
||||
code: codeValue,
|
||||
|
@ -217,22 +222,19 @@ describe('AddFilter component', () => {
|
|||
)[0] as HTMLTextAreaElement;
|
||||
const nameTextBox = screen.getAllByRole('textbox')[1];
|
||||
const addFilterBtn = screen.getByRole('button', { name: /Add filter/i });
|
||||
|
||||
await act(() => {
|
||||
userEvent.clear(nameTextBox);
|
||||
userEvent.clear(codeTextBox);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.paste(codeTextBox, longCodeValue);
|
||||
});
|
||||
|
||||
expect(nameTextBox).toHaveValue('');
|
||||
expect(codeTextBox).toHaveValue(`${longCodeValue}\n\n`);
|
||||
|
||||
userEvent.click(addFilterBtn);
|
||||
await act(() => userEvent.click(addFilterBtn));
|
||||
|
||||
const filterName = `${longCodeValue.slice(0, 16)}...`;
|
||||
|
||||
await waitFor(() => {
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledTimes(1);
|
||||
expect(activeFilterHandlerMock).toHaveBeenCalledWith(
|
||||
{
|
||||
|
@ -242,9 +244,8 @@ describe('AddFilter component', () => {
|
|||
},
|
||||
-1
|
||||
);
|
||||
expect(codeTextBox.value).toEqual('');
|
||||
expect(codeTextBox).toHaveValue('');
|
||||
expect(toggleModelMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import EditFilter, {
|
|||
EditFilterProps,
|
||||
} from 'components/Topics/Topic/Details/Messages/Filters/EditFilter';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen, waitFor, fireEvent, within } from '@testing-library/react';
|
||||
import { screen, fireEvent, within, act } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { FilterEdit } from 'components/Topics/Topic/Details/Messages/Filters/FilterModal';
|
||||
|
||||
|
@ -12,7 +12,7 @@ const editFilter: FilterEdit = {
|
|||
filter: { name: 'name', code: '' },
|
||||
};
|
||||
|
||||
const setupComponent = (props?: Partial<EditFilterProps>) =>
|
||||
const renderComponent = (props?: Partial<EditFilterProps>) =>
|
||||
render(
|
||||
<EditFilter
|
||||
toggleEditModal={jest.fn()}
|
||||
|
@ -24,13 +24,17 @@ const setupComponent = (props?: Partial<EditFilterProps>) =>
|
|||
|
||||
describe('EditFilter component', () => {
|
||||
it('renders component', async () => {
|
||||
await waitFor(() => setupComponent());
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
expect(screen.getByText(/edit saved filter/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('closes editFilter modal', async () => {
|
||||
const toggleEditModal = jest.fn();
|
||||
await waitFor(() => setupComponent({ toggleEditModal }));
|
||||
await act(() => {
|
||||
renderComponent({ toggleEditModal });
|
||||
});
|
||||
userEvent.click(screen.getByRole('button', { name: /Cancel/i }));
|
||||
expect(toggleEditModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
@ -38,19 +42,27 @@ describe('EditFilter component', () => {
|
|||
it('save edited fields and close modal', async () => {
|
||||
const toggleEditModal = jest.fn();
|
||||
const editSavedFilter = jest.fn();
|
||||
await waitFor(() => setupComponent({ toggleEditModal, editSavedFilter }));
|
||||
|
||||
await act(() => {
|
||||
renderComponent({ toggleEditModal, editSavedFilter });
|
||||
});
|
||||
|
||||
const inputs = screen.getAllByRole('textbox');
|
||||
const textAreaElement = inputs[0] as HTMLTextAreaElement;
|
||||
const inputNameElement = inputs[1];
|
||||
await act(() => {
|
||||
userEvent.paste(textAreaElement, 'edited code');
|
||||
userEvent.type(inputNameElement, 'edited name');
|
||||
await waitFor(() => fireEvent.submit(screen.getByRole('form')));
|
||||
fireEvent.submit(screen.getByRole('form'));
|
||||
});
|
||||
expect(toggleEditModal).toHaveBeenCalledTimes(1);
|
||||
expect(editSavedFilter).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('checks input values to match', async () => {
|
||||
await waitFor(() => setupComponent());
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
const inputs = screen.getAllByRole('textbox');
|
||||
const textAreaElement = inputs[0] as HTMLTextAreaElement;
|
||||
const inputNameElement = inputs[1];
|
||||
|
|
|
@ -4,12 +4,12 @@ import FilterModal, {
|
|||
} from 'components/Topics/Topic/Details/Messages/Filters/FilterModal';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { MessageFilters } from 'components/Topics/Topic/Details/Messages/Filters/Filters';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { screen, act } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
const filters: MessageFilters[] = [{ name: 'name', code: 'code' }];
|
||||
|
||||
const setupWrapper = (props?: Partial<FilterModalProps>) =>
|
||||
const renderComponent = (props?: Partial<FilterModalProps>) =>
|
||||
render(
|
||||
<FilterModal
|
||||
toggleIsOpen={jest.fn()}
|
||||
|
@ -23,7 +23,9 @@ const setupWrapper = (props?: Partial<FilterModalProps>) =>
|
|||
);
|
||||
describe('FilterModal component', () => {
|
||||
beforeEach(async () => {
|
||||
await waitFor(() => setupWrapper());
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
});
|
||||
it('renders component with add filter modal', () => {
|
||||
expect(
|
||||
|
|
|
@ -5,7 +5,7 @@ import Filters, {
|
|||
SeekTypeOptions,
|
||||
} from 'components/Topics/Topic/Details/Messages/Filters/Filters';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import { act, screen, within, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import TopicMessagesContext, {
|
||||
ContextProps,
|
||||
|
@ -19,7 +19,7 @@ const defaultContextValue: ContextProps = {
|
|||
changeSeekDirection: jest.fn(),
|
||||
};
|
||||
|
||||
const setupWrapper = (
|
||||
const renderComponent = (
|
||||
props: Partial<FiltersProps> = {},
|
||||
ctx: ContextProps = defaultContextValue
|
||||
) => {
|
||||
|
@ -41,52 +41,58 @@ const setupWrapper = (
|
|||
</TopicMessagesContext.Provider>
|
||||
);
|
||||
};
|
||||
const getSubmit = () => screen.getByText('Submit');
|
||||
|
||||
describe('Filters component', () => {
|
||||
it('shows cancel button while fetching', () => {
|
||||
setupWrapper({ isFetching: true });
|
||||
renderComponent({ isFetching: true });
|
||||
expect(screen.getByText('Cancel')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows submit button while fetching is over', () => {
|
||||
setupWrapper();
|
||||
expect(getSubmit()).toBeInTheDocument();
|
||||
renderComponent();
|
||||
expect(screen.getByText('Submit')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('Input elements', () => {
|
||||
const inputValue = 'Hello World!';
|
||||
|
||||
beforeEach(() => setupWrapper());
|
||||
beforeEach(async () => {
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
});
|
||||
|
||||
it('search input', () => {
|
||||
const SearchInput = screen.getByPlaceholderText('Search');
|
||||
expect(SearchInput).toBeInTheDocument();
|
||||
expect(SearchInput).toHaveValue('');
|
||||
userEvent.type(SearchInput, inputValue);
|
||||
expect(SearchInput).toHaveValue(inputValue);
|
||||
const searchInput = screen.getByPlaceholderText('Search');
|
||||
expect(searchInput).toHaveValue('');
|
||||
userEvent.type(searchInput, inputValue);
|
||||
expect(searchInput).toHaveValue(inputValue);
|
||||
});
|
||||
|
||||
it('offset input', () => {
|
||||
const OffsetInput = screen.getByPlaceholderText('Offset');
|
||||
expect(OffsetInput).toBeInTheDocument();
|
||||
expect(OffsetInput).toHaveValue('');
|
||||
userEvent.type(OffsetInput, inputValue);
|
||||
expect(OffsetInput).toHaveValue(inputValue);
|
||||
const offsetInput = screen.getByPlaceholderText('Offset');
|
||||
expect(offsetInput).toHaveValue('');
|
||||
userEvent.type(offsetInput, inputValue);
|
||||
expect(offsetInput).toHaveValue(inputValue);
|
||||
});
|
||||
|
||||
it('timestamp input', async () => {
|
||||
const seekTypeSelect = screen.getAllByRole('listbox');
|
||||
const option = screen.getAllByRole('option');
|
||||
|
||||
userEvent.click(seekTypeSelect[0]);
|
||||
await act(() => userEvent.click(seekTypeSelect[0]));
|
||||
|
||||
await act(() => {
|
||||
userEvent.selectOptions(seekTypeSelect[0], ['Timestamp']);
|
||||
});
|
||||
|
||||
expect(option[0]).toHaveTextContent('Timestamp');
|
||||
const timestampInput = screen.getByPlaceholderText('Select timestamp');
|
||||
expect(timestampInput).toBeInTheDocument();
|
||||
expect(timestampInput).toHaveValue('');
|
||||
userEvent.type(timestampInput, inputValue);
|
||||
await waitFor(() => expect(timestampInput).toHaveValue(inputValue));
|
||||
|
||||
await waitFor(() => userEvent.type(timestampInput, inputValue));
|
||||
|
||||
expect(timestampInput).toHaveValue(inputValue);
|
||||
expect(screen.getByText('Submit')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -101,7 +107,7 @@ describe('Filters component', () => {
|
|||
const mockTypeOptionSelectLabel = selectTypeOptionValue.label;
|
||||
|
||||
beforeEach(() => {
|
||||
setupWrapper();
|
||||
renderComponent();
|
||||
seekTypeSelects = screen.getAllByRole('listbox');
|
||||
options = screen.getAllByRole('option');
|
||||
});
|
||||
|
@ -124,16 +130,16 @@ describe('Filters component', () => {
|
|||
});
|
||||
|
||||
it('stop loading when live mode is active', () => {
|
||||
setupWrapper();
|
||||
renderComponent();
|
||||
userEvent.click(screen.getByText('Stop loading'));
|
||||
const option = screen.getAllByRole('option');
|
||||
expect(option[1]).toHaveTextContent('Oldest First');
|
||||
expect(getSubmit()).toBeInTheDocument();
|
||||
expect(screen.getByText('Submit')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders addFilter modal', async () => {
|
||||
setupWrapper();
|
||||
await waitFor(() =>
|
||||
renderComponent();
|
||||
await act(() =>
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: /add filters/i,
|
||||
|
@ -145,9 +151,9 @@ describe('Filters component', () => {
|
|||
|
||||
describe('when there is active smart filter', () => {
|
||||
beforeEach(async () => {
|
||||
setupWrapper();
|
||||
renderComponent();
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: /add filters/i,
|
||||
|
@ -165,7 +171,7 @@ describe('Filters component', () => {
|
|||
|
||||
const textAreaElement = textBoxElements[0] as HTMLTextAreaElement;
|
||||
const inputNameElement = textBoxElements[1];
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.paste(textAreaElement, filterName);
|
||||
userEvent.type(inputNameElement, filterCode);
|
||||
});
|
||||
|
@ -173,7 +179,7 @@ describe('Filters component', () => {
|
|||
expect(textAreaElement.value).toEqual(`${filterName}\n\n`);
|
||||
expect(inputNameElement).toHaveValue(filterCode);
|
||||
|
||||
await waitFor(() =>
|
||||
await act(() =>
|
||||
userEvent.click(
|
||||
within(messageFilterModal).getByRole('button', {
|
||||
name: /add filter/i,
|
||||
|
@ -191,7 +197,7 @@ describe('Filters component', () => {
|
|||
const deleteIcon = within(smartFilterElement).getByTestId(
|
||||
'activeSmartFilterCloseIcon'
|
||||
);
|
||||
await waitFor(() => userEvent.click(deleteIcon));
|
||||
await act(() => userEvent.click(deleteIcon));
|
||||
|
||||
const anotherSmartFilterElement =
|
||||
screen.queryByTestId('activeSmartFilter');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import TopicMessagesContext from 'components/contexts/TopicMessagesContext';
|
||||
import { SeekDirection } from 'generated-sources';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import FiltersContainer from './Filters/FiltersContainer';
|
||||
import MessagesTable from './MessagesTable';
|
||||
|
|
|
@ -6,7 +6,7 @@ import styled from 'styled-components';
|
|||
import { compact, concat, groupBy, map, maxBy, minBy } from 'lodash';
|
||||
import React, { useContext } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import {
|
||||
getTopicMessges,
|
||||
getIsTopicMessagesFetching,
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { screen } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import MessagesTable from 'components/Topics/Topic/Details/Messages/MessagesTable';
|
||||
import { Router } from 'react-router';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createMemoryHistory, MemoryHistory } from 'history';
|
||||
import { SeekDirection, SeekType, TopicMessage } from 'generated-sources';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import DangerZone, {
|
||||
Props,
|
||||
} from 'components/Topics/Topic/Edit/DangerZone/DangerZone';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import { act, screen, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import {
|
||||
|
@ -13,8 +13,8 @@ import {
|
|||
const defaultPartitions = 3;
|
||||
const defaultReplicationFactor = 3;
|
||||
|
||||
const renderComponent = (props?: Partial<Props>) => {
|
||||
return render(
|
||||
const renderComponent = (props?: Partial<Props>) =>
|
||||
render(
|
||||
<DangerZone
|
||||
clusterName={clusterName}
|
||||
topicName={topicName}
|
||||
|
@ -27,7 +27,6 @@ const renderComponent = (props?: Partial<Props>) => {
|
|||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const clickOnDialogSubmitButton = () => {
|
||||
userEvent.click(
|
||||
|
@ -40,18 +39,14 @@ const clickOnDialogSubmitButton = () => {
|
|||
const checkDialogThenPressCancel = async () => {
|
||||
const dialog = screen.getByRole('dialog');
|
||||
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(within(dialog).getByText(/cancel/i));
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
|
||||
);
|
||||
};
|
||||
|
||||
describe('DangerZone', () => {
|
||||
it('renders the component', () => {
|
||||
it('renders the component', async () => {
|
||||
renderComponent();
|
||||
|
||||
const numberOfPartitionsEditForm = screen.getByRole('form', {
|
||||
|
@ -139,27 +134,23 @@ describe('DangerZone', () => {
|
|||
const partitionInput = screen.getByPlaceholderText('Number of partitions');
|
||||
const partitionInputSubmitBtn = screen.getAllByText(/submit/i)[0];
|
||||
const value = (defaultPartitions - 4).toString();
|
||||
|
||||
expect(partitionInputSubmitBtn).toBeDisabled();
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.clear(partitionInput);
|
||||
userEvent.type(partitionInput, value);
|
||||
});
|
||||
|
||||
expect(partitionInput).toHaveValue(+value);
|
||||
expect(partitionInputSubmitBtn).toBeEnabled();
|
||||
await act(() => {
|
||||
userEvent.click(partitionInputSubmitBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
});
|
||||
expect(
|
||||
screen.getByText(/You can only increase the number of partitions!/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.clear(partitionInput);
|
||||
});
|
||||
expect(screen.getByText(/are required/i)).toBeInTheDocument();
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText(/are required/i)).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('should view the validation error when Replication Facto value is lower than the default passed or empty', async () => {
|
||||
|
@ -168,31 +159,31 @@ describe('DangerZone', () => {
|
|||
screen.getByPlaceholderText('Replication Factor');
|
||||
const replicatorFactorInputSubmitBtn = screen.getAllByText(/submit/i)[1];
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.clear(replicatorFactorInput);
|
||||
});
|
||||
await waitFor(() => userEvent.clear(replicatorFactorInput));
|
||||
|
||||
expect(replicatorFactorInputSubmitBtn).toBeEnabled();
|
||||
await waitFor(() => {
|
||||
userEvent.click(replicatorFactorInputSubmitBtn);
|
||||
});
|
||||
|
||||
expect(screen.getByText(/are required/i)).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => {
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText(/are required/i)).toBeInTheDocument()
|
||||
);
|
||||
userEvent.type(replicatorFactorInput, '1');
|
||||
});
|
||||
expect(screen.queryByText(/are required/i)).not.toBeInTheDocument();
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByText(/are required/i)).not.toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('should close any popup if the partitionsCount is Increased ', () => {
|
||||
it('should close any popup if the partitionsCount is Increased ', async () => {
|
||||
renderComponent({ partitionsCountIncreased: true });
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('should close any popup if the replicationFactor is Updated', () => {
|
||||
it('should close any popup if the replicationFactor is Updated', async () => {
|
||||
renderComponent({ replicationFactorUpdated: true });
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('should already opened Confirmation popup if partitionsCount is Increased', async () => {
|
||||
|
@ -254,14 +245,12 @@ describe('DangerZone', () => {
|
|||
|
||||
it('should close the partitions dialog if he cancel button is pressed', async () => {
|
||||
renderComponent();
|
||||
|
||||
const partitionInput = screen.getByPlaceholderText('Number of partitions');
|
||||
const partitionInputSubmitBtn = screen.getAllByText(/submit/i)[0];
|
||||
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.type(partitionInput, '5');
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(partitionInputSubmitBtn);
|
||||
});
|
||||
|
||||
|
@ -274,11 +263,8 @@ describe('DangerZone', () => {
|
|||
screen.getByPlaceholderText('Replication Factor');
|
||||
const replicatorFactorInputSubmitBtn = screen.getAllByText(/submit/i)[1];
|
||||
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.type(replicatorFactorInput, '5');
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(replicatorFactorInputSubmitBtn);
|
||||
});
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
import { useForm, FormProvider } from 'react-hook-form';
|
||||
import TopicForm from 'components/Topics/shared/Form/TopicForm';
|
||||
import { clusterTopicPath } from 'lib/paths';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { topicFormValidationSchema } from 'lib/yupExtended';
|
||||
import { TOPIC_CUSTOM_PARAMS_PREFIX, TOPIC_CUSTOM_PARAMS } from 'lib/constants';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import Edit, { DEFAULTS, Props } from 'components/Topics/Topic/Edit/Edit';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { Router } from 'react-router-dom';
|
||||
|
@ -109,7 +109,7 @@ describe('Edit Component', () => {
|
|||
const btn = screen.getAllByText(/submit/i)[0];
|
||||
expect(btn).toBeEnabled();
|
||||
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.type(
|
||||
screen.getByPlaceholderText('Min In Sync Replicas'),
|
||||
'1'
|
||||
|
@ -117,10 +117,8 @@ describe('Edit Component', () => {
|
|||
userEvent.click(btn);
|
||||
});
|
||||
expect(updateTopicMock).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => {
|
||||
expect(mocked.push).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check the submit functionality when topic updated is true', async () => {
|
||||
const updateTopicMock = jest.fn();
|
||||
|
@ -135,7 +133,7 @@ describe('Edit Component', () => {
|
|||
|
||||
const btn = screen.getAllByText(/submit/i)[0];
|
||||
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.type(
|
||||
screen.getByPlaceholderText('Min In Sync Replicas'),
|
||||
'1'
|
||||
|
@ -143,7 +141,6 @@ describe('Edit Component', () => {
|
|||
userEvent.click(btn);
|
||||
});
|
||||
expect(updateTopicMock).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => {
|
||||
expect(mocked.push).toHaveBeenCalled();
|
||||
expect(mocked.location.pathname).toBe(
|
||||
clusterTopicPath(clusterName, topicName)
|
||||
|
@ -151,4 +148,3 @@ describe('Edit Component', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@ import Editor from 'components/common/Editor/Editor';
|
|||
import PageLoader from 'components/common/PageLoader/PageLoader';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useHistory, useParams } from 'react-router';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { clusterTopicMessagesPath } from 'lib/paths';
|
||||
import jsf from 'json-schema-faker';
|
||||
import { fetchTopicMessageSchema, messagesApiClient } from 'redux/actions';
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
import React from 'react';
|
||||
import SendMessage from 'components/Topics/Topic/SendMessage/SendMessage';
|
||||
import {
|
||||
screen,
|
||||
waitFor,
|
||||
waitForElementToBeRemoved,
|
||||
} from '@testing-library/react';
|
||||
import { act, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { Route, Router } from 'react-router';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import {
|
||||
clusterTopicMessagesPath,
|
||||
clusterTopicSendMessagePath,
|
||||
|
@ -43,12 +39,15 @@ const clusterName = 'testCluster';
|
|||
const topicName = externalTopicPayload.name;
|
||||
const history = createMemoryHistory();
|
||||
|
||||
const renderComponent = () => {
|
||||
const renderComponent = async () => {
|
||||
history.push(clusterTopicSendMessagePath(clusterName, topicName));
|
||||
await act(() => {
|
||||
render(
|
||||
<>
|
||||
<Router history={history}>
|
||||
<Route path={clusterTopicSendMessagePath(':clusterName', ':topicName')}>
|
||||
<Route
|
||||
path={clusterTopicSendMessagePath(':clusterName', ':topicName')}
|
||||
>
|
||||
<SendMessage />
|
||||
</Route>
|
||||
</Router>
|
||||
|
@ -58,16 +57,17 @@ const renderComponent = () => {
|
|||
</>,
|
||||
{ store }
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const renderAndSubmitData = async (error: string[] = []) => {
|
||||
renderComponent();
|
||||
await waitForElementToBeRemoved(() => screen.getByRole('progressbar'));
|
||||
|
||||
await renderComponent();
|
||||
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
|
||||
await act(() => {
|
||||
userEvent.selectOptions(screen.getByLabelText('Partition'), '0');
|
||||
const sendBtn = await screen.findByText('Send');
|
||||
(validateMessage as Mock).mockImplementation(() => error);
|
||||
userEvent.click(sendBtn);
|
||||
userEvent.click(screen.getByText('Send'));
|
||||
});
|
||||
};
|
||||
|
||||
describe('SendMessage', () => {
|
||||
|
@ -85,12 +85,14 @@ describe('SendMessage', () => {
|
|||
fetchMock.reset();
|
||||
});
|
||||
|
||||
it('fetches schema on first render', () => {
|
||||
it('fetches schema on first render', async () => {
|
||||
const fetchTopicMessageSchemaMock = fetchMock.getOnce(
|
||||
`/api/clusters/${clusterName}/topics/${topicName}/messages/schema`,
|
||||
testSchema
|
||||
);
|
||||
await act(() => {
|
||||
renderComponent();
|
||||
});
|
||||
expect(fetchTopicMessageSchemaMock.called()).toBeTruthy();
|
||||
});
|
||||
|
||||
|
@ -107,9 +109,7 @@ describe('SendMessage', () => {
|
|||
it('calls sendTopicMessage on submit', async () => {
|
||||
const sendTopicMessageMock = fetchMock.postOnce(url, 200);
|
||||
await renderAndSubmitData();
|
||||
await waitFor(() =>
|
||||
expect(sendTopicMessageMock.called(url)).toBeTruthy()
|
||||
);
|
||||
expect(sendTopicMessageMock.called(url)).toBeTruthy();
|
||||
expect(history.location.pathname).toEqual(
|
||||
clusterTopicMessagesPath(clusterName, topicName)
|
||||
);
|
||||
|
@ -120,12 +120,8 @@ describe('SendMessage', () => {
|
|||
throws: 'Error',
|
||||
});
|
||||
await renderAndSubmitData();
|
||||
await waitFor(() => {
|
||||
expect(sendTopicMessageMock.called(url)).toBeTruthy();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('alert')).toBeInTheDocument();
|
||||
});
|
||||
expect(history.location.pathname).toEqual(
|
||||
clusterTopicMessagesPath(clusterName, topicName)
|
||||
);
|
||||
|
@ -134,7 +130,7 @@ describe('SendMessage', () => {
|
|||
it('should check and view validation error message when is not valid', async () => {
|
||||
const sendTopicMessageMock = fetchMock.postOnce(url, 200);
|
||||
await renderAndSubmitData(['error']);
|
||||
await waitFor(() => expect(sendTopicMessageMock.called(url)).toBeFalsy());
|
||||
expect(sendTopicMessageMock.called(url)).toBeFalsy();
|
||||
expect(history.location.pathname).not.toEqual(
|
||||
clusterTopicMessagesPath(clusterName, topicName)
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { act, screen, within } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import CustomParamsField, {
|
||||
Props,
|
||||
|
@ -16,8 +16,8 @@ const field = { name: 'name', value: 'value', id: 'id' };
|
|||
const SPACE_KEY = ' ';
|
||||
|
||||
const selectOption = async (listbox: HTMLElement, option: string) => {
|
||||
await waitFor(() => userEvent.click(listbox));
|
||||
await waitFor(() => userEvent.click(screen.getByText(option)));
|
||||
await act(() => userEvent.click(listbox));
|
||||
await act(() => userEvent.click(screen.getByText(option)));
|
||||
};
|
||||
|
||||
describe('CustomParamsField', () => {
|
||||
|
@ -25,7 +25,7 @@ describe('CustomParamsField', () => {
|
|||
const setExistingFields = jest.fn();
|
||||
|
||||
const setupComponent = (props: Props) => {
|
||||
const Wrapper: React.FC = ({ children }) => {
|
||||
const Wrapper: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const methods = useForm();
|
||||
return <FormProvider {...methods}>{children}</FormProvider>;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { act, screen, within } from '@testing-library/react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import CustomParams, {
|
||||
CustomParamsProps,
|
||||
|
@ -11,10 +11,10 @@ import { TOPIC_CUSTOM_PARAMS } from 'lib/constants';
|
|||
import { defaultValues } from './fixtures';
|
||||
|
||||
const selectOption = async (listbox: HTMLElement, option: string) => {
|
||||
await waitFor(() => {
|
||||
await act(() => {
|
||||
userEvent.click(listbox);
|
||||
userEvent.click(screen.getByText(option));
|
||||
});
|
||||
userEvent.click(screen.getByText(option));
|
||||
};
|
||||
|
||||
const expectOptionIsSelected = (listbox: HTMLElement, option: string) => {
|
||||
|
@ -28,7 +28,7 @@ const expectOptionAvailability = async (
|
|||
option: string,
|
||||
disabled: boolean
|
||||
) => {
|
||||
await waitFor(() => userEvent.click(listbox));
|
||||
await act(() => userEvent.click(listbox));
|
||||
const selectedOptions = within(listbox).getAllByText(option).reverse();
|
||||
// its either two or one nodes, we only need last one
|
||||
const selectedOption = selectedOptions[0];
|
||||
|
@ -43,11 +43,11 @@ const expectOptionAvailability = async (
|
|||
'cursor',
|
||||
disabled ? 'not-allowed' : 'pointer'
|
||||
);
|
||||
await waitFor(() => userEvent.click(listbox));
|
||||
await act(() => userEvent.click(listbox));
|
||||
};
|
||||
|
||||
const renderComponent = (props: CustomParamsProps, defaults = {}) => {
|
||||
const Wrapper: React.FC = ({ children }) => {
|
||||
const Wrapper: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const methods = useForm({ defaultValues: defaults });
|
||||
return <FormProvider {...methods}>{children}</FormProvider>;
|
||||
};
|
||||
|
@ -81,10 +81,11 @@ describe('CustomParams', () => {
|
|||
|
||||
describe('works with user inputs correctly', () => {
|
||||
let button: HTMLButtonElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
renderComponent({ isSubmitting: false });
|
||||
button = screen.getByRole('button');
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
});
|
||||
|
||||
it('button click creates custom param fieldset', async () => {
|
||||
|
@ -119,8 +120,8 @@ describe('CustomParams', () => {
|
|||
});
|
||||
|
||||
it('multiple button clicks create multiple fieldsets', async () => {
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
|
||||
const listboxes = screen.getAllByRole('listbox');
|
||||
expect(listboxes.length).toBe(3);
|
||||
|
@ -130,7 +131,7 @@ describe('CustomParams', () => {
|
|||
});
|
||||
|
||||
it("can't select already selected option", async () => {
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
|
||||
const listboxes = screen.getAllByRole('listbox');
|
||||
|
||||
|
@ -143,8 +144,8 @@ describe('CustomParams', () => {
|
|||
});
|
||||
|
||||
it('when fieldset with selected custom property type is deleted disabled options update correctly', async () => {
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await waitFor(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
await act(() => userEvent.click(button));
|
||||
|
||||
const listboxes = screen.getAllByRole('listbox');
|
||||
|
||||
|
@ -171,7 +172,7 @@ describe('CustomParams', () => {
|
|||
const deleteSecondFieldsetButton = screen.getByTitle(
|
||||
'Delete customParam field 1'
|
||||
);
|
||||
await waitFor(() => userEvent.click(deleteSecondFieldsetButton));
|
||||
await act(() => userEvent.click(deleteSecondFieldsetButton));
|
||||
expect(secondListbox).not.toBeInTheDocument();
|
||||
|
||||
await expectOptionAvailability(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen } from '@testing-library/react';
|
||||
import TimeToRetainBtn, {
|
||||
|
@ -14,7 +14,7 @@ describe('TimeToRetainBtn', () => {
|
|||
text: 'defaultPropsText',
|
||||
value: 0,
|
||||
};
|
||||
const Wrapper: React.FC = ({ children }) => {
|
||||
const Wrapper: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const methods = useForm();
|
||||
return <FormProvider {...methods}>{children}</FormProvider>;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen } from '@testing-library/react';
|
||||
import TimeToRetainBtns, {
|
||||
|
@ -11,7 +11,7 @@ describe('TimeToRetainBtns', () => {
|
|||
name: 'defaultPropsTestingName',
|
||||
value: 'defaultPropsValue',
|
||||
};
|
||||
const Wrapper: React.FC = ({ children }) => {
|
||||
const Wrapper: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const methods = useForm();
|
||||
return <FormProvider {...methods}>{children}</FormProvider>;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen } from '@testing-library/dom';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
|
@ -9,7 +9,7 @@ const isSubmitting = false;
|
|||
const onSubmit = jest.fn();
|
||||
|
||||
const renderComponent = (props: Props = { isSubmitting, onSubmit }) => {
|
||||
const Wrapper: React.FC = ({ children }) => {
|
||||
const Wrapper: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const methods = useForm();
|
||||
return <FormProvider {...methods}>{children}</FormProvider>;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { screen, within, waitFor } from '@testing-library/react';
|
||||
import { screen, within, act } from '@testing-library/react';
|
||||
import App from 'components/App';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { clustersPayload } from 'redux/reducers/clusters/__test__/fixtures';
|
||||
|
@ -43,10 +43,14 @@ describe('App', () => {
|
|||
describe('with clusters list fetched', () => {
|
||||
it('shows Cluster list', async () => {
|
||||
const mock = fetchMock.getOnce('/api/clusters', clustersPayload);
|
||||
await act(() => {
|
||||
render(<App />, {
|
||||
pathname: '/',
|
||||
});
|
||||
await waitFor(() => expect(mock.called()).toBeTruthy());
|
||||
});
|
||||
|
||||
expect(mock.called()).toBeTruthy();
|
||||
|
||||
const menuContainer = screen.getByLabelText('Sidebar Menu');
|
||||
expect(menuContainer).toBeInTheDocument();
|
||||
expect(within(menuContainer).getByText('Dashboard')).toBeInTheDocument();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { PropsWithChildren, useState } from 'react';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
|
||||
import { BreadcrumbContext, BreadcrumbEntry } from './Breadcrumb.context';
|
||||
|
@ -13,7 +13,9 @@ const mapLocationToPath = (
|
|||
: item
|
||||
);
|
||||
|
||||
export const BreadcrumbProvider: React.FC = ({ children }) => {
|
||||
export const BreadcrumbProvider: React.FC<PropsWithChildren<unknown>> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [state, setState] = useState<BreadcrumbEntry>({
|
||||
link: '',
|
||||
path: [],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { Button } from 'components/common/Button/Button';
|
||||
|
||||
import { ConfirmationModalWrapper } from './ConfirmationModal.styled';
|
||||
|
@ -12,7 +12,9 @@ export interface ConfirmationModalProps {
|
|||
submitBtnText?: string;
|
||||
}
|
||||
|
||||
const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
|
||||
const ConfirmationModal: React.FC<
|
||||
PropsWithChildren<ConfirmationModalProps>
|
||||
> = ({
|
||||
isOpen,
|
||||
children,
|
||||
title = 'Confirm the action',
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import useOutsideClickRef from '@rooks/use-outside-click-ref';
|
||||
import cx from 'classnames';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, {
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import * as S from './Dropdown.styled';
|
||||
|
||||
|
@ -10,7 +15,12 @@ export interface DropdownProps {
|
|||
up?: boolean;
|
||||
}
|
||||
|
||||
const Dropdown: React.FC<DropdownProps> = ({ label, right, up, children }) => {
|
||||
const Dropdown: React.FC<PropsWithChildren<DropdownProps>> = ({
|
||||
label,
|
||||
right,
|
||||
up,
|
||||
children,
|
||||
}) => {
|
||||
const [active, setActive] = useState<boolean>(false);
|
||||
const [wrapperRef] = useOutsideClickRef(() => setActive(false));
|
||||
const onClick = useCallback(() => setActive(!active), [active]);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
|
||||
import * as S from './Dropdown.styled';
|
||||
|
||||
|
@ -7,7 +7,7 @@ export interface DropdownItemProps {
|
|||
danger?: boolean;
|
||||
}
|
||||
|
||||
const DropdownItem: React.FC<DropdownItemProps> = ({
|
||||
const DropdownItem: React.FC<PropsWithChildren<DropdownItemProps>> = ({
|
||||
onClick,
|
||||
danger,
|
||||
children,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { AlertType } from 'redux/interfaces';
|
||||
|
||||
import * as S from './Metrics.styled';
|
||||
|
@ -11,15 +11,14 @@ export interface Props {
|
|||
alertType?: AlertType;
|
||||
}
|
||||
|
||||
const Indicator: React.FC<Props> = ({
|
||||
const Indicator: React.FC<PropsWithChildren<Props>> = ({
|
||||
label,
|
||||
title,
|
||||
fetching,
|
||||
isAlert,
|
||||
alertType = 'error',
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
}) => (
|
||||
<S.IndicatorWrapper>
|
||||
<div title={title}>
|
||||
<S.IndicatorTitle>
|
||||
|
@ -36,6 +35,5 @@ const Indicator: React.FC<Props> = ({
|
|||
</div>
|
||||
</S.IndicatorWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Indicator;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
|
||||
import * as S from './Metrics.styled';
|
||||
|
||||
|
@ -6,13 +6,11 @@ interface Props {
|
|||
title?: string;
|
||||
}
|
||||
|
||||
const Section: React.FC<Props> = ({ title, children }) => {
|
||||
return (
|
||||
const Section: React.FC<PropsWithChildren<Props>> = ({ title, children }) => (
|
||||
<div>
|
||||
{title && <S.SectionTitle>{title}</S.SectionTitle>}
|
||||
<S.IndicatorsWrapper>{children}</S.IndicatorsWrapper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Section;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import styled from 'styled-components';
|
||||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import Heading from 'components/common/heading/Heading.styled';
|
||||
|
||||
interface Props {
|
||||
|
@ -7,7 +7,11 @@ interface Props {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
const PageHeading: React.FC<Props> = ({ text, className, children }) => {
|
||||
const PageHeading: React.FC<PropsWithChildren<Props>> = ({
|
||||
text,
|
||||
className,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<div className={className}>
|
||||
<Heading>{text}</Heading>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { StaticRouter } from 'react-router';
|
||||
import { StaticRouter } from 'react-router-dom';
|
||||
import Pagination, {
|
||||
PaginationProps,
|
||||
} from 'components/common/Pagination/Pagination';
|
||||
|
|
|
@ -67,9 +67,7 @@ export const TableRow = <T, TId extends IdType, OT = never>({
|
|||
const Cell = cell as React.FC<TableCellProps<T, TId, OT>> | undefined;
|
||||
const TdComponent = customTd || Td;
|
||||
|
||||
return (
|
||||
<TdComponent maxWidth={maxWidth}>
|
||||
{Cell ? (
|
||||
const content = Cell ? (
|
||||
<Cell
|
||||
tableState={tableState}
|
||||
hovered={hovered}
|
||||
|
@ -78,7 +76,11 @@ export const TableRow = <T, TId extends IdType, OT = never>({
|
|||
/>
|
||||
) : (
|
||||
field && propertyLookup(field, dataItem)
|
||||
)}
|
||||
);
|
||||
|
||||
return (
|
||||
<TdComponent maxWidth={maxWidth}>
|
||||
{content as React.ReactNode}
|
||||
</TdComponent>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable jsx-a11y/anchor-is-valid */
|
||||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface TabsProps {
|
||||
|
@ -8,7 +8,7 @@ interface TabsProps {
|
|||
onChange?(index: number): void;
|
||||
}
|
||||
|
||||
const Tabs: React.FC<TabsProps> = ({
|
||||
const Tabs: React.FC<PropsWithChildren<TabsProps>> = ({
|
||||
tabs,
|
||||
defaultSelectedIndex = 0,
|
||||
onChange,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
||||
|
@ -13,7 +13,10 @@ const HeadingBase = styled.h1<HeadingBaseProps>`
|
|||
export interface Props {
|
||||
level?: HeadingLevel;
|
||||
}
|
||||
const Heading: React.FC<Props> = ({ level = 1, ...rest }) => {
|
||||
const Heading: React.FC<PropsWithChildren<Props>> = ({
|
||||
level = 1,
|
||||
...rest
|
||||
}) => {
|
||||
return <HeadingBase as={`h${level}`} $level={level} {...rest} />;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { SortOrder, TopicColumnsToSort } from 'generated-sources';
|
||||
import * as S from 'components/common/table/TableHeaderCell/TableHeaderCell.styled';
|
||||
|
||||
|
@ -12,7 +12,9 @@ export interface TableHeaderCellProps {
|
|||
handleOrderBy?: (orderBy: TopicColumnsToSort | null) => void;
|
||||
}
|
||||
|
||||
const TableHeaderCell: React.FC<TableHeaderCellProps> = (props) => {
|
||||
const TableHeaderCell: React.FC<PropsWithChildren<TableHeaderCellProps>> = (
|
||||
props
|
||||
) => {
|
||||
const {
|
||||
title,
|
||||
previewText,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import * as serviceWorker from 'serviceWorker';
|
||||
|
@ -8,13 +8,16 @@ import { store } from 'redux/store';
|
|||
import 'theme/index.scss';
|
||||
import 'lib/constants';
|
||||
|
||||
ReactDOM.render(
|
||||
const container =
|
||||
document.getElementById('root') || document.createElement('div');
|
||||
const root = createRoot(container);
|
||||
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter basename={window.basePath || '/'}>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</Provider>,
|
||||
document.getElementById('root')
|
||||
</Provider>
|
||||
);
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import useModal from 'lib/hooks/useModal';
|
||||
|
||||
describe('useModal CustomHook', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useLocation } from 'react-router';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const usePagination = () => {
|
||||
const { search, pathname } = useLocation();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
|
||||
const SEARCH_QUERY_ARG = 'q';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ReactElement } from 'react';
|
||||
import React, { PropsWithChildren, ReactElement } from 'react';
|
||||
import { StaticRouter } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
|
@ -40,7 +40,9 @@ const customRender = (
|
|||
}: CustomRenderOptions = {}
|
||||
) => {
|
||||
// overrides @testing-library/react render.
|
||||
const AllTheProviders: React.FC = ({ children }) => {
|
||||
const AllTheProviders: React.FC<PropsWithChildren<unknown>> = ({
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Provider store={store}>
|
||||
|
|
Loading…
Add table
Reference in a new issue