chore(shared components): Migrate enzyme to RTL (#26258)
This commit is contained in:
parent
8e2f81816f
commit
1a1548da3b
|
|
@ -16,10 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { isValidElement } from 'react';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import { fireEvent, render } from 'spec/helpers/testing-library';
|
||||
import Button from '.';
|
||||
import {
|
||||
ButtonGallery,
|
||||
|
|
@ -27,36 +24,27 @@ import {
|
|||
STYLES as buttonStyles,
|
||||
} from './Button.stories';
|
||||
|
||||
describe('Button', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
// test the basic component
|
||||
it('renders the base component', () => {
|
||||
expect(isValidElement(<Button />)).toBe(true);
|
||||
});
|
||||
|
||||
it('works with an onClick handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(<Button onClick={mockAction} />);
|
||||
wrapper.find('Button').first().simulate('click');
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not handle onClicks when disabled', () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(<Button onClick={mockAction} disabled />);
|
||||
wrapper.find('Button').first().simulate('click');
|
||||
expect(mockAction).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
// test stories from the storybook!
|
||||
it('All the sorybook gallery variants mount', () => {
|
||||
wrapper = mount(<ButtonGallery />);
|
||||
|
||||
const permutationCount =
|
||||
Object.values(buttonStyles.options).filter(o => o).length *
|
||||
Object.values(buttonSizes.options).length;
|
||||
|
||||
expect(wrapper.find(Button).length).toEqual(permutationCount);
|
||||
});
|
||||
test('works with an onClick handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
const { getByRole } = render(<Button onClick={mockAction} />);
|
||||
fireEvent.click(getByRole('button'));
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('does not handle onClicks when disabled', () => {
|
||||
const mockAction = jest.fn();
|
||||
const { getByRole } = render(<Button onClick={mockAction} disabled />);
|
||||
fireEvent.click(getByRole('button'));
|
||||
expect(mockAction).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
// test stories from the storybook!
|
||||
test('All the sorybook gallery variants mount', () => {
|
||||
const { getAllByRole } = render(<ButtonGallery />);
|
||||
|
||||
const permutationCount =
|
||||
Object.values(buttonStyles.options).filter(o => o).length *
|
||||
Object.values(buttonSizes.options).length;
|
||||
|
||||
expect(getAllByRole('button')).toHaveLength(permutationCount);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,11 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import { SuperChart } from '@superset-ui/core';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
|
||||
import ChartRenderer from 'src/components/Chart/ChartRenderer';
|
||||
|
||||
jest.mock('@superset-ui/core', () => ({
|
||||
...jest.requireActual('@superset-ui/core'),
|
||||
SuperChart: ({ formData }) => (
|
||||
<div data-test="mock-super-chart">{JSON.stringify(formData)}</div>
|
||||
),
|
||||
}));
|
||||
|
||||
jest.mock(
|
||||
'src/components/Chart/ChartContextMenu/ChartContextMenu',
|
||||
() => () => <div data-test="mock-chart-context-menu" />,
|
||||
);
|
||||
|
||||
const requiredProps = {
|
||||
chartId: 1,
|
||||
datasource: {},
|
||||
|
|
@ -31,18 +42,18 @@ const requiredProps = {
|
|||
vizType: 'table',
|
||||
};
|
||||
|
||||
describe('ChartRenderer', () => {
|
||||
it('should render SuperChart', () => {
|
||||
const wrapper = shallow(
|
||||
<ChartRenderer {...requiredProps} chartIsStale={false} />,
|
||||
);
|
||||
expect(wrapper.find(SuperChart)).toExist();
|
||||
});
|
||||
|
||||
it('should use latestQueryFormData instead of formData when chartIsStale is true', () => {
|
||||
const wrapper = shallow(<ChartRenderer {...requiredProps} chartIsStale />);
|
||||
expect(wrapper.find(SuperChart).prop('formData')).toEqual({
|
||||
testControl: 'bar',
|
||||
});
|
||||
});
|
||||
test('should render SuperChart', () => {
|
||||
const { getByTestId } = render(
|
||||
<ChartRenderer {...requiredProps} chartIsStale={false} />,
|
||||
);
|
||||
expect(getByTestId('mock-super-chart')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should use latestQueryFormData instead of formData when chartIsStale is true', () => {
|
||||
const { getByTestId } = render(
|
||||
<ChartRenderer {...requiredProps} chartIsStale />,
|
||||
);
|
||||
expect(getByTestId('mock-super-chart')).toHaveTextContent(
|
||||
JSON.stringify({ testControl: 'bar' }),
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,62 +16,46 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { fireEvent, render } from 'spec/helpers/testing-library';
|
||||
|
||||
import { isValidElement } from 'react';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import {
|
||||
styledMount as mount,
|
||||
styledShallow as shallow,
|
||||
} from 'spec/helpers/theming';
|
||||
import Checkbox from 'src/components/Checkbox';
|
||||
|
||||
import Checkbox, {
|
||||
CheckboxChecked,
|
||||
CheckboxUnchecked,
|
||||
} from 'src/components/Checkbox';
|
||||
jest.mock('src/components/Checkbox/CheckboxIcons', () => ({
|
||||
CheckboxChecked: () => <div data-test="mock-CheckboxChecked" />,
|
||||
CheckboxUnchecked: () => <div data-test="mock-CheckboxUnchecked" />,
|
||||
}));
|
||||
|
||||
describe('Checkbox', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
it('renders the base component', () => {
|
||||
expect(
|
||||
isValidElement(
|
||||
<Checkbox style={{}} checked={false} onChange={() => true} />,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
describe('when unchecked', () => {
|
||||
it('renders the unchecked component', () => {
|
||||
const shallowWrapper = shallow(
|
||||
<Checkbox style={{}} checked={false} onChange={() => true} />,
|
||||
);
|
||||
expect(shallowWrapper.dive().find(CheckboxUnchecked)).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when checked', () => {
|
||||
it('renders the checked component', () => {
|
||||
const shallowWrapper = shallow(
|
||||
<Checkbox style={{}} checked onChange={() => true} />,
|
||||
);
|
||||
expect(shallowWrapper.dive().find(CheckboxChecked)).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
it('works with an onChange handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(
|
||||
<Checkbox style={{}} checked={false} onChange={mockAction} />,
|
||||
describe('when unchecked', () => {
|
||||
test('renders the unchecked component', () => {
|
||||
const { getByTestId } = render(
|
||||
<Checkbox style={{}} checked={false} onChange={() => true} />,
|
||||
);
|
||||
wrapper.find('Checkbox').first().simulate('click');
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders custom Checkbox styles without melting', () => {
|
||||
wrapper = mount(
|
||||
<Checkbox onChange={() => true} checked={false} style={{ opacity: 1 }} />,
|
||||
);
|
||||
expect(wrapper.find('Checkbox')).toExist();
|
||||
expect(wrapper.find('Checkbox')).toHaveStyle({ opacity: 1 });
|
||||
expect(getByTestId('mock-CheckboxUnchecked')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when checked', () => {
|
||||
test('renders the checked component', () => {
|
||||
const { getByTestId } = render(
|
||||
<Checkbox style={{}} checked onChange={() => true} />,
|
||||
);
|
||||
expect(getByTestId('mock-CheckboxChecked')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('works with an onChange handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<Checkbox style={{}} checked={false} onChange={mockAction} />,
|
||||
);
|
||||
fireEvent.click(getByRole('checkbox'));
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('renders custom Checkbox styles without melting', () => {
|
||||
const { getByRole } = render(
|
||||
<Checkbox onChange={() => true} checked={false} style={{ opacity: 1 }} />,
|
||||
);
|
||||
expect(getByRole('checkbox')).toBeInTheDocument();
|
||||
expect(getByRole('checkbox')).toHaveStyle({ opacity: 1 });
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,48 +16,51 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render, waitFor } from 'spec/helpers/testing-library';
|
||||
import Button from 'src/components/Button';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import Modal from 'src/components/Modal';
|
||||
|
||||
describe('ConfirmStatusChange', () => {
|
||||
const mockedProps = {
|
||||
title: 'please confirm',
|
||||
description: 'are you sure?',
|
||||
onConfirm: jest.fn(),
|
||||
};
|
||||
const wrapper = mount(
|
||||
const mockedProps = {
|
||||
title: 'please confirm',
|
||||
description: 'are you sure?',
|
||||
onConfirm: jest.fn(),
|
||||
};
|
||||
|
||||
test('opens a confirm modal', () => {
|
||||
const { getByTestId } = render(
|
||||
<ConfirmStatusChange {...mockedProps}>
|
||||
{confirm => (
|
||||
<>
|
||||
<Button id="btn1" onClick={confirm} />
|
||||
<Button data-test="btn1" onClick={confirm} />
|
||||
</>
|
||||
)}
|
||||
</ConfirmStatusChange>,
|
||||
{
|
||||
wrappingComponent: ThemeProvider,
|
||||
wrappingComponentProps: { theme: supersetTheme },
|
||||
},
|
||||
);
|
||||
|
||||
it('opens a confirm modal', () => {
|
||||
act(() => {
|
||||
wrapper.find('#btn1').first().props().onClick('foo');
|
||||
});
|
||||
fireEvent.click(getByTestId('btn1'));
|
||||
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find(Modal)).toExist();
|
||||
});
|
||||
|
||||
it('calls the function on confirm', () => {
|
||||
act(() => {
|
||||
wrapper.find(Button).last().props().onClick();
|
||||
});
|
||||
|
||||
expect(mockedProps.onConfirm).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
expect(getByTestId(`${mockedProps.title}-modal`)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls the function on confirm', async () => {
|
||||
const { getByTestId, getByRole } = render(
|
||||
<ConfirmStatusChange {...mockedProps}>
|
||||
{confirm => (
|
||||
<>
|
||||
<Button data-test="btn1" onClick={() => confirm('foo')} />
|
||||
</>
|
||||
)}
|
||||
</ConfirmStatusChange>,
|
||||
);
|
||||
|
||||
fireEvent.click(getByTestId('btn1'));
|
||||
|
||||
const confirmInput = getByTestId('delete-modal-input');
|
||||
fireEvent.change(confirmInput, { target: { value: 'DELETE' } });
|
||||
|
||||
const confirmButton = getByRole('button', { name: 'delete' });
|
||||
fireEvent.click(confirmButton);
|
||||
|
||||
await waitFor(() => expect(mockedProps.onConfirm).toHaveBeenCalledTimes(1));
|
||||
expect(mockedProps.onConfirm).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,16 +16,12 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { mount } from 'enzyme';
|
||||
import { waitFor, render, fireEvent } from 'spec/helpers/testing-library';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import thunk from 'redux-thunk';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import sinon from 'sinon';
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import Modal from 'src/components/Modal';
|
||||
import { ChangeDatasourceModal } from 'src/components/Datasource';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import mockDatasource from 'spec/fixtures/mockDatasource';
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
|
@ -57,60 +53,40 @@ fetchMock.get(DATASOURCES_ENDPOINT, { result: [mockDatasource['7__table']] });
|
|||
fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD);
|
||||
fetchMock.get(INFO_ENDPOINT, {});
|
||||
|
||||
async function mountAndWait(props = mockedProps) {
|
||||
const mounted = mount(<ChangeDatasourceModal store={store} {...props} />, {
|
||||
wrappingComponent: ThemeProvider,
|
||||
wrappingComponentProps: { theme: supersetTheme },
|
||||
});
|
||||
await waitForComponentToPaint(mounted);
|
||||
|
||||
return mounted;
|
||||
}
|
||||
|
||||
describe('ChangeDatasourceModal', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(async () => {
|
||||
wrapper = await mountAndWait();
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(wrapper.find(ChangeDatasourceModal)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders a Modal', () => {
|
||||
expect(wrapper.find(Modal)).toExist();
|
||||
});
|
||||
|
||||
it('fetches datasources', async () => {
|
||||
expect(fetchMock.calls(INFO_ENDPOINT)).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('renders confirmation message', async () => {
|
||||
await waitForComponentToPaint(wrapper, 1000);
|
||||
|
||||
act(() => {
|
||||
wrapper.find('[data-test="datasource-link"]').at(0).props().onClick();
|
||||
});
|
||||
|
||||
await waitForComponentToPaint(wrapper);
|
||||
|
||||
expect(wrapper.find('.proceed-btn')).toExist();
|
||||
});
|
||||
|
||||
it('changes the datasource', async () => {
|
||||
await waitForComponentToPaint(wrapper, 1000);
|
||||
|
||||
act(() => {
|
||||
wrapper.find('[data-test="datasource-link"]').at(0).props().onClick();
|
||||
});
|
||||
await waitForComponentToPaint(wrapper);
|
||||
|
||||
act(() => {
|
||||
wrapper.find('.proceed-btn').at(0).props().onClick(datasourceData);
|
||||
});
|
||||
await waitForComponentToPaint(wrapper);
|
||||
|
||||
expect(fetchMock.calls(/api\/v1\/dataset\/7/)).toHaveLength(1);
|
||||
});
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
});
|
||||
|
||||
const setup = (props = mockedProps) =>
|
||||
render(<ChangeDatasourceModal {...props} />, {
|
||||
useRedux: true,
|
||||
store,
|
||||
});
|
||||
|
||||
test('renders', () => {
|
||||
const { getByTestId } = setup();
|
||||
expect(getByTestId('Swap dataset-modal')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('fetches datasources', async () => {
|
||||
setup();
|
||||
await waitFor(() => expect(fetchMock.calls(INFO_ENDPOINT)).toHaveLength(1));
|
||||
});
|
||||
|
||||
test('renders confirmation message', async () => {
|
||||
const { findByTestId, getByRole } = setup();
|
||||
const confirmLink = await findByTestId('datasource-link');
|
||||
fireEvent.click(confirmLink);
|
||||
expect(getByRole('button', { name: 'Proceed' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('changes the datasource', async () => {
|
||||
const { findByTestId, getByRole } = setup();
|
||||
const confirmLink = await findByTestId('datasource-link');
|
||||
fireEvent.click(confirmLink);
|
||||
const proceedButton = getByRole('button', { name: 'Proceed' });
|
||||
fireEvent.click(proceedButton);
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(/api\/v1\/dataset\/7/)).toHaveLength(1),
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { isValidElement } from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
|
||||
import mockDatasource from 'spec/fixtures/mockDatasource';
|
||||
import CollectionTable from './CollectionTable';
|
||||
|
|
@ -27,22 +26,13 @@ const props = {
|
|||
tableColumns: ['column_name', 'type', 'groupby'],
|
||||
};
|
||||
|
||||
describe('CollectionTable', () => {
|
||||
let wrapper;
|
||||
let el;
|
||||
|
||||
beforeEach(() => {
|
||||
el = <CollectionTable {...props} />;
|
||||
wrapper = shallow(el);
|
||||
});
|
||||
|
||||
it('is valid', () => {
|
||||
expect(isValidElement(el)).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a table', () => {
|
||||
const { length } = mockDatasource['7__table'].columns;
|
||||
expect(wrapper.find('table')).toExist();
|
||||
expect(wrapper.find('tbody tr.row')).toHaveLength(length);
|
||||
});
|
||||
test('renders a table', () => {
|
||||
const { length } = mockDatasource['7__table'].columns;
|
||||
const { getByRole } = render(<CollectionTable {...props} />);
|
||||
expect(getByRole('table')).toBeInTheDocument();
|
||||
expect(
|
||||
getByRole('table')
|
||||
.getElementsByTagName('tbody')[0]
|
||||
.getElementsByClassName('row'),
|
||||
).toHaveLength(length);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,40 +16,34 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { fireEvent, render, screen } from 'spec/helpers/testing-library';
|
||||
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import { shallow } from 'enzyme';
|
||||
import TextAreaControl from 'src/explore/components/controls/TextAreaControl';
|
||||
import Field from './Field';
|
||||
|
||||
describe('Field', () => {
|
||||
const defaultProps = {
|
||||
fieldKey: 'mock',
|
||||
value: '',
|
||||
label: 'mock',
|
||||
description: 'description',
|
||||
control: <TextAreaControl />,
|
||||
onChange: jest.fn(),
|
||||
compact: false,
|
||||
inline: false,
|
||||
};
|
||||
const defaultProps = {
|
||||
fieldKey: 'mock',
|
||||
value: '',
|
||||
label: 'mock',
|
||||
description: 'description',
|
||||
control: <input type="text" data-test="mock-text-control" />,
|
||||
onChange: jest.fn(),
|
||||
compact: false,
|
||||
inline: false,
|
||||
};
|
||||
|
||||
it('should render', () => {
|
||||
const { container } = render(<Field {...defaultProps} />);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call onChange', () => {
|
||||
const wrapper = shallow(<Field {...defaultProps} />);
|
||||
const textArea = wrapper.find(TextAreaControl);
|
||||
textArea.simulate('change', { target: { value: 'x' } });
|
||||
expect(defaultProps.onChange).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should render compact', () => {
|
||||
render(<Field {...defaultProps} compact />);
|
||||
expect(
|
||||
screen.queryByText(defaultProps.description),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
test('should render', () => {
|
||||
const { container } = render(<Field {...defaultProps} />);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should call onChange', () => {
|
||||
const { getByTestId } = render(<Field {...defaultProps} />);
|
||||
const textArea = getByTestId('mock-text-control');
|
||||
fireEvent.change(textArea, { target: { value: 'x' } });
|
||||
expect(defaultProps.onChange).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should render compact', () => {
|
||||
render(<Field {...defaultProps} compact />);
|
||||
expect(screen.queryByText(defaultProps.description)).not.toBeInTheDocument();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,88 +16,98 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { isValidElement } from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
import { fireEvent, getByRole, render } from 'spec/helpers/testing-library';
|
||||
|
||||
import EditableTable from 'src/components/EditableTitle';
|
||||
|
||||
describe('EditableTitle', () => {
|
||||
const callback = sinon.spy();
|
||||
const mockProps = {
|
||||
title: 'my title',
|
||||
canEdit: true,
|
||||
onSaveTitle: callback,
|
||||
};
|
||||
const mockEvent = {
|
||||
target: {
|
||||
value: 'new title',
|
||||
},
|
||||
};
|
||||
let editableWrapper = shallow(<EditableTable {...mockProps} />);
|
||||
const notEditableWrapper = shallow(
|
||||
<EditableTable title="my title" onSaveTitle={callback} />,
|
||||
const mockEvent = {
|
||||
target: {
|
||||
value: 'new title',
|
||||
},
|
||||
};
|
||||
const mockProps = {
|
||||
title: 'my title',
|
||||
canEdit: true,
|
||||
onSaveTitle: jest.fn(),
|
||||
};
|
||||
|
||||
test('should render title', () => {
|
||||
const { getByRole } = render(<EditableTable {...mockProps} />);
|
||||
expect(getByRole('button')).toBeInTheDocument();
|
||||
expect(getByRole('button')).toHaveValue(mockProps.title);
|
||||
});
|
||||
test('should not render an input if it is not editable', () => {
|
||||
const { queryByRole } = render(
|
||||
<EditableTable title="my title" onSaveTitle={jest.fn()} />,
|
||||
);
|
||||
it('is valid', () => {
|
||||
expect(isValidElement(<EditableTable {...mockProps} />)).toBe(true);
|
||||
});
|
||||
it('should render title', () => {
|
||||
const titleElement = editableWrapper.find('input');
|
||||
expect(titleElement.props().value).toBe('my title');
|
||||
expect(titleElement.props().type).toBe('button');
|
||||
});
|
||||
it('should not render an input if it is not editable', () => {
|
||||
expect(notEditableWrapper.find('input')).not.toExist();
|
||||
});
|
||||
expect(queryByRole('button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('should handle click', () => {
|
||||
it('should change title', () => {
|
||||
editableWrapper.find('input').simulate('click');
|
||||
expect(editableWrapper.find('input').props().type).toBe('text');
|
||||
});
|
||||
});
|
||||
|
||||
describe('should handle change', () => {
|
||||
afterEach(() => {
|
||||
editableWrapper = shallow(<EditableTable {...mockProps} />);
|
||||
});
|
||||
it('should change title', () => {
|
||||
editableWrapper.find('input').simulate('change', mockEvent);
|
||||
expect(editableWrapper.find('input').props().value).toBe('new title');
|
||||
});
|
||||
});
|
||||
|
||||
describe('should handle blur', () => {
|
||||
beforeEach(() => {
|
||||
editableWrapper.find('input').simulate('click');
|
||||
});
|
||||
afterEach(() => {
|
||||
callback.resetHistory();
|
||||
editableWrapper = shallow(<EditableTable {...mockProps} />);
|
||||
});
|
||||
|
||||
it('default input type should be text', () => {
|
||||
expect(editableWrapper.find('input').props().type).toBe('text');
|
||||
});
|
||||
|
||||
it('should trigger callback', () => {
|
||||
editableWrapper.find('input').simulate('change', mockEvent);
|
||||
editableWrapper.find('input').simulate('blur');
|
||||
expect(editableWrapper.find('input').props().type).toBe('button');
|
||||
expect(callback.callCount).toBe(1);
|
||||
expect(callback.getCall(0).args[0]).toBe('new title');
|
||||
});
|
||||
it('should not trigger callback', () => {
|
||||
editableWrapper.find('input').simulate('blur');
|
||||
expect(editableWrapper.find('input').props().type).toBe('button');
|
||||
// no change
|
||||
expect(callback.callCount).toBe(0);
|
||||
});
|
||||
it('should not save empty title', () => {
|
||||
editableWrapper.find('input').simulate('blur');
|
||||
expect(editableWrapper.find('input').props().type).toBe('button');
|
||||
expect(editableWrapper.find('input').props().value).toBe('my title');
|
||||
expect(callback.callCount).toBe(0);
|
||||
});
|
||||
describe('should handle click', () => {
|
||||
test('should change title', () => {
|
||||
const { getByRole, container } = render(<EditableTable {...mockProps} />);
|
||||
fireEvent.click(getByRole('button'));
|
||||
expect(container.querySelector('input')?.getAttribute('type')).toEqual(
|
||||
'text',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('should handle change', () => {
|
||||
test('should change title', () => {
|
||||
const { getByTestId, container } = render(
|
||||
<EditableTable {...mockProps} editing />,
|
||||
);
|
||||
fireEvent.change(getByTestId('editable-title-input'), mockEvent);
|
||||
expect(container.querySelector('input')).toHaveValue('new title');
|
||||
});
|
||||
});
|
||||
|
||||
describe('should handle blur', () => {
|
||||
const setup = (overrides: Partial<typeof mockProps> = {}) => {
|
||||
const selectors = render(<EditableTable {...mockProps} {...overrides} />);
|
||||
fireEvent.click(selectors.getByRole('button'));
|
||||
return selectors;
|
||||
};
|
||||
|
||||
test('default input type should be text', () => {
|
||||
const { container } = setup();
|
||||
expect(container.querySelector('input')?.getAttribute('type')).toEqual(
|
||||
'text',
|
||||
);
|
||||
});
|
||||
|
||||
test('should trigger callback', () => {
|
||||
const callback = jest.fn();
|
||||
const { getByTestId, container } = setup({ onSaveTitle: callback });
|
||||
fireEvent.change(getByTestId('editable-title-input'), mockEvent);
|
||||
fireEvent.blur(getByTestId('editable-title-input'));
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
expect(callback).toHaveBeenCalledWith('new title');
|
||||
expect(container.querySelector('input')?.getAttribute('type')).toEqual(
|
||||
'button',
|
||||
);
|
||||
});
|
||||
|
||||
test('should not trigger callback', () => {
|
||||
const callback = jest.fn();
|
||||
const { getByTestId, container } = setup({ onSaveTitle: callback });
|
||||
fireEvent.blur(getByTestId('editable-title-input'));
|
||||
expect(container.querySelector('input')?.getAttribute('type')).toEqual(
|
||||
'button',
|
||||
);
|
||||
// no change
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should not save empty title', () => {
|
||||
const callback = jest.fn();
|
||||
const { getByTestId, container } = setup({ onSaveTitle: callback });
|
||||
fireEvent.blur(getByTestId('editable-title-input'));
|
||||
expect(container.querySelector('input')?.getAttribute('type')).toEqual(
|
||||
'button',
|
||||
);
|
||||
expect(getByRole(container, 'button')).toHaveValue(mockProps.title);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,42 +16,44 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
|
||||
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
|
||||
import { Row, Col } from 'src/components';
|
||||
import TextControl from 'src/explore/components/controls/TextControl';
|
||||
import FormRow from 'src/components/FormRow';
|
||||
|
||||
jest.mock('@superset-ui/chart-controls', () => ({
|
||||
...jest.requireActual('@superset-ui/chart-controls'),
|
||||
InfoTooltipWithTrigger: () => <div data-test="mock-info-tooltip" />,
|
||||
}));
|
||||
jest.mock('src/components', () => ({
|
||||
...jest.requireActual('src/components'),
|
||||
Row: ({ children }) => <div data-test="mock-row">{children}</div>,
|
||||
Col: ({ children }) => <div data-test="mock-col">{children}</div>,
|
||||
}));
|
||||
|
||||
const defaultProps = {
|
||||
label: 'Hello',
|
||||
tooltip: 'A tooltip',
|
||||
control: <TextControl label="test_cbox" />,
|
||||
};
|
||||
|
||||
describe('FormRow', () => {
|
||||
let wrapper;
|
||||
|
||||
const getWrapper = (overrideProps = {}) => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
...overrideProps,
|
||||
};
|
||||
return shallow(<FormRow {...props} />);
|
||||
const setup = (overrideProps = {}) => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
...overrideProps,
|
||||
};
|
||||
return render(<FormRow {...props} />);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = getWrapper();
|
||||
});
|
||||
|
||||
it('renders an InfoTooltipWithTrigger only if needed', () => {
|
||||
expect(wrapper.find(InfoTooltipWithTrigger)).toExist();
|
||||
wrapper = getWrapper({ tooltip: null });
|
||||
expect(wrapper.find(InfoTooltipWithTrigger)).not.toExist();
|
||||
});
|
||||
|
||||
it('renders a Row and 2 Cols', () => {
|
||||
expect(wrapper.find(Row)).toExist();
|
||||
expect(wrapper.find(Col)).toHaveLength(2);
|
||||
});
|
||||
test('renders an InfoTooltipWithTrigger only if needed', () => {
|
||||
const { getByTestId, queryByTestId, rerender } = setup();
|
||||
expect(getByTestId('mock-info-tooltip')).toBeInTheDocument();
|
||||
rerender(<FormRow {...defaultProps} tooltip={null} />);
|
||||
expect(queryByTestId('mock-info-tooltip')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders a Row and 2 Cols', () => {
|
||||
const { getByTestId, getAllByTestId } = setup();
|
||||
expect(getByTestId('mock-row')).toBeInTheDocument();
|
||||
expect(getAllByTestId('mock-col')).toHaveLength(2);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,25 +16,29 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { isValidElement } from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
import { IconTooltip } from 'src/components/IconTooltip';
|
||||
|
||||
describe('IconTooltip', () => {
|
||||
const mockedProps = {
|
||||
tooltip: 'This is a tooltip',
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(isValidElement(<IconTooltip>TEST</IconTooltip>)).toBe(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(
|
||||
isValidElement(<IconTooltip {...mockedProps}>TEST</IconTooltip>),
|
||||
).toBe(true);
|
||||
});
|
||||
it('renders a tooltip', () => {
|
||||
const wrapper = shallow(<IconTooltip {...mockedProps}>TEST</IconTooltip>);
|
||||
expect(wrapper.find(Tooltip)).toExist();
|
||||
});
|
||||
jest.mock('src/components/Tooltip', () => ({
|
||||
Tooltip: () => <div data-test="mock-tooltip" />,
|
||||
}));
|
||||
|
||||
const mockedProps = {
|
||||
tooltip: 'This is a tooltip',
|
||||
};
|
||||
test('renders', () => {
|
||||
const { container } = render(<IconTooltip>TEST</IconTooltip>);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
test('renders with props', () => {
|
||||
const { container } = render(
|
||||
<IconTooltip {...mockedProps}>TEST</IconTooltip>,
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
test('renders a tooltip', () => {
|
||||
const { getByTestId } = render(
|
||||
<IconTooltip {...mockedProps}>TEST</IconTooltip>,
|
||||
);
|
||||
expect(getByTestId('mock-tooltip')).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,18 +16,14 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import thunk from 'redux-thunk';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { fireEvent, render, waitFor } from 'spec/helpers/testing-library';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { Upload } from 'src/components';
|
||||
import Button from 'src/components/Button';
|
||||
import { ImportResourceName } from 'src/views/CRUD/types';
|
||||
import ImportModelsModal from 'src/components/ImportModal';
|
||||
import Modal from 'src/components/Modal';
|
||||
import ImportModelsModal, {
|
||||
ImportModelsModalProps,
|
||||
} from 'src/components/ImportModal';
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
const store = mockStore({});
|
||||
|
|
@ -48,148 +44,98 @@ const requiredProps = {
|
|||
onHide: () => {},
|
||||
};
|
||||
|
||||
describe('ImportModelsModal', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(<ImportModelsModal {...requiredProps} />, {
|
||||
context: { store },
|
||||
});
|
||||
});
|
||||
const setup = (overrides: Partial<ImportModelsModalProps> = {}) =>
|
||||
render(<ImportModelsModal {...requiredProps} {...overrides} />, { store });
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
test('renders', () => {
|
||||
const { container } = setup();
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(wrapper.find(ImportModelsModal)).toExist();
|
||||
});
|
||||
test('renders a Modal', () => {
|
||||
const { getByTestId } = setup();
|
||||
expect(getByTestId('model-modal')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders a Modal', () => {
|
||||
expect(wrapper.find(Modal)).toExist();
|
||||
});
|
||||
test('renders "Import database" header', () => {
|
||||
const { getByText } = setup();
|
||||
expect(getByText('Import database')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders "Import database" header', () => {
|
||||
expect(wrapper.find('h4').text()).toEqual('Import database');
|
||||
});
|
||||
test('renders a file input field', () => {
|
||||
setup();
|
||||
expect(document.querySelector('input[type="file"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders a file input field', () => {
|
||||
expect(wrapper.find('input[type="file"]')).toExist();
|
||||
});
|
||||
test('should render the close, file, import and cancel buttons', () => {
|
||||
setup();
|
||||
expect(document.querySelectorAll('button')).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('should render the close, file, import and cancel buttons', () => {
|
||||
expect(wrapper.find('button')).toHaveLength(4);
|
||||
});
|
||||
test('should render the import button initially disabled', () => {
|
||||
const { getByRole } = setup();
|
||||
expect(getByRole('button', { name: 'Import' })).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should render the import button initially disabled', () => {
|
||||
expect(wrapper.find(Button).at(2).prop('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('should render the import button enabled when a file is selected', () => {
|
||||
const file = new File([new ArrayBuffer(1)], 'model_export.zip');
|
||||
act(() => {
|
||||
const handler = wrapper.find(Upload).prop('onChange');
|
||||
if (handler) {
|
||||
handler({
|
||||
fileList: [],
|
||||
file: {
|
||||
name: 'model_export.zip',
|
||||
originFileObj: file,
|
||||
uid: '-1',
|
||||
size: 0,
|
||||
type: 'zip',
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find(Button).at(2).prop('disabled')).toBe(false);
|
||||
});
|
||||
|
||||
it('should POST with request header `Accept: application/json`', async () => {
|
||||
const file = new File([new ArrayBuffer(1)], 'model_export.zip');
|
||||
act(() => {
|
||||
const handler = wrapper.find(Upload).prop('onChange');
|
||||
if (handler) {
|
||||
handler({
|
||||
fileList: [],
|
||||
file: {
|
||||
name: 'model_export.zip',
|
||||
originFileObj: file,
|
||||
uid: '-1',
|
||||
size: 0,
|
||||
type: 'zip',
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
wrapper.find(Button).at(2).simulate('click');
|
||||
await waitForComponentToPaint(wrapper);
|
||||
expect(fetchMock.calls(DATABASE_IMPORT_URL)[0][1]?.headers).toStrictEqual({
|
||||
Accept: 'application/json',
|
||||
'X-CSRFToken': '1234',
|
||||
});
|
||||
});
|
||||
|
||||
it('should render password fields when needed for import', () => {
|
||||
const wrapperWithPasswords = mount(
|
||||
<ImportModelsModal
|
||||
{...requiredProps}
|
||||
passwordFields={['databases/examples.yaml']}
|
||||
/>,
|
||||
{
|
||||
context: { store },
|
||||
test('should render the import button enabled when a file is selected', async () => {
|
||||
const file = new File([new ArrayBuffer(1)], 'model_export.zip');
|
||||
const { getByTestId, getByRole } = setup();
|
||||
await waitFor(() =>
|
||||
fireEvent.change(getByTestId('model-file-input'), {
|
||||
target: {
|
||||
files: [file],
|
||||
},
|
||||
);
|
||||
expect(wrapperWithPasswords.find('input[type="password"]')).toExist();
|
||||
});
|
||||
}),
|
||||
);
|
||||
expect(getByRole('button', { name: 'Import' })).toBeEnabled();
|
||||
});
|
||||
|
||||
it('should render ssh_tunnel password fields when needed for import', () => {
|
||||
const wrapperWithPasswords = mount(
|
||||
<ImportModelsModal
|
||||
{...requiredProps}
|
||||
sshTunnelPasswordFields={['databases/examples.yaml']}
|
||||
/>,
|
||||
{
|
||||
context: { store },
|
||||
test('should POST with request header `Accept: application/json`', async () => {
|
||||
const file = new File([new ArrayBuffer(1)], 'model_export.zip');
|
||||
const { getByTestId, getByRole } = setup();
|
||||
await waitFor(() =>
|
||||
fireEvent.change(getByTestId('model-file-input'), {
|
||||
target: {
|
||||
files: [file],
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wrapperWithPasswords.find('[data-test="ssh_tunnel_password"]'),
|
||||
).toExist();
|
||||
});
|
||||
|
||||
it('should render ssh_tunnel private_key fields when needed for import', () => {
|
||||
const wrapperWithPasswords = mount(
|
||||
<ImportModelsModal
|
||||
{...requiredProps}
|
||||
sshTunnelPrivateKeyFields={['databases/examples.yaml']}
|
||||
/>,
|
||||
{
|
||||
context: { store },
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wrapperWithPasswords.find('[data-test="ssh_tunnel_private_key"]'),
|
||||
).toExist();
|
||||
});
|
||||
|
||||
it('should render ssh_tunnel private_key_password fields when needed for import', () => {
|
||||
const wrapperWithPasswords = mount(
|
||||
<ImportModelsModal
|
||||
{...requiredProps}
|
||||
sshTunnelPrivateKeyPasswordFields={['databases/examples.yaml']}
|
||||
/>,
|
||||
{
|
||||
context: { store },
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wrapperWithPasswords.find(
|
||||
'[data-test="ssh_tunnel_private_key_password"]',
|
||||
),
|
||||
).toExist();
|
||||
}),
|
||||
);
|
||||
fireEvent.click(getByRole('button', { name: 'Import' }));
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(DATABASE_IMPORT_URL)).toHaveLength(1),
|
||||
);
|
||||
expect(fetchMock.calls(DATABASE_IMPORT_URL)[0][1]?.headers).toStrictEqual({
|
||||
Accept: 'application/json',
|
||||
'X-CSRFToken': '1234',
|
||||
});
|
||||
});
|
||||
|
||||
test('should render password fields when needed for import', () => {
|
||||
setup({ passwordFields: ['databases/examples.yaml'] });
|
||||
expect(document.querySelector('input[type="password"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render ssh_tunnel password fields when needed for import', () => {
|
||||
const { getByTestId } = setup({
|
||||
sshTunnelPasswordFields: ['databases/examples.yaml'],
|
||||
});
|
||||
expect(getByTestId('ssh_tunnel_password')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render ssh_tunnel private_key fields when needed for import', () => {
|
||||
const { getByTestId } = setup({
|
||||
sshTunnelPrivateKeyFields: ['databases/examples.yaml'],
|
||||
});
|
||||
expect(getByTestId('ssh_tunnel_private_key')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render ssh_tunnel private_key_password fields when needed for import', () => {
|
||||
const { getByTestId } = setup({
|
||||
sshTunnelPrivateKeyPasswordFields: ['databases/examples.yaml'],
|
||||
});
|
||||
expect(getByTestId('ssh_tunnel_private_key_password')).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,42 +16,28 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { fireEvent, render } from 'spec/helpers/testing-library';
|
||||
|
||||
import { isValidElement } from 'react';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import Label from '.';
|
||||
import { LabelGallery, options } from './Label.stories';
|
||||
|
||||
describe('Label', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
// test the basic component
|
||||
it('renders the base component (no onClick)', () => {
|
||||
expect(isValidElement(<Label />)).toBe(true);
|
||||
});
|
||||
|
||||
it('renders with role=undefined when onClick is not present', () => {
|
||||
wrapper = mount(<Label />);
|
||||
expect(wrapper.find('span').prop('role')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('renders with role="button" when onClick is present', () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(<Label onClick={mockAction} />);
|
||||
expect(wrapper.find('span').prop('role')).toBe('button');
|
||||
});
|
||||
|
||||
it('works with an onClick handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(<Label onClick={mockAction} />);
|
||||
wrapper.find(Label).simulate('click');
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// test stories from the storybook!
|
||||
it('renders all the storybook gallery variants', () => {
|
||||
wrapper = mount(<LabelGallery />);
|
||||
expect(wrapper.find(Label).length).toEqual(options.length * 2);
|
||||
});
|
||||
// test the basic component
|
||||
test('renders the base component (no onClick)', () => {
|
||||
const { container } = render(<Label />);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('works with an onClick handler', () => {
|
||||
const mockAction = jest.fn();
|
||||
const { getByText } = render(<Label onClick={mockAction}>test</Label>);
|
||||
fireEvent.click(getByText('test'));
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// test stories from the storybook!
|
||||
test('renders all the storybook gallery variants', () => {
|
||||
const { container } = render(<LabelGallery />);
|
||||
expect(container.querySelectorAll('.ant-tag')).toHaveLength(
|
||||
options.length * 2,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,30 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { fireEvent, render } from 'spec/helpers/testing-library';
|
||||
|
||||
import { MouseEvent } from 'react';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import LastUpdated from '.';
|
||||
|
||||
describe('LastUpdated', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
const updatedAt = new Date('Sat Dec 12 2020 00:00:00 GMT-0800');
|
||||
const updatedAt = new Date('Sat Dec 12 2020 00:00:00 GMT-0800');
|
||||
|
||||
it('renders the base component (no refresh)', () => {
|
||||
const wrapper = mount(<LastUpdated updatedAt={updatedAt} />);
|
||||
expect(/^Last Updated .+$/.test(wrapper.text())).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a refresh action', async () => {
|
||||
const mockAction = jest.fn();
|
||||
wrapper = mount(<LastUpdated updatedAt={updatedAt} update={mockAction} />);
|
||||
await waitForComponentToPaint(wrapper);
|
||||
const props = wrapper.find('[aria-label="refresh"]').first().props();
|
||||
if (props.onClick) {
|
||||
props.onClick({} as MouseEvent);
|
||||
}
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
test('renders the base component (no refresh)', () => {
|
||||
const { getByText } = render(<LastUpdated updatedAt={updatedAt} />);
|
||||
expect(getByText(/^Last Updated .+$/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders a refresh action', async () => {
|
||||
const mockAction = jest.fn();
|
||||
const { getByLabelText } = render(
|
||||
<LastUpdated updatedAt={updatedAt} update={mockAction} />,
|
||||
);
|
||||
fireEvent.click(getByLabelText('refresh'));
|
||||
expect(mockAction).toHaveBeenCalled();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { mount } from 'enzyme';
|
||||
import { ThemeProvider, supersetTheme } from '@superset-ui/core';
|
||||
import { fireEvent, render, waitFor } from 'spec/helpers/testing-library';
|
||||
import Toast from 'src/components/MessageToasts/Toast';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import mockMessageToasts from './mockMessageToasts';
|
||||
|
||||
const props = {
|
||||
|
|
@ -27,35 +25,22 @@ const props = {
|
|||
onCloseToast() {},
|
||||
};
|
||||
|
||||
const setup = overrideProps =>
|
||||
mount(<Toast {...props} {...overrideProps} />, {
|
||||
wrappingComponent: ThemeProvider,
|
||||
wrappingComponentProps: { theme: supersetTheme },
|
||||
});
|
||||
const setup = overrideProps => render(<Toast {...props} {...overrideProps} />);
|
||||
|
||||
describe('Toast', () => {
|
||||
it('should render', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find('[data-test="toast-container"]')).toExist();
|
||||
});
|
||||
|
||||
it('should render toastText within the div', () => {
|
||||
const wrapper = setup();
|
||||
const container = wrapper.find('[data-test="toast-container"]');
|
||||
expect(container.hostNodes().childAt(1).text()).toBe(props.toast.text);
|
||||
});
|
||||
|
||||
it('should call onCloseToast upon toast dismissal', async () =>
|
||||
act(
|
||||
() =>
|
||||
new Promise(done => {
|
||||
const onCloseToast = id => {
|
||||
expect(id).toBe(props.toast.id);
|
||||
done();
|
||||
};
|
||||
|
||||
const wrapper = setup({ onCloseToast });
|
||||
wrapper.find('[data-test="close-button"]').props().onClick();
|
||||
}),
|
||||
));
|
||||
test('should render', () => {
|
||||
const { getByTestId } = setup();
|
||||
expect(getByTestId('toast-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render toastText within the div', () => {
|
||||
const { getByTestId } = setup();
|
||||
expect(getByTestId('toast-container')).toHaveTextContent(props.toast.text);
|
||||
});
|
||||
|
||||
test('should call onCloseToast upon toast dismissal', async () => {
|
||||
const onCloseToast = jest.fn();
|
||||
const { getByTestId } = setup({ onCloseToast });
|
||||
fireEvent.click(getByTestId('close-button'));
|
||||
await waitFor(() => expect(onCloseToast).toHaveBeenCalledTimes(1));
|
||||
expect(onCloseToast).toHaveBeenCalledWith(props.toast.id);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,35 +16,33 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import Toast from 'src/components/MessageToasts/Toast';
|
||||
import { fireEvent, render, waitFor } from 'spec/helpers/testing-library';
|
||||
|
||||
import ToastPresenter from 'src/components/MessageToasts/ToastPresenter';
|
||||
import mockMessageToasts from './mockMessageToasts';
|
||||
|
||||
describe('ToastPresenter', () => {
|
||||
const props = {
|
||||
toasts: mockMessageToasts,
|
||||
removeToast() {},
|
||||
};
|
||||
const props = {
|
||||
toasts: mockMessageToasts,
|
||||
removeToast() {},
|
||||
};
|
||||
|
||||
function setup(overrideProps) {
|
||||
const wrapper = shallow(<ToastPresenter {...props} {...overrideProps} />);
|
||||
return wrapper;
|
||||
}
|
||||
function setup(overrideProps) {
|
||||
return render(<ToastPresenter {...props} {...overrideProps} />);
|
||||
}
|
||||
|
||||
it('should render a div with id toast-presenter', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find('#toast-presenter')).toExist();
|
||||
});
|
||||
|
||||
it('should render a Toast for each toast object', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find(Toast)).toHaveLength(props.toasts.length);
|
||||
});
|
||||
|
||||
it('should pass removeToast to the Toast component', () => {
|
||||
const removeToast = () => {};
|
||||
const wrapper = setup({ removeToast });
|
||||
expect(wrapper.find(Toast).first().prop('onCloseToast')).toBe(removeToast);
|
||||
});
|
||||
test('should render a div with id toast-presenter', () => {
|
||||
const { container } = setup();
|
||||
expect(container.querySelector('#toast-presenter')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render a Toast for each toast object', () => {
|
||||
const { getAllByRole } = setup();
|
||||
expect(getAllByRole('alert')).toHaveLength(props.toasts.length);
|
||||
});
|
||||
|
||||
test('should pass removeToast to the Toast component', async () => {
|
||||
const removeToast = jest.fn();
|
||||
const { getAllByTestId } = setup({ removeToast });
|
||||
fireEvent.click(getAllByTestId('close-button')[0]);
|
||||
await waitFor(() => expect(removeToast).toHaveBeenCalledTimes(1));
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue