Skip to content

Commit

Permalink
feat: update dataset editor modal (#10347)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lily Kuang authored Jul 28, 2020
1 parent e89e60d commit 39fad85
Show file tree
Hide file tree
Showing 12 changed files with 541 additions and 510 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@
* under the License.
*/
import React from 'react';
import { mount } from 'enzyme';
import { Modal } from 'react-bootstrap';
import configureStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import fetchMock from 'fetch-mock';
import thunk from 'redux-thunk';
import sinon from 'sinon';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';
import { act } from 'react-dom/test-utils';

import ChangeDatasourceModal from 'src/datasource/ChangeDatasourceModal';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import mockDatasource from '../../fixtures/mockDatasource';

const props = {
const mockStore = configureStore([thunk]);
const store = mockStore({});

const mockedProps = {
addDangerToast: () => {},
onDatasourceSave: sinon.spy(),
onChange: () => {},
Expand All @@ -37,62 +43,53 @@ const props = {

const datasource = mockDatasource['7__table'];
const datasourceData = {
id: datasource.name,
id: datasource.id,
type: datasource.type,
uid: datasource.id,
};

const DATASOURCES_ENDPOINT = 'glob:*/superset/datasources/';
const DATASOURCE_ENDPOINT = `glob:*/datasource/get/${datasourceData.type}/${datasourceData.id}`;
const DATASOURCES_PAYLOAD = { json: 'data' };
const DATASOURCE_PAYLOAD = { new: 'data' };

describe('ChangeDatasourceModal', () => {
const mockStore = configureStore([thunk]);
const store = mockStore({});
fetchMock.get(DATASOURCES_ENDPOINT, DATASOURCES_PAYLOAD);
fetchMock.get(DATASOURCES_ENDPOINT, [mockDatasource['7__table']]);
fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD);

async function mountAndWait(props = mockedProps) {
const mounted = mount(<ChangeDatasourceModal {...props} />, {
context: { store },
wrappingComponent: ThemeProvider,
wrappingComponentProps: { theme: supersetTheme },
});
await waitForComponentToPaint(mounted);

return mounted;
}

describe('ChangeDatasourceModal', () => {
let wrapper;
let el;
let inst;

beforeEach(() => {
el = <ChangeDatasourceModal {...props} />;
wrapper = shallow(el, { context: { store } }).dive();
inst = wrapper.instance();
beforeEach(async () => {
wrapper = await mountAndWait();
});

it('is valid', () => {
expect(React.isValidElement(el)).toBe(true);
it('renders', () => {
expect(wrapper.find(ChangeDatasourceModal)).toHaveLength(1);
});

it('renders a Modal', () => {
expect(wrapper.find(Modal)).toHaveLength(1);
});

it('fetches datasources', () => {
return new Promise(done => {
inst.onEnterModal();
setTimeout(() => {
expect(fetchMock.calls(DATASOURCES_ENDPOINT)).toHaveLength(1);
fetchMock.reset();
done();
}, 0);
});
it('fetches datasources', async () => {
expect(fetchMock.calls(/superset\/datasources/)).toHaveLength(3);
});

it('changes the datasource', () => {
return new Promise(done => {
fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD);
inst.selectDatasource(datasourceData);
setTimeout(() => {
expect(fetchMock.calls(DATASOURCE_ENDPOINT)).toHaveLength(1);
expect(props.onDatasourceSave.getCall(0).args[0]).toEqual(
DATASOURCE_PAYLOAD,
);
fetchMock.reset();
done();
}, 0);
it('changes the datasource', async () => {
act(() => {
wrapper.find('.datasource-link').at(0).props().onClick(datasourceData);
});
await waitForComponentToPaint(wrapper);
expect(fetchMock.calls(/datasource\/get\/table\/7/)).toHaveLength(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,66 +17,80 @@
* under the License.
*/
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Modal } from 'react-bootstrap';
import configureStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import { mount } from 'enzyme';
import fetchMock from 'fetch-mock';
import thunk from 'redux-thunk';
import sinon from 'sinon';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';

import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import DatasourceModal from 'src/datasource/DatasourceModal';
import DatasourceEditor from 'src/datasource/DatasourceEditor';
import mockDatasource from '../../fixtures/mockDatasource';

const props = {
datasource: mockDatasource['7__table'],
const mockStore = configureStore([thunk]);
const store = mockStore({});
const datasource = mockDatasource['7__table'];

const SAVE_ENDPOINT = 'glob:*/api/v1/dataset/7';
const SAVE_PAYLOAD = { new: 'data' };

const mockedProps = {
datasource,
addSuccessToast: () => {},
addDangerToast: () => {},
onChange: () => {},
show: true,
onHide: () => {},
show: true,
onDatasourceSave: sinon.spy(),
};

const SAVE_ENDPOINT = 'glob:*/datasource/save/';
const SAVE_PAYLOAD = { new: 'data' };
async function mountAndWait(props = mockedProps) {
const mounted = mount(<DatasourceModal {...props} />, {
context: { store },
wrappingComponent: ThemeProvider,
wrappingComponentProps: { theme: supersetTheme },
});
await waitForComponentToPaint(mounted);

return mounted;
}

describe('DatasourceModal', () => {
const mockStore = configureStore([thunk]);
const store = mockStore({});
fetchMock.post(SAVE_ENDPOINT, SAVE_PAYLOAD);
const callsP = fetchMock.put(SAVE_ENDPOINT, SAVE_PAYLOAD);

let wrapper;
let el;
let inst;

beforeEach(() => {
el = <DatasourceModal {...props} />;
wrapper = shallow(el, { context: { store } }).dive();
inst = wrapper.instance();
beforeEach(async () => {
wrapper = await mountAndWait();
});

it('is valid', () => {
expect(React.isValidElement(el)).toBe(true);
it('renders', () => {
expect(wrapper.find(DatasourceModal)).toHaveLength(1);
});

it('renders a Modal', () => {
expect(wrapper.find(Modal)).toHaveLength(1);
expect(wrapper.find(Modal)).toHaveLength(2);
});

it('renders a DatasourceEditor', () => {
expect(wrapper.find(DatasourceEditor)).toHaveLength(1);
});

it('saves on confirm', () => {
return new Promise(done => {
inst.onConfirmSave();
setTimeout(() => {
expect(fetchMock.calls(SAVE_ENDPOINT)).toHaveLength(1);
expect(props.onDatasourceSave.getCall(0).args[0]).toEqual(SAVE_PAYLOAD);
fetchMock.reset();
done();
}, 0);
it('saves on confirm', async () => {
act(() => {
wrapper.find('[className="m-r-5"]').props().onClick();
});
await waitForComponentToPaint(wrapper);
act(() => {
const okButton = wrapper.find('[className="btn btn-sm btn-primary"]');
okButton.simulate('click');
});
await waitForComponentToPaint(wrapper);
expect(callsP._calls).toHaveLength(2); /* eslint no-underscore-dangle: 0 */
});
});
Loading

0 comments on commit 39fad85

Please sign in to comment.