Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions superset/assets/spec/javascripts/components/AnchorLink_spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,27 @@ describe('AnchorLink', () => {
anchorLinkId: 'CHART-123',
};

beforeEach(() => {
global.window = Object.create(window);
Object.defineProperty(window, 'location', {
value: {
hash: '#' + props.anchorLinkId,
},
});
});

afterEach(() => {
delete global.window.location.value;
});

it('should scroll the AnchorLink into view upon mount', () => {
const callback = sinon.spy();
const clock = sinon.useFakeTimers();
const stub = sinon.stub(document, 'getElementById').returns({
scrollIntoView: callback,
});

const wrapper = shallow(<AnchorLink {...props} />);
wrapper.instance().getLocationHash = () => (props.anchorLinkId);
wrapper.update();

wrapper.instance().componentDidMount();
shallow(<AnchorLink {...props} />);
clock.tick(2000);
expect(callback.callCount).toEqual(1);
stub.restore();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,29 @@
import sinon from 'sinon';
import { SupersetClient } from '@superset-ui/connection';

import { saveDashboardRequest } from '../../../../src/dashboard/actions/dashboardState';
import {
removeSliceFromDashboard,
saveDashboardRequest,
} from '../../../../src/dashboard/actions/dashboardState';
import { REMOVE_FILTER } from '../../../../src/dashboard/actions/dashboardFilters';
import { UPDATE_COMPONENTS_PARENTS_LIST } from '../../../../src/dashboard/actions/dashboardLayout';
import {
filterId,
sliceEntitiesForDashboard as sliceEntities,
} from '../fixtures/mockSliceEntities';
import { emptyFilters } from '../fixtures/mockDashboardFilters';
import mockDashboardData from '../fixtures/mockDashboardData';
import { DASHBOARD_GRID_ID } from '../../../../src/dashboard/util/constants';

describe('dashboardState actions', () => {
const mockState = {
dashboardState: {
sliceIds: [filterId],
hasUnsavedChanges: true,
},
dashboardInfo: {},
sliceEntities,
dashboardFilters: emptyFilters,
dashboardLayout: {
past: [],
present: mockDashboardData.positions,
Expand Down Expand Up @@ -97,4 +109,14 @@ describe('dashboardState actions', () => {
);
});
});

it('should dispatch removeFilter if a removed slice is a filter_box', () => {
const { getState, dispatch } = setup(mockState);
const thunk = removeSliceFromDashboard(filterId);
thunk(dispatch, getState);

const removeFilter = dispatch.getCall(0).args[0];
removeFilter(dispatch, getState);
expect(dispatch.getCall(3).args[0].type).toBe(REMOVE_FILTER);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('DashboardBuilder', () => {
setColorSchemeAndUnsavedChanges() {},
colorScheme: undefined,
handleComponentDrop() {},
toggleBuilderPane() {},
setDirectPathToChild: sinon.spy(),
};

function setup(overrideProps, useProvider = false, store = mockStore) {
Expand Down Expand Up @@ -171,7 +171,7 @@ describe('DashboardBuilder', () => {
expect(wrapper.find(BuilderComponentPane)).toHaveLength(1);
});

it('should change tabs if a top-level Tab is clicked', () => {
it('should change redux state if a top-level Tab is clicked', () => {
const wrapper = setup(
{ dashboardLayout: layoutWithTabs },
true,
Expand All @@ -185,6 +185,6 @@ describe('DashboardBuilder', () => {
.at(1)
.simulate('click');

expect(wrapper.find(TabContainer).prop('activeKey')).toBe(1);
expect(props.setDirectPathToChild.callCount).toBe(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('Dashboard', () => {
dashboardState,
dashboardInfo,
charts: chartQueries,
filters: {},
slices: sliceEntities.slices,
datasources,
layout: dashboardLayout.present,
Expand All @@ -60,27 +61,23 @@ describe('Dashboard', () => {
return wrapper;
}

const OVERRIDE_FILTERS = {
1: { region: [] },
2: { country_name: ['USA'] },
3: { region: [], country_name: ['USA'] },
};

it('should render a DashboardBuilder', () => {
const wrapper = setup();
expect(wrapper.find(DashboardBuilder)).toHaveLength(1);
});

describe('refreshExcept', () => {
const overrideDashboardState = {
...dashboardState,
filters: {
1: { region: [] },
2: { country_name: ['USA'] },
3: { region: [], country_name: ['USA'] },
},
refresh: true,
};

const overrideDashboardInfo = {
...dashboardInfo,
metadata: {
...dashboardInfo.metadata,
filter_immune_slice_fields: { [chartQueries[chartId].id]: ['region'] },
filterImmuneSliceFields: { [chartQueries[chartId].id]: ['region'] },
},
};

Expand Down Expand Up @@ -108,14 +105,14 @@ describe('Dashboard', () => {
expect(spy.callCount).toBe(Object.keys(overrideCharts).length - 1);
});

it('should not call triggerQuery for filter_immune_slices', () => {
it('should not call triggerQuery for filterImmuneSlices', () => {
const wrapper = setup({
charts: overrideCharts,
dashboardInfo: {
...dashboardInfo,
metadata: {
...dashboardInfo.metadata,
filter_immune_slices: Object.keys(overrideCharts).map(id =>
filterImmuneSlices: Object.keys(overrideCharts).map(id =>
Number(id),
),
},
Expand All @@ -127,9 +124,9 @@ describe('Dashboard', () => {
expect(spy.callCount).toBe(0);
});

it('should not call triggerQuery for filter_immune_slice_fields', () => {
it('should not call triggerQuery for filterImmuneSliceFields', () => {
const wrapper = setup({
dashboardState: overrideDashboardState,
filters: OVERRIDE_FILTERS,
dashboardInfo: overrideDashboardInfo,
});
const spy = sinon.spy(props.actions, 'triggerQuery');
Expand All @@ -140,7 +137,7 @@ describe('Dashboard', () => {

it('should call triggerQuery if filter has more filter-able fields', () => {
const wrapper = setup({
dashboardState: overrideDashboardState,
filters: OVERRIDE_FILTERS,
dashboardInfo: overrideDashboardInfo,
});
const spy = sinon.spy(props.actions, 'triggerQuery');
Expand Down Expand Up @@ -187,117 +184,78 @@ describe('Dashboard', () => {
});

describe('componentDidUpdate', () => {
const overrideDashboardState = {
...dashboardState,
filters: {
1: { region: [] },
2: { country_name: ['USA'] },
},
refresh: true,
};
let wrapper;
let prevProps;
let refreshExceptSpy;

it('should not call refresh when there is no change', () => {
const wrapper = setup({ dashboardState: overrideDashboardState });
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
const prevProps = wrapper.instance().props;
beforeEach(() => {
wrapper = setup({ filters: OVERRIDE_FILTERS });
wrapper.instance().appliedFilters = OVERRIDE_FILTERS;
prevProps = wrapper.instance().props;
refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
});

afterEach(() => {
refreshExceptSpy.restore();
});

it('should not call refresh when is editMode', () => {
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
...dashboardState,
editMode: true,
},
});
wrapper.instance().componentDidUpdate(prevProps);
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(0);
});

it('should call refresh if a filter is added', () => {
const wrapper = setup({ dashboardState: overrideDashboardState });
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
it('should not call refresh when there is no change', () => {
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
filters: {
...overrideDashboardState.filters,
3: { another_filter: ['please'] },
},
},
filters: OVERRIDE_FILTERS,
});
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(1);
wrapper.instance().componentDidUpdate(prevProps);
expect(refreshExceptSpy.callCount).toBe(0);
expect(wrapper.instance().appliedFilters).toBe(OVERRIDE_FILTERS);
});

it('should call refresh if a filter is removed', () => {
const wrapper = setup({ dashboardState: overrideDashboardState });
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
it('should call refresh if a filter is added', () => {
const newFilter = {
gender: ['boy', 'girl'],
};
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
filters: {},
filters: {
...OVERRIDE_FILTERS,
...newFilter,
},
});
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(1);
expect(wrapper.instance().appliedFilters).toEqual({
...OVERRIDE_FILTERS,
...newFilter,
});
});

it('should call refresh if a filter is changed', () => {
const wrapper = setup({ dashboardState: overrideDashboardState });
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
it('should call refresh if a filter is removed', () => {
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
filters: {
...overrideDashboardState.filters,
2: { country_name: ['Canada'] },
},
},
filters: {},
});
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(1);
expect(wrapper.instance().appliedFilters).toEqual({});
});

it('should not call refresh if filters change and refresh is false', () => {
const wrapper = setup({ dashboardState: overrideDashboardState });
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
it('should call refresh if a filter is changed', () => {
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
filters: {
...overrideDashboardState.filters,
2: { country_name: ['Canada'] },
},
refresh: false,
},
});
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(0);
});

it('should not refresh filter_immune_slices', () => {
const wrapper = setup({
dashboardState: overrideDashboardState,
dashboardInfo: {
...dashboardInfo,
metadata: {
...dashboardInfo.metadata,
filter_immune_slices: [chartId],
},
filters: {
...OVERRIDE_FILTERS,
region: ['Canada'],
},
});
const refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
const prevProps = wrapper.instance().props;
wrapper.setProps({
dashboardState: {
...overrideDashboardState,
filters: {
...overrideDashboardState.filters,
2: { country_name: ['Canada'] },
},
refresh: false,
},
expect(refreshExceptSpy.callCount).toBe(1);
expect(wrapper.instance().appliedFilters).toEqual({
...OVERRIDE_FILTERS,
region: ['Canada'],
});
wrapper.instance().componentDidUpdate(prevProps);
refreshExceptSpy.restore();
expect(refreshExceptSpy.callCount).toBe(0);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* 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 { shallow } from 'enzyme';

import { dashboardFilters } from '../fixtures/mockDashboardFilters';
import { filterId, column } from '../fixtures/mockSliceEntities';
import FilterIndicatorGroup from '../../../../src/dashboard/components/FilterIndicatorGroup';
import FilterBadgeIcon from '../../../../src/components/FilterBadgeIcon';

describe('FilterIndicatorGroup', () => {
const mockedProps = {
indicators: [
{
...dashboardFilters[filterId],
colorCode: 'badge-1',
name: column,
values: ['a', 'b', 'c'],
},
],
setDirectPathToChild: () => {},
};

function setup(overrideProps) {
return shallow(
<FilterIndicatorGroup {...mockedProps} {...overrideProps} />,
);
}

it('should show indicator group with badge', () => {
const wrapper = setup();
expect(wrapper.find(FilterBadgeIcon)).toHaveLength(1);
});
});
Loading