blob: 81bd0d0670d1213f16a4a62e2b9e2081ad292890 [file] [log] [blame]
/**
* 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 { mount } from 'enzyme';
import { Provider } from 'react-redux';
import fetchMock from 'fetch-mock';
import {
supersetTheme,
SupersetClient,
ThemeProvider,
} from '@superset-ui/core';
import Modal from 'src/components/Modal';
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
import { mockStore } from 'spec/fixtures/mockStore';
const dashboardResult = {
json: {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"something":"foo"}',
owners: [],
roles: [],
},
},
};
fetchMock.restore();
fetchMock.get('glob:*/api/v1/dashboard/related/owners?*', {
result: [],
});
fetchMock.get('glob:*/api/v1/dashboard/*', {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"something":"foo"}',
owners: [],
roles: [],
},
});
describe('PropertiesModal', () => {
afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});
const requiredProps = {
dashboardId: 1,
show: true,
addSuccessToast: () => {},
};
function setup(overrideProps) {
return mount(
<Provider store={mockStore}>
<PropertiesModal {...requiredProps} {...overrideProps} />
</Provider>,
{
wrappingComponent: ThemeProvider,
wrappingComponentProps: { theme: supersetTheme },
},
);
}
describe('onColorSchemeChange', () => {
it('sets up a default state', () => {
const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
expect(
wrapper.find('PropertiesModal').instance().state.values.colorScheme,
).toEqual('SUPERSET_DEFAULT');
});
describe('with a valid color scheme as an arg', () => {
describe('without metadata', () => {
const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
const modalInstance = wrapper.find('PropertiesModal').instance();
it('does not update the color scheme in the metadata', () => {
const spy = jest.spyOn(modalInstance, 'onMetadataChange');
modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
expect(spy).not.toHaveBeenCalled();
});
});
describe('with metadata', () => {
describe('with color_scheme in the metadata', () => {
it('will update the metadata', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
modalInstance.setState({
values: {
json_metadata: '{"color_scheme": "foo"}',
},
});
const spy = jest.spyOn(modalInstance, 'onMetadataChange');
modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
expect(spy).toHaveBeenCalledWith(
'{"color_scheme": "SUPERSET_DEFAULT", "label_colors": {}}',
);
});
});
describe('without color_scheme in the metadata', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
modalInstance.setState({
values: {
json_metadata: '{"timed_refresh_immune_slices": []}',
},
});
it('will not update the metadata', () => {
const spy = jest.spyOn(modalInstance, 'onMetadataChange');
modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
expect(spy).not.toHaveBeenCalled();
});
});
});
});
describe('with an invalid color scheme as an arg', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
it('will raise an error', () => {
const spy = jest.spyOn(Modal, 'error');
expect(() =>
modalInstance.onColorSchemeChange('THIS_WILL_NOT_WORK'),
).toThrowError('A valid color scheme is required');
expect(spy).toHaveBeenCalled();
});
});
});
describe('onOwnersChange', () => {
it('should update the state with the value passed', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const spy = jest.spyOn(modalInstance, 'updateFormState');
modalInstance.onOwnersChange('foo');
expect(spy).toHaveBeenCalledWith('owners', 'foo');
});
});
describe('onMetadataChange', () => {
it('should update the state with the value passed', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const spy = jest.spyOn(modalInstance, 'updateFormState');
modalInstance.onMetadataChange('foo');
expect(spy).toHaveBeenCalledWith('json_metadata', 'foo');
});
});
describe('onChange', () => {
it('should update the state with the value passed', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const spy = jest.spyOn(modalInstance, 'updateFormState');
modalInstance.onChange({ target: { name: 'test', value: 'foo' } });
expect(spy).toHaveBeenCalledWith('test', 'foo');
});
});
describe('fetchDashboardDetails', () => {
it('should make an api call', () => {
const spy = jest.spyOn(SupersetClient, 'get');
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
modalInstance.fetchDashboardDetails();
expect(spy).toHaveBeenCalledWith({
endpoint: '/api/v1/dashboard/1',
});
});
it('should update state', async () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const fetchSpy = jest
.spyOn(SupersetClient, 'get')
.mockResolvedValue(dashboardResult);
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toBeUndefined();
expect(modalInstance.state.values.dashboard_title).toEqual('New Title');
expect(modalInstance.state.values.slug).toEqual('/new');
expect(modalInstance.state.values.json_metadata).toEqual(
'{"something": "foo"}',
);
});
it('should call onOwnersChange', async () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
json: {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"something":"foo"}',
owners: [{ id: 1, first_name: 'Al', last_name: 'Pacino' }],
roles: [],
},
},
});
const onOwnersSpy = jest.spyOn(modalInstance, 'onOwnersChange');
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toBeUndefined();
expect(onOwnersSpy).toHaveBeenCalledWith([
{ value: 1, label: 'Al Pacino' },
]);
});
it('should call onRolesChange', async () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
json: {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"something":"foo"}',
owners: [],
roles: [{ id: 1, name: 'Alpha' }],
},
},
});
const onRolwesSpy = jest.spyOn(modalInstance, 'onRolesChange');
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toBeUndefined();
expect(onRolwesSpy).toHaveBeenCalledWith([{ value: 1, label: 'Alpha' }]);
});
describe('when colorScheme is undefined as a prop', () => {
describe('when color_scheme is defined in json_metadata', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
it('should use the color_scheme from json_metadata in the api response', async () => {
const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
json: {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"color_scheme":"SUPERSET_DEFAULT"}',
owners: [],
roles: [],
},
},
});
modalInstance.fetchDashboardDetails();
// this below triggers the callback of the api call
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toEqual(
'SUPERSET_DEFAULT',
);
});
describe('when color_scheme is not defined in json_metadata', () => {
const wrapper = setup();
const modalInstance = wrapper.find('PropertiesModal').instance();
it('should be undefined', async () => {
const fetchSpy = jest
.spyOn(SupersetClient, 'get')
.mockResolvedValue(dashboardResult);
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toBeUndefined();
});
});
});
});
describe('when colorScheme is defined as a prop', () => {
describe('when color_scheme is defined in json_metadata', () => {
const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
const modalInstance = wrapper.find('PropertiesModal').instance();
it('should use the color_scheme from json_metadata in the api response', async () => {
const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
json: {
result: {
dashboard_title: 'New Title',
slug: '/new',
json_metadata: '{"color_scheme":"SUPERSET_DEFAULT"}',
owners: [],
roles: [],
},
},
});
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toEqual(
'SUPERSET_DEFAULT',
);
});
});
describe('when color_scheme is not defined in json_metadata', () => {
const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
const modalInstance = wrapper.find('PropertiesModal').instance();
it('should use the colorScheme from the prop', async () => {
const fetchSpy = jest
.spyOn(SupersetClient, 'get')
.mockResolvedValue(dashboardResult);
modalInstance.fetchDashboardDetails();
await fetchSpy();
expect(modalInstance.state.values.colorScheme).toBeUndefined();
});
});
});
});
});