+
{name}:
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.test.tsx
new file mode 100644
index 0000000000000..b1a2638e7e004
--- /dev/null
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.test.tsx
@@ -0,0 +1,94 @@
+/**
+ * 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 React from 'react';
+import userEvent from '@testing-library/user-event';
+import { render, screen } from 'spec/helpers/testing-library';
+import Footer from './Footer';
+
+const createProps = () => ({
+ filterSetName: 'Set name',
+ disabled: false,
+ editMode: false,
+ onCancel: jest.fn(),
+ onEdit: jest.fn(),
+ onCreate: jest.fn(),
+});
+
+const editModeProps = {
+ ...createProps(),
+ editMode: true,
+};
+
+test('should render', () => {
+ const mockedProps = createProps();
+ const { container } = render(, { useRedux: true });
+ expect(container).toBeInTheDocument();
+});
+
+test('should render a button', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ expect(screen.getByRole('button')).toBeInTheDocument();
+ expect(screen.getByText('Create new filter set')).toBeInTheDocument();
+});
+
+test('should render a disabled button', () => {
+ const mockedProps = createProps();
+ const disabledProps = {
+ ...mockedProps,
+ disabled: true,
+ };
+ render(, { useRedux: true });
+ expect(screen.getByRole('button')).toBeDisabled();
+});
+
+test('should edit', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ const btn = screen.getByRole('button');
+ expect(mockedProps.onEdit).not.toHaveBeenCalled();
+ userEvent.click(btn);
+ expect(mockedProps.onEdit).toHaveBeenCalled();
+});
+
+test('should render the Create button', () => {
+ render(, { useRedux: true });
+ expect(screen.getByText('Create')).toBeInTheDocument();
+});
+
+test('should create', () => {
+ render(, { useRedux: true });
+ const createBtn = screen.getByText('Create');
+ expect(editModeProps.onCreate).not.toHaveBeenCalled();
+ userEvent.click(createBtn);
+ expect(editModeProps.onCreate).toHaveBeenCalled();
+});
+
+test('should render the Cancel button', () => {
+ render(, { useRedux: true });
+ expect(screen.getByText('Cancel')).toBeInTheDocument();
+});
+
+test('should cancel', () => {
+ render(, { useRedux: true });
+ const cancelBtn = screen.getByText('Cancel');
+ expect(editModeProps.onCancel).not.toHaveBeenCalled();
+ userEvent.click(cancelBtn);
+ expect(editModeProps.onCancel).toHaveBeenCalled();
+});
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.tsx
index f208327c05eab..5681c260a3313 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/Footer.tsx
@@ -23,7 +23,7 @@ import { Tooltip } from 'src/common/components/Tooltip';
import { APPLY_FILTERS_HINT } from './utils';
import { useFilterSetNameDuplicated } from './state';
-type FooterProps = {
+export type FooterProps = {
filterSetName: string;
disabled: boolean;
editMode: boolean;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/FilterSets.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
similarity index 99%
rename from superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/FilterSets.tsx
rename to superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
index 846790a589d56..d7dda1fa9b7d5 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/FilterSets.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
@@ -61,7 +61,7 @@ const FilterSetUnitWrapper = styled.div<{
`background: ${selected ? theme.colors.primary.light5 : 'transparent'}`};
`;
-type FilterSetsProps = {
+export type FilterSetsProps = {
disabled: boolean;
isFilterSetChanged: boolean;
dataMaskSelected: DataMaskUnit;
@@ -253,6 +253,7 @@ const FilterSets: React.FC = ({
onClick={(e: MouseEvent) =>
takeFilterSet(filterSet.id, e.target as HTMLElement)
}
+ key={filterSet.id}
>
({
+ toggleFiltersBar: jest.fn(),
+ onApply: jest.fn(),
+ setDataMaskSelected: jest.fn(),
+ dataMaskSelected: {
+ DefaultsID: {
+ currentState: {
+ value: null,
+ },
+ },
+ },
+ dataMaskApplied: {
+ DefaultsID: {
+ id: 'DefaultsID',
+ currentState: {
+ value: null,
+ },
+ },
+ },
+ isApplyDisabled: false,
+});
+
+test('should render', () => {
+ const mockedProps = createProps();
+ const { container } = render(, { useRedux: true });
+ expect(container).toBeInTheDocument();
+});
+
+test('should render the "Filters" heading', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ expect(screen.getByText('Filters')).toBeInTheDocument();
+});
+
+test('should render the "Clear all" option', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ expect(screen.getByText('Clear all')).toBeInTheDocument();
+});
+
+test('should render the "Apply" button', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ expect(screen.getByText('Apply')).toBeInTheDocument();
+ expect(screen.getByText('Apply').parentElement).toBeEnabled();
+});
+
+test('should render the "Clear all" button as disabled', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ const clearBtn = screen.getByText('Clear all');
+ expect(clearBtn.parentElement).toBeDisabled();
+});
+
+test('should render the "Apply" button as disabled', () => {
+ const mockedProps = createProps();
+ const applyDisabledProps = {
+ ...mockedProps,
+ isApplyDisabled: true,
+ };
+ render(, { useRedux: true });
+ const applyBtn = screen.getByText('Apply');
+ expect(applyBtn.parentElement).toBeDisabled();
+ userEvent.click(applyBtn);
+ expect(mockedProps.onApply).not.toHaveBeenCalled();
+});
+
+test('should apply', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ const applyBtn = screen.getByText('Apply');
+ expect(mockedProps.onApply).not.toHaveBeenCalled();
+ userEvent.click(applyBtn);
+ expect(mockedProps.onApply).toHaveBeenCalled();
+});
+
+test('should render the expand button', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ expect(screen.getByRole('button', { name: 'expand' })).toBeInTheDocument();
+});
+
+test('should toggle', () => {
+ const mockedProps = createProps();
+ render(, { useRedux: true });
+ const expandBtn = screen.getByRole('button', { name: 'expand' });
+ expect(mockedProps.toggleFiltersBar).not.toHaveBeenCalled();
+ userEvent.click(expandBtn);
+ expect(mockedProps.toggleFiltersBar).toHaveBeenCalled();
+});
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx
similarity index 93%
rename from superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header.tsx
rename to superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx
index f7d7cbad1eac9..849e1015dd739 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx
@@ -24,9 +24,9 @@ import Button from 'src/components/Button';
import { useSelector } from 'react-redux';
import { getInitialMask } from 'src/dataMask/reducer';
import { DataMaskUnit, DataMaskUnitWithId } from 'src/dataMask/types';
-import FilterConfigurationLink from './FilterConfigurationLink';
-import { useFilters } from './state';
-import { Filter } from '../types';
+import FilterConfigurationLink from 'src/dashboard/components/nativeFilters/FilterBar/FilterConfigurationLink';
+import { useFilters } from 'src/dashboard/components/nativeFilters/FilterBar/state';
+import { Filter } from 'src/dashboard/components/nativeFilters/types';
const TitleArea = styled.h4`
display: flex;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
similarity index 98%
rename from superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.tsx
rename to superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
index ef30ab80737e9..2106570742c0b 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
@@ -29,9 +29,9 @@ import { updateDataMask } from 'src/dataMask/actions';
import { DataMaskState, DataMaskUnit } from 'src/dataMask/types';
import { useImmer } from 'use-immer';
import { areObjectsEqual } from 'src/reduxUtils';
-import { Filter } from '../types';
+import { Filter } from 'src/dashboard/components/nativeFilters/types';
import { mapParentFiltersToChildren, TabIds } from './utils';
-import FilterSets from './FilterSets/FilterSets';
+import FilterSets from './FilterSets';
import {
useDataMask,
useFilters,
@@ -138,7 +138,7 @@ const StyledTabs = styled(Tabs)`
}
`;
-interface FiltersBarProps {
+export interface FiltersBarProps {
filtersOpen: boolean;
toggleFiltersBar: any;
directPathToChild?: string[];