diff --git a/superset-frontend/src/components/ListView/ListView.test.jsx b/superset-frontend/src/components/ListView/ListView.test.jsx
deleted file mode 100644
index 4045c4b85cc..00000000000
--- a/superset-frontend/src/components/ListView/ListView.test.jsx
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { render, screen, within, waitFor } from 'spec/helpers/testing-library';
-import userEvent from '@testing-library/user-event';
-import { QueryParamProvider } from 'use-query-params';
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-
-// Only import components that are directly referenced in tests
-import { ListView } from './ListView';
-
-const middlewares = [thunk];
-const mockStore = configureStore(middlewares);
-
-function makeMockLocation(query) {
- const queryStr = encodeURIComponent(query);
- return {
- protocol: 'http:',
- host: 'localhost',
- pathname: '/',
- search: queryStr.length ? `?${queryStr}` : '',
- };
-}
-
-const fetchSelectsMock = jest.fn(() => []);
-const mockedProps = {
- title: 'Data Table',
- columns: [
- {
- accessor: 'id',
- Header: 'ID',
- sortable: true,
- id: 'id',
- },
- {
- accessor: 'age',
- Header: 'Age',
- id: 'age',
- },
- {
- accessor: 'name',
- Header: 'Name',
- id: 'name',
- },
- {
- accessor: 'time',
- Header: 'Time',
- id: 'time',
- },
- ],
- filters: [
- {
- Header: 'ID',
- id: 'id',
- input: 'select',
- selects: [{ label: 'foo', value: 'bar' }],
- operator: 'eq',
- },
- {
- Header: 'Name',
- id: 'name',
- input: 'search',
- operator: 'ct',
- },
- {
- Header: 'Age',
- id: 'age',
- input: 'select',
- fetchSelects: fetchSelectsMock,
- paginate: true,
- operator: 'eq',
- },
- {
- Header: 'Time',
- id: 'time',
- input: 'datetime_range',
- operator: 'between',
- },
- ],
- data: [
- { id: 1, name: 'data 1', age: 10, time: '2020-11-18T07:53:45.354Z' },
- { id: 2, name: 'data 2', age: 1, time: '2020-11-18T07:53:45.354Z' },
- ],
- count: 2,
- pageSize: 1,
- fetchData: jest.fn(() => []),
- loading: false,
- bulkSelectEnabled: true,
- disableBulkSelect: jest.fn(),
- bulkActions: [
- {
- key: 'something',
- name: 'do something',
- style: 'danger',
- onSelect: jest.fn(),
- },
- ],
- cardSortSelectOptions: [
- {
- desc: false,
- id: 'something',
- label: 'Alphabetical',
- value: 'alphabetical',
- },
- ],
-};
-
-const factory = (props = mockedProps) =>
- render(
-
-
- ,
- { store: mockStore() },
- );
-
-// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
-describe('ListView', () => {
- beforeEach(() => {
- fetchMock.reset();
- jest.clearAllMocks();
- factory();
- });
-
- afterEach(() => {
- fetchMock.reset();
- mockedProps.fetchData.mockClear();
- mockedProps.bulkActions.forEach(ba => {
- ba.onSelect.mockClear();
- });
- });
-
- // Example of converted test:
- test('calls fetchData on mount', () => {
- expect(mockedProps.fetchData).toHaveBeenCalledWith({
- filters: [],
- pageIndex: 0,
- pageSize: 1,
- sortBy: [],
- });
- });
-
- test('calls fetchData on sort', async () => {
- const sortHeader = screen.getAllByTestId('sort-header')[1];
- await userEvent.click(sortHeader);
-
- expect(mockedProps.fetchData).toHaveBeenCalledWith({
- filters: [],
- pageIndex: 0,
- pageSize: 1,
- sortBy: [
- {
- desc: false,
- id: 'id',
- },
- ],
- });
- });
-
- // Update pagination control tests for Ant Design pagination
- test('renders pagination controls', () => {
- const paginationList = screen.getByRole('list');
- expect(paginationList).toBeInTheDocument();
-
- const pageOneItem = screen.getByRole('listitem', { name: '1' });
- expect(pageOneItem).toBeInTheDocument();
- });
-
- test('calls fetchData on page change', async () => {
- const pageTwoItem = screen.getByRole('listitem', { name: '2' });
- await userEvent.click(pageTwoItem);
-
- await waitFor(() => {
- const { calls } = mockedProps.fetchData.mock;
- const pageChangeCall = calls.find(
- call =>
- call[0].pageIndex === 1 &&
- call[0].filters.length === 0 &&
- call[0].pageSize === 1,
- );
- expect(pageChangeCall).toBeDefined();
- });
- });
-
- test('handles bulk actions on 1 row', async () => {
- const checkboxes = screen.getAllByRole('checkbox');
- await userEvent.click(checkboxes[1]); // Index 1 is the first row checkbox
-
- const bulkActionButton = within(
- screen.getByTestId('bulk-select-controls'),
- ).getByTestId('bulk-select-action');
- await userEvent.click(bulkActionButton);
-
- expect(mockedProps.bulkActions[0].onSelect).toHaveBeenCalledWith([
- {
- age: 10,
- id: 1,
- name: 'data 1',
- time: '2020-11-18T07:53:45.354Z',
- },
- ]);
- });
-
- // Update UI filters test to use more specific selector
- test('renders UI filters', () => {
- const filterControls = screen.getAllByRole('combobox');
- expect(filterControls).toHaveLength(2);
- });
-
- test('calls fetchData on filter', async () => {
- // Handle select filter
- const selectFilter = screen.getAllByRole('combobox')[0];
- await userEvent.click(selectFilter);
- const option = screen.getByText('foo');
- await userEvent.click(option);
-
- // Handle search filter
- const searchFilter = screen.getByPlaceholderText('Type a value');
- await userEvent.type(searchFilter, 'something');
- await userEvent.tab();
-
- expect(mockedProps.fetchData).toHaveBeenCalledWith(
- expect.objectContaining({
- filters: [
- {
- id: 'id',
- operator: 'eq',
- value: { label: 'foo', value: 'bar' },
- },
- {
- id: 'name',
- operator: 'ct',
- value: 'something',
- },
- ],
- }),
- );
- });
-
- test('calls fetchData on card view sort', async () => {
- factory({
- ...mockedProps,
- renderCard: jest.fn(),
- initialSort: [{ id: 'something' }],
- });
-
- const sortSelect = screen.getByTestId('card-sort-select');
- await userEvent.click(sortSelect);
-
- const sortOption = screen.getByText('Alphabetical');
- await userEvent.click(sortOption);
-
- expect(mockedProps.fetchData).toHaveBeenCalled();
- });
-});
diff --git a/superset-frontend/src/components/ListView/ListView.test.tsx b/superset-frontend/src/components/ListView/ListView.test.tsx
index f40dc229fbc..9d55ec1ad84 100644
--- a/superset-frontend/src/components/ListView/ListView.test.tsx
+++ b/superset-frontend/src/components/ListView/ListView.test.tsx
@@ -16,11 +16,146 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { render, waitFor } from 'spec/helpers/testing-library';
-import { ListView } from './ListView';
+import { render, screen, within, waitFor } from 'spec/helpers/testing-library';
+import userEvent from '@testing-library/user-event';
+import { QueryParamProvider } from 'use-query-params';
+import thunk from 'redux-thunk';
+import configureStore from 'redux-mock-store';
+import fetchMock from 'fetch-mock';
+import { ReactNode } from 'react';
+import { ListView, type ListViewProps } from './ListView';
+import { ListViewFilterOperator, type ListViewFetchDataConfig } from './types';
-const mockedProps = {
- title: 'Data Table',
+// Test-specific type that properly represents mocked props
+type MockedListViewProps = Omit<
+ ListViewProps,
+ | 'fetchData'
+ | 'refreshData'
+ | 'addSuccessToast'
+ | 'addDangerToast'
+ | 'disableBulkSelect'
+ | 'bulkActions'
+> & {
+ fetchData: jest.Mock;
+ refreshData: jest.Mock;
+ addSuccessToast: jest.Mock;
+ addDangerToast: jest.Mock;
+ disableBulkSelect: jest.Mock;
+ bulkActions: Array<{
+ key: string;
+ name: ReactNode;
+ onSelect: jest.Mock;
+ type?: 'primary' | 'secondary' | 'danger';
+ }>;
+};
+
+const middlewares = [thunk];
+const mockStore = configureStore(middlewares);
+
+function makeMockLocation(query?: string) {
+ const queryStr = query ? encodeURIComponent(query) : '';
+ return {
+ protocol: 'http:',
+ host: 'localhost',
+ pathname: '/',
+ search: queryStr.length ? `?${queryStr}` : '',
+ } as Location;
+}
+
+const fetchSelectsMock = jest.fn(() =>
+ Promise.resolve({ data: [], totalCount: 0 }),
+);
+
+// Create a properly typed mock with all required fields and Jest mock types
+const mockedPropsComprehensive: MockedListViewProps = {
+ columns: [
+ {
+ accessor: 'id',
+ Header: 'ID',
+ sortable: true,
+ id: 'id',
+ },
+ {
+ accessor: 'age',
+ Header: 'Age',
+ id: 'age',
+ },
+ {
+ accessor: 'name',
+ Header: 'Name',
+ id: 'name',
+ },
+ {
+ accessor: 'time',
+ Header: 'Time',
+ id: 'time',
+ },
+ ],
+ filters: [
+ {
+ key: 'id',
+ Header: 'ID',
+ id: 'id',
+ input: 'select',
+ selects: [{ label: 'foo', value: 'bar' }],
+ operator: ListViewFilterOperator.Equals,
+ },
+ {
+ key: 'name',
+ Header: 'Name',
+ id: 'name',
+ input: 'search',
+ operator: ListViewFilterOperator.Contains,
+ },
+ {
+ key: 'age',
+ Header: 'Age',
+ id: 'age',
+ input: 'select',
+ fetchSelects: fetchSelectsMock,
+ paginate: true,
+ operator: ListViewFilterOperator.Equals,
+ },
+ {
+ key: 'time',
+ Header: 'Time',
+ id: 'time',
+ input: 'datetime_range',
+ operator: ListViewFilterOperator.Between,
+ },
+ ],
+ data: [
+ { id: 1, name: 'data 1', age: 10, time: '2020-11-18T07:53:45.354Z' },
+ { id: 2, name: 'data 2', age: 1, time: '2020-11-18T07:53:45.354Z' },
+ ],
+ count: 2,
+ pageSize: 1,
+ fetchData: jest.fn(() => []),
+ loading: false,
+ refreshData: jest.fn(),
+ addSuccessToast: jest.fn(),
+ addDangerToast: jest.fn(),
+ bulkSelectEnabled: true,
+ disableBulkSelect: jest.fn(),
+ bulkActions: [
+ {
+ key: 'something',
+ name: 'do something',
+ type: 'danger',
+ onSelect: jest.fn(),
+ },
+ ],
+ cardSortSelectOptions: [
+ {
+ desc: false,
+ id: 'something',
+ label: 'Alphabetical',
+ value: 'alphabetical',
+ },
+ ],
+};
+
+const mockedPropsSimple = {
columns: [
{
accessor: 'id',
@@ -59,7 +194,7 @@ const mockedProps = {
test('redirects to first page when page index is invalid', async () => {
const fetchData = jest.fn();
window.history.pushState({}, '', '/?pageIndex=9');
- render(, {
+ render(, {
useRouter: true,
useQueryParams: true,
});
@@ -75,3 +210,152 @@ test('redirects to first page when page index is invalid', async () => {
});
fetchData.mockClear();
});
+
+// Comprehensive test suite from original JSX file
+const factory = (overrides?: Partial) => {
+ const props = { ...mockedPropsComprehensive, ...overrides };
+ return render(
+
+
+ ,
+ { store: mockStore() },
+ );
+};
+
+// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
+describe('ListView', () => {
+ beforeEach(() => {
+ fetchMock.reset();
+ jest.clearAllMocks();
+ factory();
+ });
+
+ afterEach(() => {
+ fetchMock.reset();
+ mockedPropsComprehensive.fetchData.mockClear();
+ mockedPropsComprehensive.bulkActions.forEach(ba => {
+ ba.onSelect.mockClear();
+ });
+ });
+
+ test('calls fetchData on mount', () => {
+ expect(mockedPropsComprehensive.fetchData).toHaveBeenCalledWith({
+ filters: [],
+ pageIndex: 0,
+ pageSize: 1,
+ sortBy: [],
+ });
+ });
+
+ test('calls fetchData on sort', async () => {
+ const sortHeader = screen.getAllByTestId('sort-header')[1];
+ await userEvent.click(sortHeader);
+
+ expect(mockedPropsComprehensive.fetchData).toHaveBeenCalledWith({
+ filters: [],
+ pageIndex: 0,
+ pageSize: 1,
+ sortBy: [
+ {
+ desc: false,
+ id: 'id',
+ },
+ ],
+ });
+ });
+
+ test('renders pagination controls', () => {
+ const paginationList = screen.getByRole('list');
+ expect(paginationList).toBeInTheDocument();
+
+ const pageOneItem = screen.getByRole('listitem', { name: '1' });
+ expect(pageOneItem).toBeInTheDocument();
+ });
+
+ test('calls fetchData on page change', async () => {
+ const pageTwoItem = screen.getByRole('listitem', { name: '2' });
+ await userEvent.click(pageTwoItem);
+
+ await waitFor(() => {
+ const { calls } = mockedPropsComprehensive.fetchData.mock;
+ const pageChangeCall = calls.find(
+ (call: [ListViewFetchDataConfig]) =>
+ call?.[0]?.pageIndex === 1 &&
+ call?.[0]?.filters?.length === 0 &&
+ call?.[0]?.pageSize === 1,
+ );
+ expect(pageChangeCall).toBeDefined();
+ });
+ });
+
+ test('handles bulk actions on 1 row', async () => {
+ const checkboxes = screen.getAllByRole('checkbox');
+ await userEvent.click(checkboxes[1]); // Index 1 is the first row checkbox
+
+ const bulkActionButton = within(
+ screen.getByTestId('bulk-select-controls'),
+ ).getByTestId('bulk-select-action');
+ await userEvent.click(bulkActionButton);
+
+ expect(
+ mockedPropsComprehensive.bulkActions[0].onSelect,
+ ).toHaveBeenCalledWith([
+ {
+ age: 10,
+ id: 1,
+ name: 'data 1',
+ time: '2020-11-18T07:53:45.354Z',
+ },
+ ]);
+ });
+
+ test('renders UI filters', () => {
+ const filterControls = screen.getAllByRole('combobox');
+ expect(filterControls).toHaveLength(2);
+ });
+
+ test('calls fetchData on filter', async () => {
+ // Handle select filter
+ const selectFilter = screen.getAllByRole('combobox')[0];
+ await userEvent.click(selectFilter);
+ const option = screen.getByText('foo');
+ await userEvent.click(option);
+
+ // Handle search filter
+ const searchFilter = screen.getByPlaceholderText('Type a value');
+ await userEvent.type(searchFilter, 'something');
+ await userEvent.tab();
+
+ expect(mockedPropsComprehensive.fetchData).toHaveBeenCalledWith(
+ expect.objectContaining({
+ filters: [
+ {
+ id: 'id',
+ operator: 'eq',
+ value: { label: 'foo', value: 'bar' },
+ },
+ {
+ id: 'name',
+ operator: 'ct',
+ value: 'something',
+ },
+ ],
+ }),
+ );
+ });
+
+ test('calls fetchData on card view sort', async () => {
+ factory({
+ renderCard: jest.fn(),
+ initialSort: [{ id: 'something' }],
+ });
+
+ const sortSelect = screen.getByTestId('card-sort-select');
+ await userEvent.click(sortSelect);
+
+ const sortOption = screen.getByText('Alphabetical');
+ await userEvent.click(sortOption);
+
+ expect(mockedPropsComprehensive.fetchData).toHaveBeenCalled();
+ });
+});
diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx
deleted file mode 100644
index 8f6b520cab8..00000000000
--- a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import configureStore from 'redux-mock-store';
-import { DatasourceType } from '@superset-ui/core';
-import {
- fireEvent,
- render,
- screen,
- userEvent,
- waitFor,
-} from 'spec/helpers/testing-library';
-import DatasourceControl, {
- getDatasourceTitle,
-} from 'src/explore/components/controls/DatasourceControl';
-
-const defaultProps = {
- name: 'datasource',
- label: 'Dataset',
- value: '1__table',
- datasource: {
- name: 'birth_names',
- type: 'table',
- uid: '1__table',
- id: 1,
- columns: [],
- metrics: [],
- owners: [{ username: 'admin', userId: 1 }],
- database: {
- backend: 'mysql',
- name: 'main',
- },
- health_check_message: 'Warning message!',
- },
- actions: {
- setDatasource: jest.fn(),
- },
- onChange: jest.fn(),
- user: {
- createdOn: '2021-04-27T18:12:38.952304',
- email: 'admin',
- firstName: 'admin',
- isActive: true,
- lastName: 'admin',
- permissions: {},
- roles: { Admin: Array(173) },
- userId: 1,
- username: 'admin',
- },
-};
-
-// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
-describe('DatasourceControl', () => {
- const setup = (overrideProps = {}) => {
- const mockStore = configureStore([]);
- const store = mockStore({});
- const props = {
- ...defaultProps,
- ...overrideProps,
- };
- return {
- rendered: render(, {
- useRedux: true,
- useRouter: true,
- store,
- }),
- store,
- props,
- };
- };
-
- test('should not render Modal', () => {
- setup();
- expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
- });
-
- test('should not render ChangeDatasourceModal', () => {
- setup();
- expect(screen.queryByTestId('Swap dataset-modal')).not.toBeInTheDocument();
- });
-
- test('show or hide Edit Datasource option', async () => {
- const {
- rendered: { container, rerender },
- store,
- props,
- } = setup();
- expect(
- container.querySelector('[data-test="datasource-menu-trigger"]'),
- ).toBeInTheDocument();
- userEvent.click(screen.getByLabelText('more'));
- await waitFor(() => {
- expect(screen.queryAllByRole('menuitem')).toHaveLength(3);
- });
-
- // Close the menu
- userEvent.click(document.body);
- await waitFor(() => {
- expect(screen.queryAllByRole('menuitem')).toHaveLength(0);
- });
-
- rerender(, {
- useRedux: true,
- useRouter: true,
- store,
- });
- expect(
- container.querySelector('[data-test="datasource-menu-trigger"]'),
- ).toBeInTheDocument();
- userEvent.click(screen.getByLabelText('more'));
- await waitFor(() => {
- expect(screen.queryAllByRole('menuitem')).toHaveLength(2);
- });
- });
-
- test('should render health check message', async () => {
- setup();
- const modalTrigger = screen.getByLabelText('warning');
- expect(modalTrigger).toBeInTheDocument();
-
- // Hover the modal so healthcheck message can show up
- fireEvent.mouseOver(modalTrigger);
- await waitFor(() => {
- expect(
- screen.getByText(defaultProps.datasource.health_check_message),
- ).toBeInTheDocument();
- });
- });
-
- test('Gets Datasource Title', () => {
- const sql = 'This is the sql';
- const name = 'this is a name';
- const emptyResult = '';
- const queryDatasource1 = { type: DatasourceType.Query, sql };
- let displayText = getDatasourceTitle(queryDatasource1);
- expect(displayText).toBe(sql);
- const queryDatasource2 = { type: DatasourceType.Query, sql: null };
- displayText = getDatasourceTitle(queryDatasource2);
- expect(displayText).toBe(null);
- const queryDatasource3 = { type: 'random type', name };
- displayText = getDatasourceTitle(queryDatasource3);
- expect(displayText).toBe(name);
- const queryDatasource4 = { type: 'random type' };
- displayText = getDatasourceTitle(queryDatasource4);
- expect(displayText).toBe(emptyResult);
- displayText = getDatasourceTitle();
- expect(displayText).toBe(emptyResult);
- displayText = getDatasourceTitle(null);
- expect(displayText).toBe(emptyResult);
- displayText = getDatasourceTitle('I should not be a string');
- expect(displayText).toBe(emptyResult);
- displayText = getDatasourceTitle([]);
- expect(displayText).toBe(emptyResult);
- });
-});
diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.jsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.jsx
deleted file mode 100644
index 1b4d43eb9c7..00000000000
--- a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.jsx
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import sinon from 'sinon';
-import { getChartMetadataRegistry, ChartMetadata } from '@superset-ui/core';
-import {
- act,
- cleanup,
- render,
- screen,
- userEvent,
-} from 'spec/helpers/testing-library';
-import VizTypeControl from 'src/explore/components/controls/VizTypeControl';
-import { DynamicPluginProvider } from 'src/components';
-
-const defaultProps = {
- name: 'viz_type',
- label: 'Visualization Type',
- value: 'vis1',
- onChange: sinon.spy(),
- isModalOpenInit: true,
-};
-
-/**
- * AntD and/or the Icon component seems to be doing some kind of async changes,
- * so even though the test passes, there is a warning an update to Icon was not
- * wrapped in act(). This sufficiently act-ifies whatever side effects are going
- * on and prevents those warnings.
- */
-const waitForEffects = () =>
- act(() => new Promise(resolve => setTimeout(resolve, 0)));
-
-// Increase global timeout
-jest.setTimeout(60000);
-
-// Add cleanup after each test
-afterEach(async () => {
- cleanup();
- // Wait for any pending effects to complete
- await new Promise(resolve => setTimeout(resolve, 0));
-});
-
-// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
-describe('VizTypeControl', () => {
- const registry = getChartMetadataRegistry();
- registry
- .registerValue(
- 'vis1',
- new ChartMetadata({
- name: 'vis1',
- thumbnail: '',
- tags: ['Featured'],
- }),
- )
- .registerValue(
- 'vis2',
- new ChartMetadata({
- name: 'vis2',
- thumbnail: '',
- tags: ['foobar'],
- }),
- );
-
- beforeEach(async () => {
- render(
-
-
- ,
- { useRedux: true },
- );
- await waitForEffects();
- }, 30000); // Increase beforeEach timeout
-
- test('calls onChange when submitted', async () => {
- const thumbnail = await screen.findByTestId('viztype-selector-container', {
- timeout: 15000,
- });
- const submit = await screen.findByText('Select', { timeout: 15000 });
-
- await act(async () => {
- userEvent.click(thumbnail);
- await waitForEffects();
- });
-
- expect(defaultProps.onChange.called).toBe(false);
-
- await act(async () => {
- userEvent.click(submit);
- await waitForEffects();
- });
-
- expect(defaultProps.onChange.called).toBe(true);
- }, 30000);
-
- test('filters images based on text input', async () => {
- const thumbnails = await screen.findByTestId('viztype-selector-container', {
- timeout: 15000,
- });
- expect(thumbnails).toBeInTheDocument();
-
- const searchInput = await screen.findByPlaceholderText(
- 'Search all charts',
- { timeout: 15000 },
- );
-
- await act(async () => {
- userEvent.type(searchInput, 'foo');
- await waitForEffects();
- });
-
- const thumbnail = await screen.findByTestId('viztype-selector-container', {
- timeout: 15000,
- });
- expect(thumbnail).toBeInTheDocument();
- }, 30000);
-});