mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
chore(native-filters): Add unit tests for filter cards (#18967)
* chore(native-filters): Add unit tests for filter cards * Fix test
This commit is contained in:
committed by
GitHub
parent
ca93d63bbb
commit
ec746c2a10
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
* 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 * as reactRedux from 'react-redux';
|
||||
import { Filter, NativeFilterType } from '@superset-ui/core';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
|
||||
import { SET_DIRECT_PATH } from 'src/dashboard/actions/dashboardState';
|
||||
import { FilterCardContent } from './FilterCardContent';
|
||||
|
||||
const baseInitialState = {
|
||||
nativeFilters: {
|
||||
filters: {
|
||||
'NATIVE_FILTER-1': {
|
||||
id: 'NATIVE_FILTER-1',
|
||||
controlValues: {},
|
||||
name: 'Native filter 1',
|
||||
filterType: 'filter_select',
|
||||
targets: [
|
||||
{
|
||||
datasetId: 1,
|
||||
column: {
|
||||
name: 'gender',
|
||||
},
|
||||
},
|
||||
],
|
||||
defaultDataMask: {},
|
||||
cascadeParentIds: [],
|
||||
scope: {
|
||||
rootPath: [DASHBOARD_ROOT_ID],
|
||||
excluded: [],
|
||||
},
|
||||
type: NativeFilterType.NATIVE_FILTER,
|
||||
description: '',
|
||||
},
|
||||
'NATIVE_FILTER-2': {
|
||||
id: 'NATIVE_FILTER-2',
|
||||
controlValues: {},
|
||||
name: 'Native filter 2',
|
||||
filterType: 'filter_select',
|
||||
targets: [
|
||||
{
|
||||
datasetId: 1,
|
||||
column: {
|
||||
name: 'gender',
|
||||
},
|
||||
},
|
||||
],
|
||||
defaultDataMask: {},
|
||||
cascadeParentIds: [],
|
||||
scope: {
|
||||
rootPath: [DASHBOARD_ROOT_ID],
|
||||
excluded: [],
|
||||
},
|
||||
type: NativeFilterType.NATIVE_FILTER,
|
||||
description: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
charts: {
|
||||
'1': {
|
||||
id: 1,
|
||||
},
|
||||
'2': {
|
||||
id: 2,
|
||||
},
|
||||
'3': {
|
||||
id: 3,
|
||||
},
|
||||
},
|
||||
dashboardLayout: {
|
||||
past: [],
|
||||
future: [],
|
||||
present: {
|
||||
ROOT_ID: {
|
||||
children: ['TABS-1'],
|
||||
id: 'ROOT_ID',
|
||||
type: 'ROOT',
|
||||
},
|
||||
|
||||
'TABS-1': {
|
||||
children: ['TAB-1', 'TAB-2'],
|
||||
id: 'TABS-1',
|
||||
meta: {},
|
||||
parents: ['ROOT_ID'],
|
||||
type: 'TABS',
|
||||
},
|
||||
'TAB-1': {
|
||||
children: [],
|
||||
id: 'TAB-1',
|
||||
meta: {
|
||||
defaultText: 'Tab title',
|
||||
placeholder: 'Tab title',
|
||||
text: 'Tab 1',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1'],
|
||||
type: 'TAB',
|
||||
},
|
||||
'TAB-2': {
|
||||
children: [],
|
||||
id: 'TAB-2',
|
||||
meta: {
|
||||
defaultText: 'Tab title',
|
||||
placeholder: 'Tab title',
|
||||
text: 'Tab 2',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1'],
|
||||
type: 'TAB',
|
||||
},
|
||||
'CHART-1': {
|
||||
children: [],
|
||||
id: 'CHART-1',
|
||||
meta: {
|
||||
chartId: 1,
|
||||
sliceName: 'Test chart',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1', 'TAB-1'],
|
||||
type: 'CHART',
|
||||
},
|
||||
'CHART-2': {
|
||||
children: [],
|
||||
id: 'CHART-2',
|
||||
meta: {
|
||||
chartId: 2,
|
||||
sliceName: 'Test chart 2',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1', 'TAB-1'],
|
||||
type: 'CHART',
|
||||
},
|
||||
'CHART-3': {
|
||||
children: [],
|
||||
id: 'CHART-3',
|
||||
meta: {
|
||||
chartId: 3,
|
||||
sliceName: 'Test chart 3',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1', 'TAB-1'],
|
||||
type: 'CHART',
|
||||
},
|
||||
'CHART-4': {
|
||||
children: [],
|
||||
id: 'CHART-4',
|
||||
meta: {
|
||||
chartId: 4,
|
||||
sliceName: 'Test chart 4',
|
||||
},
|
||||
parents: ['ROOT_ID', 'TABS-1', 'TAB-2'],
|
||||
type: 'CHART',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const baseFilter: Filter = {
|
||||
id: 'NATIVE_FILTER-1',
|
||||
controlValues: {},
|
||||
name: 'Native filter 1',
|
||||
filterType: 'filter_select',
|
||||
targets: [
|
||||
{
|
||||
datasetId: 1,
|
||||
column: {
|
||||
name: 'gender',
|
||||
},
|
||||
},
|
||||
],
|
||||
defaultDataMask: {},
|
||||
cascadeParentIds: [],
|
||||
scope: {
|
||||
rootPath: [DASHBOARD_ROOT_ID],
|
||||
excluded: [],
|
||||
},
|
||||
type: NativeFilterType.NATIVE_FILTER,
|
||||
description: '',
|
||||
};
|
||||
|
||||
jest.mock('@superset-ui/core', () => ({
|
||||
// @ts-ignore
|
||||
...jest.requireActual('@superset-ui/core'),
|
||||
getChartMetadataRegistry: () => ({
|
||||
get: (type: string) => {
|
||||
if (type === 'filter_select') {
|
||||
return { name: 'Select filter' };
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
// extract text from embedded html tags
|
||||
// source: https://polvara.me/posts/five-things-you-didnt-know-about-testing-library
|
||||
const getTextInHTMLTags =
|
||||
(target: string | RegExp) => (content: string, node: Element) => {
|
||||
const hasText = (node: Element) => node.textContent === target;
|
||||
const nodeHasText = hasText(node);
|
||||
const childrenDontHaveText = Array.from(node.children).every(
|
||||
child => !hasText(child),
|
||||
);
|
||||
|
||||
return nodeHasText && childrenDontHaveText;
|
||||
};
|
||||
|
||||
const renderContent = (filter = baseFilter, initialState = baseInitialState) =>
|
||||
render(<FilterCardContent filter={filter} />, {
|
||||
useRedux: true,
|
||||
initialState,
|
||||
});
|
||||
|
||||
describe('Filter Card', () => {
|
||||
it('Basic', () => {
|
||||
renderContent();
|
||||
expect(screen.getByText('Native filter 1')).toBeVisible();
|
||||
expect(screen.getByLabelText('filter-small')).toBeVisible();
|
||||
|
||||
expect(screen.getByText('Filter type')).toBeVisible();
|
||||
expect(screen.getByText('Select filter')).toBeVisible();
|
||||
|
||||
expect(screen.getByText('Scope')).toBeVisible();
|
||||
expect(screen.getByText('All charts')).toBeVisible();
|
||||
|
||||
expect(screen.queryByText('Dependencies')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('Scope', () => {
|
||||
it('Scope with excluded', () => {
|
||||
const filter = {
|
||||
...baseFilter,
|
||||
scope: { rootPath: [DASHBOARD_ROOT_ID], excluded: [1, 4] },
|
||||
};
|
||||
renderContent(filter);
|
||||
expect(screen.getByText('Scope')).toBeVisible();
|
||||
expect(screen.getByText('Test chart 2')).toBeVisible();
|
||||
expect(
|
||||
screen.getByText(getTextInHTMLTags('Test chart 2, Test chart 3')),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
it('Scope with top level tab as root', () => {
|
||||
const filter = {
|
||||
...baseFilter,
|
||||
scope: { rootPath: ['TAB-1', 'TAB-2'], excluded: [1, 2] },
|
||||
};
|
||||
renderContent(filter);
|
||||
expect(screen.getByText('Scope')).toBeVisible();
|
||||
expect(
|
||||
screen.getByText(getTextInHTMLTags('Tab 2, Test chart 3')),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
it('Empty scope', () => {
|
||||
const filter = {
|
||||
...baseFilter,
|
||||
scope: { rootPath: [], excluded: [1, 2, 3, 4] },
|
||||
};
|
||||
renderContent(filter);
|
||||
expect(screen.getByText('Scope')).toBeVisible();
|
||||
expect(screen.getByText('None')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dependencies', () => {
|
||||
it('Has dependency', () => {
|
||||
const filter = {
|
||||
...baseFilter,
|
||||
cascadeParentIds: ['NATIVE_FILTER-2'],
|
||||
};
|
||||
renderContent(filter);
|
||||
expect(screen.getByText('Dependent on')).toBeVisible();
|
||||
expect(screen.getByText('Native filter 2')).toBeVisible();
|
||||
});
|
||||
|
||||
it('Focus filter on dependency click', () => {
|
||||
const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch');
|
||||
const dummyDispatch = jest.fn();
|
||||
useDispatchMock.mockReturnValue(dummyDispatch);
|
||||
|
||||
const filter = {
|
||||
...baseFilter,
|
||||
cascadeParentIds: ['NATIVE_FILTER-2'],
|
||||
};
|
||||
renderContent(filter);
|
||||
|
||||
userEvent.click(screen.getByText('Native filter 2'));
|
||||
expect(dummyDispatch).toHaveBeenCalledWith({
|
||||
type: SET_DIRECT_PATH,
|
||||
path: ['NATIVE_FILTER-2'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -47,17 +47,16 @@ export const ScopeRow = React.memo(({ filter }: FilterCardRowProps) => {
|
||||
[elementsTruncated, scope],
|
||||
);
|
||||
|
||||
if (!Array.isArray(scope) || scope.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Row>
|
||||
<RowLabel>{t('Scope')}</RowLabel>
|
||||
<TooltipWithTruncation title={tooltipText}>
|
||||
<RowValue ref={scopeRef}>
|
||||
{scope.map((element, index) => (
|
||||
<span>{index === 0 ? element : `, ${element}`}</span>
|
||||
))}
|
||||
{scope
|
||||
? scope.map((element, index) => (
|
||||
<span>{index === 0 ? element : `, ${element}`}</span>
|
||||
))
|
||||
: t('None')}
|
||||
</RowValue>
|
||||
{hasHiddenElements > 0 && (
|
||||
<RowTruncationCount>+{elementsTruncated}</RowTruncationCount>
|
||||
|
||||
Reference in New Issue
Block a user