This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch replace-jest-enzyme
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/replace-jest-enzyme by this
push:
new 4f935f23d0 breaking up monolithic tests
4f935f23d0 is described below
commit 4f935f23d09e98ebccec2a82014c97ad5eee6696
Author: Evan Rusackas <[email protected]>
AuthorDate: Fri Feb 7 15:59:43 2025 -0700
breaking up monolithic tests
---
.../FilterScope/FilterScope.test.tsx | 181 +--------------------
.../__tests__/TreeInitialization.test.tsx | 80 +++++++++
.../FilterScope/__tests__/TreeSelection.test.tsx | 124 ++++++++++++++
.../FilterScope/__tests__/utils.tsx | 84 ++++++++++
4 files changed, 290 insertions(+), 179 deletions(-)
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.test.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.test.tsx
index c37153993e..918eea9a48 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.test.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.test.tsx
@@ -16,183 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Provider } from 'react-redux';
-import {
- render,
- screen,
- fireEvent,
- waitFor,
- cleanup,
-} from 'spec/helpers/testing-library';
-import { mockStoreWithChartsInTabsAndRoot } from 'spec/fixtures/mockStore';
-import { AntdForm, FormInstance } from 'src/components';
-import { NativeFiltersForm } from
'src/dashboard/components/nativeFilters/FiltersConfigModal/types';
-import FiltersConfigForm, {
- FilterPanels,
-} from
'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm';
-describe('FilterScope', () => {
- const save = jest.fn();
- let form: FormInstance<NativeFiltersForm>;
- const mockedProps = {
- expanded: false,
- filterId: 'DefaultFilterId',
- dependencies: [],
- setErroredFilters: jest.fn(),
- restoreFilter: jest.fn(),
- getAvailableFilters: () => [],
- getDependencySuggestion: () => '',
- save,
- removedFilters: {},
- handleActiveFilterPanelChange: jest.fn(),
- activeFilterPanelKeys: `DefaultFilterId-${FilterPanels.configuration.key}`,
- isActive: true,
- validateDependencies: jest.fn(),
- onModifyFilter: jest.fn(),
- };
-
- const MockModal = ({ scope }: { scope?: object }) => {
- const [newForm] = AntdForm.useForm<NativeFiltersForm>();
- form = newForm;
- if (scope) {
- form.setFieldsValue({
- filters: {
- [mockedProps.filterId]: {
- scope,
- },
- },
- });
- }
- return (
- <Provider store={mockStoreWithChartsInTabsAndRoot}>
- <AntdForm form={form}>
- <FiltersConfigForm form={form} {...mockedProps} />
- </AntdForm>
- </Provider>
- );
- };
-
- const getTreeSwitcher = (order = 0) =>
- document.querySelectorAll('.ant-tree-switcher')[order];
-
- beforeAll(() => {
- // Reduce the global timeout
- jest.setTimeout(10000);
- });
-
- beforeEach(() => {
- // Add this to speed up animations/transitions
- jest.useFakeTimers();
- });
-
- afterEach(() => {
- cleanup();
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
- });
-
- it('select tree values with 1 excluded', async () => {
- const { unmount } = render(<MockModal />);
-
- // First, wait for and click the Scoping tab
- const scopingTab = await screen.findByRole('tab', { name: 'Scoping' });
- fireEvent.click(scopingTab);
-
- // Wait for tree to be rendered after tab switch
- await waitFor(
- () => {
- expect(screen.getByRole('tree')).toBeInTheDocument();
- expect(
- document.querySelector('.ant-tree-treenode'),
- ).toBeInTheDocument();
- },
- { timeout: 3000 },
- );
-
- // Continue with tree interactions
- fireEvent.click(getTreeSwitcher(2));
-
- const chartNode = await screen.findByText('CHART_ID2');
- fireEvent.click(chartNode);
-
- // Check form values
- await waitFor(
- () =>
- expect(
- form.getFieldValue('filters')?.[mockedProps.filterId].scope,
- ).toEqual({
- excluded: [20],
- rootPath: ['ROOT_ID'],
- }),
- { timeout: 3000 },
- );
-
- unmount();
- }, 5000);
-
- it('select 1 value only', async () => {
- const { unmount } = render(<MockModal />);
-
- // First, wait for and click the Scoping tab
- const scopingTab = await screen.findByRole('tab', { name: 'Scoping' });
- fireEvent.click(scopingTab);
-
- // Wait for tree to be rendered
- await waitFor(
- () => {
- expect(screen.getByRole('tree')).toBeInTheDocument();
- },
- { timeout: 3000 },
- );
-
- // Perform tree interactions
- fireEvent.click(getTreeSwitcher(2));
-
- const chartNode = await screen.findByText('CHART_ID2');
- fireEvent.click(chartNode);
-
- const tabNode = await screen.findByText('tab1');
- fireEvent.click(tabNode);
-
- // Update expected state to include both excluded IDs
- await waitFor(
- () =>
- expect(
- form.getFieldValue('filters')?.[mockedProps.filterId].scope,
- ).toEqual({
- excluded: [18, 20],
- rootPath: ['ROOT_ID'],
- }),
- { timeout: 3000 },
- );
-
- unmount();
- }, 5000);
-
- it('correct init tree with values', async () => {
- const { unmount } = render(
- <MockModal
- scope={{
- rootPath: ['TAB_ID'],
- excluded: [],
- }}
- />,
- );
-
- await waitFor(() => {
- fireEvent.click(screen.getByText('Scoping'));
- });
-
- await waitFor(
- () => {
- expect(screen.getByRole('tree')).toBeInTheDocument();
- expect(
- document.querySelectorAll('.ant-tree-checkbox-checked').length,
- ).toBe(4);
- },
- { timeout: 10000 },
- );
-
- unmount();
- }, 15000);
-});
+import './__tests__/TreeSelection.test';
+import './__tests__/TreeInitialization.test';
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeInitialization.test.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeInitialization.test.tsx
new file mode 100644
index 0000000000..fe89ac1e67
--- /dev/null
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeInitialization.test.tsx
@@ -0,0 +1,80 @@
+/**
+ * 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,
+ fireEvent,
+ waitFor,
+ cleanup,
+} from 'spec/helpers/testing-library';
+import { createMockModal } from './utils';
+import { FormInstance } from 'antd/lib/form';
+
+describe('FilterScope TreeInitialization', () => {
+ let formRef: { current: FormInstance | null };
+
+ beforeEach(() => {
+ jest.useFakeTimers();
+ formRef = { current: null };
+ });
+
+ afterEach(() => {
+ cleanup();
+ jest.runOnlyPendingTimers();
+ jest.useRealTimers();
+ });
+
+ it('correct init tree with values', async () => {
+ const { MockModalComponent } = createMockModal({
+ scope: {
+ rootPath: ['TAB_ID'],
+ excluded: [],
+ },
+ formRef,
+ });
+
+ const modal = render(<MockModalComponent />);
+
+ const scopingTab = await screen.findByRole('tab', { name: 'Scoping' });
+ fireEvent.click(scopingTab);
+
+ jest.runAllTimers();
+
+ await waitFor(
+ () => {
+ expect(screen.getByRole('tree')).toBeInTheDocument();
+ },
+ { timeout: 10000 },
+ );
+
+ jest.runAllTimers();
+
+ await waitFor(
+ () => {
+ const checkedNodes = document.querySelectorAll(
+ '.ant-tree-checkbox-checked',
+ );
+ expect(checkedNodes.length).toBe(1);
+ },
+ { timeout: 10000 },
+ );
+
+ modal.unmount();
+ }, 30000);
+});
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeSelection.test.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeSelection.test.tsx
new file mode 100644
index 0000000000..0d1e8e6535
--- /dev/null
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/TreeSelection.test.tsx
@@ -0,0 +1,124 @@
+/**
+ * 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,
+ fireEvent,
+ waitFor,
+ cleanup,
+} from 'spec/helpers/testing-library';
+import { FormInstance } from 'antd/lib/form';
+import { createMockModal, getTreeSwitcher } from './utils';
+
+describe('FilterScope TreeSelection', () => {
+ let formRef: { current: FormInstance | null };
+
+ beforeEach(() => {
+ jest.useFakeTimers();
+ formRef = { current: null };
+ });
+
+ afterEach(() => {
+ cleanup();
+ jest.runOnlyPendingTimers();
+ jest.useRealTimers();
+ });
+
+ it('select tree values with 1 excluded', async () => {
+ const { MockModalComponent } = createMockModal({ formRef });
+ const modal = render(<MockModalComponent />);
+
+ const scopingTab = await screen.findByRole('tab', { name: 'Scoping' });
+ fireEvent.click(scopingTab);
+
+ await waitFor(
+ () => {
+ expect(screen.getByRole('tree')).toBeInTheDocument();
+ expect(
+ document.querySelector('.ant-tree-treenode'),
+ ).toBeInTheDocument();
+ },
+ { timeout: 3000 },
+ );
+
+ fireEvent.click(getTreeSwitcher(2));
+
+ const chartNode = await screen.findByText('CHART_ID2');
+ fireEvent.click(chartNode);
+
+ await waitFor(
+ () => {
+ expect(formRef.current).toBeTruthy();
+ const scope = formRef.current?.getFieldValue([
+ 'filters',
+ 'DefaultFilterId',
+ 'scope',
+ ]);
+ expect(scope).toEqual({
+ excluded: [20],
+ rootPath: ['ROOT_ID'],
+ });
+ },
+ { timeout: 3000 },
+ );
+
+ modal.unmount();
+ });
+
+ it('select 1 value only', async () => {
+ const { MockModalComponent } = createMockModal({ formRef });
+ const modal = render(<MockModalComponent />);
+
+ const scopingTab = await screen.findByRole('tab', { name: 'Scoping' });
+ fireEvent.click(scopingTab);
+
+ await waitFor(
+ () => {
+ expect(screen.getByRole('tree')).toBeInTheDocument();
+ },
+ { timeout: 3000 },
+ );
+
+ fireEvent.click(getTreeSwitcher(2));
+
+ const chartNode = await screen.findByText('CHART_ID2');
+ fireEvent.click(chartNode);
+
+ const tabNode = await screen.findByText('tab1');
+ fireEvent.click(tabNode);
+
+ await waitFor(
+ () => {
+ expect(formRef.current).toBeTruthy();
+ const scope = formRef.current?.getFieldValue([
+ 'filters',
+ 'DefaultFilterId',
+ 'scope',
+ ]);
+ expect(scope).toEqual({
+ excluded: [18, 20],
+ rootPath: ['ROOT_ID'],
+ });
+ },
+ { timeout: 3000 },
+ );
+
+ modal.unmount();
+ });
+});
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/utils.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/utils.tsx
new file mode 100644
index 0000000000..311f8c791d
--- /dev/null
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/__tests__/utils.tsx
@@ -0,0 +1,84 @@
+/**
+ * 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 { Provider } from 'react-redux';
+import { AntdForm, FormInstance } from 'src/components';
+import FiltersConfigForm, {
+ FilterPanels,
+} from
'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm';
+import { mockStoreWithChartsInTabsAndRoot } from 'spec/fixtures/mockStore';
+
+export const createMockedProps = () => ({
+ expanded: false,
+ filterId: 'DefaultFilterId',
+ dependencies: [],
+ setErroredFilters: jest.fn(),
+ restoreFilter: jest.fn(),
+ getAvailableFilters: () => [],
+ getDependencySuggestion: () => '',
+ save: jest.fn(),
+ removedFilters: {},
+ handleActiveFilterPanelChange: jest.fn(),
+ activeFilterPanelKeys: `DefaultFilterId-${FilterPanels.configuration.key}`,
+ isActive: true,
+ validateDependencies: jest.fn(),
+ onModifyFilter: jest.fn(),
+});
+
+interface MockModalProps {
+ scope?: object;
+ formRef: { current: FormInstance | null };
+}
+
+export const createMockModal = ({ scope, formRef }: MockModalProps) => {
+ const MockModalComponent = () => {
+ const [form] = AntdForm.useForm();
+
+ React.useEffect(() => {
+ // Create a new ref object instead of modifying the parameter
+ const currentForm = form;
+ Object.defineProperty(formRef, 'current', {
+ value: currentForm,
+ writable: true,
+ });
+
+ if (scope) {
+ currentForm.setFieldsValue({
+ filters: {
+ [createMockedProps().filterId]: {
+ scope,
+ },
+ },
+ });
+ }
+ }, [form]); // Add form to dependency array
+
+ return (
+ <Provider store={mockStoreWithChartsInTabsAndRoot}>
+ <AntdForm form={form}>
+ <FiltersConfigForm form={form} {...createMockedProps()} />
+ </AntdForm>
+ </Provider>
+ );
+ };
+
+ return { MockModalComponent };
+};
+
+export const getTreeSwitcher = (order = 0) =>
+ document.querySelectorAll('.ant-tree-switcher')[order];