You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2021/09/09 04:07:09 UTC

[GitHub] [superset] villebro commented on a change in pull request #16638: chore: Writes the tests for the new Select component

villebro commented on a change in pull request #16638:
URL: https://github.com/apache/superset/pull/16638#discussion_r704933750



##########
File path: superset-frontend/src/components/Select/Select.test.tsx
##########
@@ -17,66 +17,467 @@
  * under the License.
  */
 import React from 'react';
-import { render, screen } from 'spec/helpers/testing-library';
+import {
+  render,
+  screen,
+  waitFor,
+  waitForElementToBeRemoved,
+  within,
+} from 'spec/helpers/testing-library';
+import userEvent from '@testing-library/user-event';
 import { Select } from 'src/components';
 
-test('renders with default props', () => {
-  const ariaLabel = 'test';
+const ARIA_LABEL = 'Test';
+const NEW_OPTION = 'Kyle';
+const NO_DATA = 'No Data';
+const LOADING = 'Loading...';
+const OPTIONS = [
+  { label: 'John', value: 1 },
+  { label: 'Liam', value: 2 },
+  { label: 'Olivia', value: 3 },
+  { label: 'Emma', value: 4 },
+  { label: 'Noah', value: 5 },
+  { label: 'Ava', value: 6 },
+  { label: 'Oliver', value: 7 },
+  { label: 'ElijahH', value: 8 },
+  { label: 'Charlotte', value: 9 },
+  { label: 'Giovanni', value: 10 },
+  { label: 'Franco', value: 11 },
+  { label: 'Sandro', value: 12 },
+  { label: 'Alehandro', value: 13 },
+  { label: 'Johnny', value: 14 },
+  { label: 'Nikole', value: 15 },
+  { label: 'Igor', value: 16 },
+  { label: 'Guilherme', value: 17 },
+  { label: 'Irfan', value: 18 },
+  { label: 'George', value: 19 },
+  { label: 'Ashfaq', value: 20 },
+];
+
+const loadOptions = async (search: string, page: number, pageSize: number) => {
+  const totalCount = OPTIONS.length;
+  const start = page * pageSize;
+  const deleteCount =
+    start + pageSize < totalCount ? pageSize : totalCount - start;
+  const data = OPTIONS.filter(option => option.label.match(search)).splice(
+    start,
+    deleteCount,
+  );
+  return {
+    data,
+    totalCount: OPTIONS.length,
+  };
+};
+
+const defaultProps = {
+  allowClear: true,
+  ariaLabel: ARIA_LABEL,
+  labelInValue: true,
+  options: OPTIONS,
+  pageSize: 10,
+  showSearch: true,
+};
+
+const getElementByClassName = (className: string) =>
+  document.querySelector(className)! as HTMLElement;
+
+const getElementsByClassName = (className: string) =>
+  document.querySelectorAll(className)! as NodeListOf<HTMLElement>;
+
+const getSelect = () => screen.getByRole('combobox', { name: ARIA_LABEL });
+
+const findSelectOption = (text: string) =>
+  waitFor(() =>
+    within(getElementByClassName('.rc-virtual-list')).getByText(text),
+  );
+
+const findAllSelectOptions = () =>
+  waitFor(() => getElementsByClassName('.ant-select-item-option-content'));
+
+const findSelectValue = () =>
+  waitFor(() => getElementByClassName('.ant-select-selection-item'));
+
+const findAllSelectValues = () =>
+  waitFor(() => getElementsByClassName('.ant-select-selection-item'));
+
+const type = (text: string) => userEvent.type(getSelect(), text, { delay: 10 });
+
+const open = () => waitFor(() => userEvent.click(getSelect()));
+
+test('displays a header', async () => {
+  const headerText = 'Header';
+  render(<Select {...defaultProps} header={headerText} />);
+  expect(screen.getByText(headerText)).toBeInTheDocument();
+});
+
+test('inverts the selection', async () => {
+  render(<Select {...defaultProps} invertSelection />);
+  await open();
+  userEvent.click(await findSelectOption(OPTIONS[0].label));
+  expect(await screen.findByLabelText('stop')).toBeInTheDocument();
+});
+
+test('displays the selected values first', async () => {
+  render(<Select {...defaultProps} mode="multiple" />);
+  const option3 = OPTIONS[2].label;
+  const option8 = OPTIONS[7].label;
+  await open();
+  userEvent.click(await findSelectOption(option3));
+  userEvent.click(await findSelectOption(option8));
+  await type('{esc}');
+  await open();
+  const sortedOptions = await findAllSelectOptions();
+  expect(sortedOptions[0]).toHaveTextContent(option3);
+  expect(sortedOptions[1]).toHaveTextContent(option8);
+});
+
+test('searches for label or value', async () => {
+  const option = OPTIONS[11];
+  render(<Select {...defaultProps} />);
+  const search = option.value;
+  await type(search.toString());
+  const options = await findAllSelectOptions();
+  expect(options.length).toBe(1);
+  expect(options[0]).toHaveTextContent(option.label);
+});
+
+test('clear all the values', async () => {
+  const onClear = jest.fn();
+  render(
+    <Select
+      {...defaultProps}
+      mode="multiple"
+      value={[OPTIONS[0], OPTIONS[1]]}
+      onClear={onClear}
+    />,
+  );
+  userEvent.click(screen.getByLabelText('close-circle'));
+  expect(onClear).toHaveBeenCalled();
+  const values = await findAllSelectValues();
+  expect(values.length).toBe(0);
+});
+
+test('does not add a new option if allowNewValue is false', async () => {
+  render(<Select {...defaultProps} options={loadOptions} />);
+  await open();
+  await type(NEW_OPTION);
+  expect(await screen.findByText(NO_DATA)).toBeInTheDocument();
+});
+
+test('static - renders the select with default props', () => {
+  render(<Select {...defaultProps} />);
+  expect(getSelect()).toBeInTheDocument();
+});
+
+test('static - opens the select without any data', async () => {
+  render(<Select {...defaultProps} options={[]} />);
+  await open();
+  expect(screen.getByText(NO_DATA)).toBeInTheDocument();
+});
+
+test('static - makes a selection in single mode', async () => {
+  render(<Select {...defaultProps} />);
+  const optionText = 'Emma';
+  await open();
+  userEvent.click(await findSelectOption(optionText));
+  expect(await findSelectValue()).toHaveTextContent(optionText);
+});
+
+test('static - multiple selections in multiple mode', async () => {
+  render(<Select {...defaultProps} mode="multiple" />);
+  await open();
+  const firstOption = OPTIONS[0];
+  const secondOption = OPTIONS[1];

Review comment:
       nit: some of these might look nicer by doing the ol'
   ```suggestion
     const [firstOption, secondOption] = OPTIONS;
   ```




-- 
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: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org