justinpark commented on code in PR #30151:
URL: https://github.com/apache/superset/pull/30151#discussion_r1755604760
##########
superset-frontend/src/explore/components/controls/SelectControl.test.jsx:
##########
@@ -30,139 +37,198 @@ const defaultProps = {
],
name: 'row_limit',
label: 'Row Limit',
- valueKey: 'value', // shallow isn't passing
SelectControl.defaultProps.valueKey through
- onChange: sinon.spy(),
+ valueKey: 'value',
+ onChange: jest.fn(),
};
+jest.useFakeTimers();
+
const options = [
{ value: '1 year ago', label: '1 year ago' },
{ value: '1 week ago', label: '1 week ago' },
{ value: 'today', label: 'today' },
];
-describe('SelectControl', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = shallow(<SelectControl {...defaultProps} />);
- });
+const renderSelectControl = (props = {}) => {
+ const overrideProps = {
+ ...defaultProps,
+ ...props,
+ };
+ const { container } = render(<SelectControl {...overrideProps} />);
+ return container;
+};
- it('calls props.onChange when select', () => {
- const select = wrapper.instance();
- select.onChange(50);
- expect(defaultProps.onChange.calledWith(50)).toBe(true);
+describe('SelectControl', () => {
+ it('calls props.onChange when select', async () => {
+ renderSelectControl();
+ defaultProps.onChange(50);
+ expect(defaultProps.onChange).toHaveBeenCalledWith(50);
});
describe('render', () => {
it('renders with Select by default', () => {
- expect(wrapper.find(SelectComponent)).toExist();
+ renderSelectControl();
+ const selectorWrapper = screen.getByLabelText('Row Limit', {
+ selector: 'div',
+ });
+ const selectorInput = within(selectorWrapper).getByLabelText(
+ 'Row Limit',
+ { selector: 'input' },
+ );
+ expect(selectorWrapper).toBeInTheDocument();
+ expect(selectorInput).toBeInTheDocument();
});
it('renders as mode multiple', () => {
- wrapper.setProps({ multi: true });
- expect(wrapper.find(SelectComponent)).toExist();
- expect(wrapper.find(SelectComponent).prop('mode')).toBe('multiple');
+ renderSelectControl({ multi: true });
+ const selectorWrapper = screen.getByLabelText('Row Limit', {
+ selector: 'div',
+ });
+ const selectorInput = within(selectorWrapper).getByLabelText(
+ 'Row Limit',
+ { selector: 'input' },
+ );
+ expect(selectorWrapper).toBeInTheDocument();
+ expect(selectorInput).toBeInTheDocument();
+ userEvent.click(selectorInput);
+ expect(screen.getByText('Select All (3)')).toBeInTheDocument();
});
it('renders with allowNewOptions when freeForm', () => {
- wrapper.setProps({ freeForm: true });
- expect(wrapper.find(SelectComponent)).toExist();
- expect(wrapper.find(SelectComponent).prop('allowNewOptions')).toBe(true);
+ renderSelectControl({ freeForm: true });
+ const selectorWrapper = screen.getByLabelText('Row Limit', {
+ selector: 'div',
+ });
+ const selectorInput = within(selectorWrapper).getByLabelText(
+ 'Row Limit',
+ { selector: 'input' },
+ );
+ expect(selectorWrapper).toBeInTheDocument();
+ expect(selectorInput).toBeInTheDocument();
+
+ // Expect a new option to be selectable.
+ userEvent.click(selectorInput);
+ userEvent.type(selectorInput, 'a new option');
+ act(() => jest.runAllTimers());
+ expect(within(selectorWrapper).getByRole('option')).toHaveTextContent(
+ 'a new option',
+ );
});
it('renders with allowNewOptions=false when freeForm=false', () => {
- wrapper.setProps({ freeForm: false });
- expect(wrapper.find(SelectComponent)).toExist();
-
expect(wrapper.find(SelectComponent).prop('allowNewOptions')).toBe(false);
+ const container = renderSelectControl({ freeForm: false });
+ const selectorWrapper = screen.getByLabelText('Row Limit', {
+ selector: 'div',
+ });
+ const selectorInput = within(selectorWrapper).getByLabelText(
+ 'Row Limit',
+ { selector: 'input' },
+ );
+ expect(selectorWrapper).toBeInTheDocument();
+ expect(selectorInput).toBeInTheDocument();
+
+ // Expect no new option to be selectable.
+ userEvent.click(selectorInput);
+ userEvent.type(selectorInput, 'a new option');
+ act(() => jest.advanceTimersByTime(300));
+
+ expect(
+ container.querySelector('[role="option"]'),
+ ).not.toBeInTheDocument();
+ expect(within(selectorWrapper).getByText('No Data')).toBeInTheDocument();
});
it('renders with tokenSeparators', () => {
- wrapper.setProps({ tokenSeparators: ['\n', '\t', ';'] });
- expect(wrapper.find(SelectComponent)).toExist();
- expect(wrapper.find(SelectComponent).prop('tokenSeparators')).toEqual(
- expect.arrayContaining([expect.any(String)]),
+ renderSelectControl({ tokenSeparators: ['\n', '\t', ';'], multi: true });
+ const selectorWrapper = screen.getByLabelText('Row Limit', {
+ selector: 'div',
+ });
+ const selectorInput = within(selectorWrapper).getByLabelText(
+ 'Row Limit',
+ { selector: 'input' },
);
+ expect(selectorWrapper).toBeInTheDocument();
+ expect(selectorInput).toBeInTheDocument();
+
+ userEvent.click(selectorInput);
+ const paste = createEvent.paste(selectorInput, {
+ clipboardData: {
+ getData: () => '1 year ago;1 week ago',
+ },
+ });
+ fireEvent(selectorInput, paste);
+ const yearOption = screen.getByLabelText('1 year ago');
+ expect(yearOption).toBeInTheDocument();
+ expect(yearOption).toHaveAttribute('aria-selected', 'true');
+ const weekOption = screen.getByText(/1 week ago/, {
+ selector: 'div',
+ }).parentNode;
+ expect(weekOption?.getAttribute('aria-selected')).toEqual('true');
});
describe('empty placeholder', () => {
describe('withMulti', () => {
it('does not show a placeholder if there are no choices', () => {
- const withMulti = mount(
- <SelectControl
- {...defaultProps}
- choices={[]}
- multi
- placeholder="add something"
- />,
- );
- expect(withMulti.html()).not.toContain('option(s');
+ const container = renderSelectControl({
+ choices: [],
+ multi: true,
+ placeholder: 'add something',
+ });
+ expect(
+ container.querySelector('[role="option"]'),
Review Comment:
queryByRole is better for this case.
```suggestion
screen.queryByRole('option')
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]