michael-s-molina commented on a change in pull request #15017:
URL: https://github.com/apache/superset/pull/15017#discussion_r649066085
##########
File path:
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx
##########
@@ -17,198 +17,289 @@
* under the License.
*/
import { Preset } from '@superset-ui/core';
-import { SelectFilterPlugin, TimeFilterPlugin } from 'src/filters/components';
-import { render, cleanup, screen } from 'spec/helpers/testing-library';
-import { Provider } from 'react-redux';
import {
- getMockStore,
- mockStore,
- stateWithoutNativeFilters,
-} from 'spec/fixtures/mockStore';
+ SelectFilterPlugin,
+ RangeFilterPlugin,
+ TimeFilterPlugin,
+ TimeColumnFilterPlugin,
+ TimeGrainFilterPlugin,
+} from 'src/filters/components';
+import { render, screen, waitFor } from 'spec/helpers/testing-library';
import fetchMock from 'fetch-mock';
import React from 'react';
-import userEvent from '@testing-library/user-event';
-import { testWithId } from 'src/utils/testUtils';
-import { waitFor } from '@testing-library/react';
+import userEvent, { specialChars } from '@testing-library/user-event';
import {
- FILTERS_CONFIG_MODAL_TEST_ID,
FiltersConfigModal,
+ FiltersConfigModalProps,
} from './FiltersConfigModal';
-jest.useFakeTimers();
-
class MainPreset extends Preset {
constructor() {
super({
name: 'Legacy charts',
plugins: [
- new TimeFilterPlugin().configure({ key: 'filter_time' }),
new SelectFilterPlugin().configure({ key: 'filter_select' }),
+ new RangeFilterPlugin().configure({ key: 'filter_range' }),
+ new TimeFilterPlugin().configure({ key: 'filter_time' }),
+ new TimeColumnFilterPlugin().configure({ key: 'filter_timecolumn' }),
+ new TimeGrainFilterPlugin().configure({ key: 'filter_timegrain' }),
],
});
}
}
-const getTestId = testWithId<string>(FILTERS_CONFIG_MODAL_TEST_ID, true);
+const initialStoreState = {
+ datasources: [{ id: 1, table_name: 'Datasource 1' }],
+};
-describe('FilterConfigModal', () => {
- new MainPreset().register();
- const onSave = jest.fn();
- const newFilterProps = {
- isOpen: true,
- initialFilterId: undefined,
- createNewOnOpen: true,
- onSave,
- onCancel: jest.fn(),
- };
- fetchMock.get(
- 'glob:*/api/v1/dataset/?q=*',
- {
- count: 1,
- ids: [11],
- label_columns: {
- id: 'Id',
- table_name: 'Table Name',
- },
- list_columns: ['id', 'table_name'],
- order_columns: ['table_name'],
- result: [
- {
- id: 11,
- owners: [],
- table_name: 'birth_names',
- },
- ],
- },
- { overwriteRoutes: true },
- );
- fetchMock.get(
- 'glob:*/api/v1/dataset/11',
- {
- description_columns: {},
- id: 3,
- label_columns: {
- columns: 'Columns',
- table_name: 'Table Name',
- },
- result: {
- columns: [
- {
- column_name: 'name',
- groupby: true,
- id: 334,
- },
- ],
- table_name: 'birth_names',
+fetchMock.get('glob:*/api/v1/dataset/1', {
+ description_columns: {},
+ id: 1,
+ label_columns: {
+ columns: 'Columns',
+ table_name: 'Table Name',
+ },
+ result: {
+ metrics: [],
+ columns: [
+ {
+ column_name: 'Column A',
+ id: 1,
},
- show_columns: ['id', 'table_name'],
- },
- { overwriteRoutes: true },
- );
- fetchMock.post(
- 'glob:*/api/v1/chart/data',
+ ],
+ table_name: 'birth_names',
+ id: 1,
+ },
+ show_columns: ['id', 'table_name'],
+});
+
+fetchMock.post('glob:*/api/v1/chart/data', {
+ result: [
{
- result: [
- {
- status: 'success',
- data: [
- { name: 'Aaron', count: 453 },
- { name: 'Abigail', count: 228 },
- { name: 'Adam', count: 454 },
- ],
- applied_filters: [{ column: 'name' }],
- },
+ status: 'success',
+ data: [
+ { name: 'Aaron', count: 453 },
+ { name: 'Abigail', count: 228 },
+ { name: 'Adam', count: 454 },
],
+ applied_filters: [{ column: 'name' }],
},
- { overwriteRoutes: true },
- );
-
- const renderWrapper = (
- props = newFilterProps,
- state: object = stateWithoutNativeFilters,
- ) =>
- render(
- <Provider
- store={state ? getMockStore(stateWithoutNativeFilters) : mockStore}
- >
- <FiltersConfigModal {...props} />
- </Provider>,
- );
-
- afterEach(() => {
- cleanup();
- jest.clearAllMocks();
+ ],
+});
+
+const FILTER_TYPE_REGEX = /^filter type$/i;
+const FILTER_NAME_REGEX = /^filter name$/i;
+const DATASET_REGEX = /^dataset$/i;
+const COLUMN_REGEX = /^column$/i;
+const VALUE_REGEX = /^value$/i;
+const NUMERICAL_RANGE_REGEX = /^numerical range$/i;
+const TIME_RANGE_REGEX = /^time range$/i;
+const TIME_COLUMN_REGEX = /^time column$/i;
+const TIME_GRAIN_REGEX = /^time grain$/i;
+const ADVANCED_REGEX = /^advanced$/i;
+const DEFAULT_VALUE_REGEX = /^filter has default value$/i;
+const MULTIPLE_REGEX = /^multiple select$/i;
+const REQUIRED_REGEX = /^required$/i;
+const APPLY_INSTANTLY_REGEX = /^apply changes instantly$/i;
+const HIERARCHICAL_REGEX = /^filter is hierarchical$/i;
+const FIRST_ITEM_REGEX = /^default to first item$/i;
+const INVERSE_SELECTION_REGEX = /^inverse selection$/i;
+const SEARCH_ALL_REGEX = /^search all filter options$/i;
+const PRE_FILTER_REGEX = /^pre-filter available values$/i;
+const SORT_REGEX = /^sort filter values$/i;
+const SAVE_REGEX = /^save$/i;
+const NAME_REQUIRED_REGEX = /^name is required$/i;
+const COLUMN_REQUIRED_REGEX = /^column is required$/i;
+const DEFAULT_VALUE_REQUIRED_REGEX = /^default value is required$/i;
+const PARENT_REQUIRED_REGEX = /^parent filter is required$/i;
+const PRE_FILTER_REQUIRED_REGEX = /^pre-filter is required$/i;
+const FILL_REQUIRED_FIELDS_REGEX = /fill all required fields to enable/;
+
+const props: FiltersConfigModalProps = {
+ isOpen: true,
+ createNewOnOpen: true,
+ onSave: jest.fn(),
+ onCancel: jest.fn(),
+};
+
+beforeAll(() => {
+ new MainPreset().register();
+});
+
+function defaultRender(
+ overrides?: Partial<FiltersConfigModalProps>,
+ initialState?: {},
+) {
+ return render(<FiltersConfigModal {...props} {...overrides} />, {
+ useRedux: true,
+ initialState,
});
+}
+
+function getCheckbox(name: RegExp) {
+ return screen.getByRole('checkbox', { name });
+}
+
+function queryCheckbox(name: RegExp) {
+ return screen.queryByRole('checkbox', { name });
+}
+
+test('renders a value filter type', () => {
+ defaultRender();
+
+ userEvent.click(screen.getByText(ADVANCED_REGEX));
+
+ expect(screen.getByText(FILTER_TYPE_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(DATASET_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(COLUMN_REGEX)).toBeInTheDocument();
+
+ expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked();
+ expect(getCheckbox(REQUIRED_REGEX)).not.toBeChecked();
+ expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked();
+ expect(getCheckbox(HIERARCHICAL_REGEX)).not.toBeChecked();
+ expect(getCheckbox(FIRST_ITEM_REGEX)).not.toBeChecked();
+ expect(getCheckbox(INVERSE_SELECTION_REGEX)).not.toBeChecked();
+ expect(getCheckbox(SEARCH_ALL_REGEX)).not.toBeChecked();
+ expect(getCheckbox(PRE_FILTER_REGEX)).not.toBeChecked();
+ expect(getCheckbox(SORT_REGEX)).not.toBeChecked();
+
+ expect(getCheckbox(MULTIPLE_REGEX)).toBeChecked();
+});
+
+test('renders a numerical range filter type', () => {
+ defaultRender();
- // TODO: fix and unskip
- it.skip('Create Select Filter (with datasource and columns) with specific
filter scope', async () => {
- renderWrapper();
-
- const FILTER_NAME = 'Select Filter 1';
-
- // fill name
- userEvent.type(screen.getByTestId(getTestId('name-input')), FILTER_NAME);
-
- // fill dataset
- await waitFor(() =>
- expect(screen.queryByText('Loading...')).not.toBeInTheDocument(),
- );
- userEvent.click(
- screen
- .getByTestId(getTestId('datasource-input'))
- .querySelector('.Select__indicators')!,
- );
- userEvent.click(screen.getByText('birth_names'));
-
- // fill column
- userEvent.click(screen.getByText('Select...'));
- await waitFor(() =>
- expect(screen.queryByText('Loading...')).not.toBeInTheDocument(),
- );
- userEvent.click(screen.getByText('name'));
-
- // fill controls
- expect(screen.getByText('Multiple select').parentElement!).toHaveAttribute(
- 'class',
- 'ant-checkbox-wrapper ant-checkbox-wrapper-checked',
- );
- userEvent.click(screen.getByText('Multiple select'));
+ userEvent.click(screen.getByText(VALUE_REGEX));
+ userEvent.click(screen.getByText(NUMERICAL_RANGE_REGEX));
+ userEvent.click(screen.getByText(ADVANCED_REGEX));
+
+ expect(screen.getByText(FILTER_TYPE_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(DATASET_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(COLUMN_REGEX)).toBeInTheDocument();
+
+ expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked();
+ expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked();
+ expect(getCheckbox(PRE_FILTER_REGEX)).not.toBeChecked();
+
+ expect(queryCheckbox(MULTIPLE_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(REQUIRED_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(HIERARCHICAL_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(FIRST_ITEM_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(INVERSE_SELECTION_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(SEARCH_ALL_REGEX)).not.toBeInTheDocument();
+ expect(queryCheckbox(SORT_REGEX)).not.toBeInTheDocument();
+});
+
+test('renders a time range filter type', () => {
+ defaultRender();
+
+ userEvent.click(screen.getByText(VALUE_REGEX));
+ userEvent.click(screen.getByText(TIME_RANGE_REGEX));
+
+ expect(screen.getByText(FILTER_TYPE_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument();
+ expect(screen.queryByText(DATASET_REGEX)).not.toBeInTheDocument();
+ expect(screen.queryByText(COLUMN_REGEX)).not.toBeInTheDocument();
+
+ expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked();
+ expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked();
+
+ expect(screen.queryByText(ADVANCED_REGEX)).not.toBeInTheDocument();
+});
+
+test('renders a time column filter type', () => {
+ defaultRender();
+
+ userEvent.click(screen.getByText(VALUE_REGEX));
+ userEvent.click(screen.getByText(TIME_COLUMN_REGEX));
+
+ expect(screen.getByText(FILTER_TYPE_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(DATASET_REGEX)).toBeInTheDocument();
+ expect(screen.queryByText(COLUMN_REGEX)).not.toBeInTheDocument();
+
+ expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked();
+ expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked();
+
+ expect(screen.queryByText(ADVANCED_REGEX)).not.toBeInTheDocument();
+});
+
+test('renders a time grain filter type', () => {
+ defaultRender();
+
+ userEvent.click(screen.getByText(VALUE_REGEX));
+ userEvent.click(screen.getByText(TIME_GRAIN_REGEX));
+
+ expect(screen.getByText(FILTER_TYPE_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument();
+ expect(screen.getByText(DATASET_REGEX)).toBeInTheDocument();
+ expect(screen.queryByText(COLUMN_REGEX)).not.toBeInTheDocument();
+
+ expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked();
+ expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked();
+
+ expect(screen.queryByText(ADVANCED_REGEX)).not.toBeInTheDocument();
+});
+
+test('validates the name', async () => {
+ defaultRender();
+ userEvent.click(screen.getByRole('button', { name: SAVE_REGEX }));
+ expect(await screen.findByText(NAME_REQUIRED_REGEX)).toBeInTheDocument();
+});
+
+test('validates the column', async () => {
+ defaultRender();
+ userEvent.click(screen.getByRole('button', { name: SAVE_REGEX }));
+ expect(await screen.findByText(COLUMN_REQUIRED_REGEX)).toBeInTheDocument();
+});
+
+// eslint-disable-next-line jest/no-disabled-tests
+test.skip('validates the default value', async () => {
Review comment:
I decided to skip it and tackle it in the next iteration because it's
passing locally but failing on Github for no apparent reason.
--
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.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]