diff --git a/superset-frontend/spec/fixtures/mockStore.js b/superset-frontend/spec/fixtures/mockStore.js index 263f3c3dc..faf083389 100644 --- a/superset-frontend/spec/fixtures/mockStore.js +++ b/superset-frontend/spec/fixtures/mockStore.js @@ -27,8 +27,12 @@ import { sliceId } from './mockChartQueries'; import { dashboardFilters } from './mockDashboardFilters'; import { nativeFilters } from './mockNativeFilters'; -export const getMockStore = () => - createStore(rootReducer, mockState, compose(applyMiddleware(thunk))); +export const getMockStore = overrideState => + createStore( + rootReducer, + { ...mockState, ...overrideState }, + compose(applyMiddleware(thunk)), + ); export const mockStore = getMockStore(); diff --git a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/ChartHolder_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/ChartHolder_spec.jsx index 7d8e8841b..052e0edfa 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/ChartHolder_spec.jsx +++ b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/ChartHolder_spec.jsx @@ -29,14 +29,17 @@ import DragDroppable from 'src/dashboard/components/dnd/DragDroppable'; import HoverMenu from 'src/dashboard/components/menu/HoverMenu'; import ResizableContainer from 'src/dashboard/components/resizable/ResizableContainer'; -import { mockStore } from 'spec/fixtures/mockStore'; +import { getMockStore } from 'spec/fixtures/mockStore'; import { sliceId } from 'spec/fixtures/mockChartQueries'; +import dashboardInfo from 'spec/fixtures/mockDashboardInfo'; import { dashboardLayout as mockLayout } from 'spec/fixtures/mockDashboardLayout'; import WithDragDropContext from 'spec/helpers/WithDragDropContext'; +import { sliceEntitiesForChart } from 'spec/fixtures/mockSliceEntities'; describe('ChartHolder', () => { const props = { id: String(sliceId), + dashboardId: dashboardInfo.id, parentId: 'ROW_ID', component: mockLayout.present.CHART_ID, depth: 2, @@ -54,6 +57,10 @@ describe('ChartHolder', () => { }; function setup(overrideProps) { + const mockStore = getMockStore({ + sliceEntities: sliceEntitiesForChart, + }); + // We have to wrap provide DragDropContext for the underlying DragDroppable // otherwise we cannot assert on DragDroppable children const wrapper = mount( diff --git a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx index f2289f274..e658916d8 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx +++ b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tab_spec.jsx @@ -42,6 +42,8 @@ describe('Tabs', () => { depth: 1, editMode: false, renderType: RENDER_TAB, + filters: {}, + setDirectPathToChild: jest.fn(), onDropOnTab() {}, onDeleteTab() {}, availableColumnCount: 12, diff --git a/superset-frontend/spec/javascripts/datasource/ChangeDatasourceModal_spec.jsx b/superset-frontend/spec/javascripts/datasource/ChangeDatasourceModal_spec.jsx index efa39e032..bdef06ad5 100644 --- a/superset-frontend/spec/javascripts/datasource/ChangeDatasourceModal_spec.jsx +++ b/superset-frontend/spec/javascripts/datasource/ChangeDatasourceModal_spec.jsx @@ -52,8 +52,11 @@ const DATASOURCES_ENDPOINT = const DATASOURCE_ENDPOINT = `glob:*/datasource/get/${datasourceData.type}/${datasourceData.id}`; const DATASOURCE_PAYLOAD = { new: 'data' }; +const INFO_ENDPOINT = 'glob:*/api/v1/dataset/_info?*'; + fetchMock.get(DATASOURCES_ENDPOINT, { result: [mockDatasource['7__table']] }); fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD); +fetchMock.get(INFO_ENDPOINT, {}); async function mountAndWait(props = mockedProps) { const mounted = mount(, { diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx index a22d615ea..d25e18138 100644 --- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx @@ -55,7 +55,7 @@ const columns = [ const formData = { metric: undefined, - metrics: [sumValueAdhocMetric, savedMetric.saved_metric_name], + metrics: [sumValueAdhocMetric, savedMetric.metric_name], }; function setup(overrides) { diff --git a/superset-frontend/spec/javascripts/explore/components/EmbedCodeButton_spec.jsx b/superset-frontend/spec/javascripts/explore/components/EmbedCodeButton_spec.jsx index 80201a5db..59d226262 100644 --- a/superset-frontend/spec/javascripts/explore/components/EmbedCodeButton_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/EmbedCodeButton_spec.jsx @@ -23,11 +23,15 @@ import Popover from 'src/common/components/Popover'; import sinon from 'sinon'; import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; - +import fetchMock from 'fetch-mock'; import EmbedCodeButton from 'src/explore/components/EmbedCodeButton'; import * as exploreUtils from 'src/explore/exploreUtils'; import * as common from 'src/utils/common'; +const ENDPOINT = 'glob:*/r/shortner/'; + +fetchMock.post(ENDPOINT, {}); + describe('EmbedCodeButton', () => { const mockStore = configureStore([]); const store = mockStore({}); diff --git a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx index 825b57ed1..68fdf8341 100644 --- a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx @@ -131,7 +131,6 @@ describe('MetricsControl', () => { label: 'SUM(value)', optionName: 'blahblahblah', }, - 'avg__value', ], }); @@ -149,7 +148,6 @@ describe('MetricsControl', () => { sqlExpression: null, isNew: false, }, - 'avg__value', ]); }); }); @@ -157,7 +155,10 @@ describe('MetricsControl', () => { describe('onChange', () => { it('handles creating a new metric', () => { const { component, onChange } = setup(); - component.instance().onNewMetric({ metric_name: 'sum__value' }); + component.instance().onNewMetric({ + metric_name: 'sum__value', + expression: 'SUM(energy_usage.value)', + }); expect(onChange.lastCall.args).toEqual([['sum__value']]); }); }); diff --git a/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx b/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx index 66e7706a8..1c3c50cc1 100644 --- a/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/SaveModal_spec.jsx @@ -71,6 +71,17 @@ describe('SaveModal', () => { value: 10, }; + const mockDashboardData = { + pks: ['id'], + result: [{ id: 'id', dashboard_title: 'dashboard title' }], + }; + + const saveEndpoint = `glob:*/dashboardasync/api/read?_flt_0_owners=${1}`; + + beforeAll(() => fetchMock.get(saveEndpoint, mockDashboardData)); + + afterAll(() => fetchMock.restore()); + const getWrapper = () => shallow() .dive() @@ -183,21 +194,21 @@ describe('SaveModal', () => { }); describe('should always reload or redirect', () => { + const originalLocation = window.location; + delete window.location; + window.location = { assign: jest.fn() }; + const stub = sinon.stub(window.location, 'assign'); + + afterAll(() => { + delete window.location; + window.location = originalLocation; + }); + let wrapper; - let windowLocation; beforeEach(() => { + stub.resetHistory(); wrapper = getWrapper(); - windowLocation = window.location; - // To bypass "TypeError: Cannot redefine property: assign" - Object.defineProperty(window, 'location', { - value: { ...windowLocation, assign: () => {} }, - }); - sinon.stub(window.location, 'assign'); - }); - afterEach(() => { - window.location.assign.restore(); - Object.defineProperty(window, 'location', windowLocation); }); it('Save & go to dashboard', () => @@ -248,25 +259,9 @@ describe('SaveModal', () => { let actionThunk; const userID = 1; - const mockDashboardData = { - pks: ['id'], - result: [{ id: 'id', dashboard_title: 'dashboard title' }], - }; - - const saveEndpoint = `glob:*/dashboardasync/api/read?_flt_0_owners=${1}`; - - beforeAll(() => { - fetchMock.get(saveEndpoint, mockDashboardData); - }); - - afterAll(fetchMock.restore); - beforeEach(() => { - dispatch = sinon.spy(); - }); - - afterEach(() => { fetchMock.resetHistory(); + dispatch = sinon.spy(); }); const makeRequest = () => { diff --git a/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx index 2c76ce477..b9c76e380 100644 --- a/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx @@ -155,7 +155,7 @@ describe('SelectControl', () => { , ); diff --git a/superset-frontend/spec/javascripts/messageToasts/components/Toast_spec.jsx b/superset-frontend/spec/javascripts/messageToasts/components/Toast_spec.jsx index cdb86ab03..fb61656fd 100644 --- a/superset-frontend/spec/javascripts/messageToasts/components/Toast_spec.jsx +++ b/superset-frontend/spec/javascripts/messageToasts/components/Toast_spec.jsx @@ -20,7 +20,7 @@ import { Alert } from 'react-bootstrap'; import React from 'react'; import { mount } from 'enzyme'; import Toast from 'src/messageToasts/components/Toast'; - +import { act } from 'react-dom/test-utils'; import mockMessageToasts from '../mockMessageToasts'; const props = { @@ -43,19 +43,23 @@ describe('Toast', () => { expect(alert.childAt(0).childAt(1).text()).toBe(props.toast.text); }); - it('should call onCloseToast upon alert dismissal', () => - new Promise(done => { - const onCloseToast = id => { - expect(id).toBe(props.toast.id); - done(); - }; + it('should call onCloseToast upon alert dismissal', async () => { + await act( + () => + new Promise(done => { + const onCloseToast = id => { + expect(id).toBe(props.toast.id); + done(); + }; - const wrapper = setup({ onCloseToast }); - const handleClosePress = wrapper.find('[label="Close alert"]').props() - .onClick; + const wrapper = setup({ onCloseToast }); + const handleClosePress = wrapper.find('[label="Close alert"]').props() + .onClick; - const alertProps = wrapper.find(Alert).props(); - expect(alertProps.onDismiss).toBe(handleClosePress); - handleClosePress(); // there is a timeout for onCloseToast to be called - })); + const alertProps = wrapper.find(Alert).props(); + expect(alertProps.onDismiss).toBe(handleClosePress); + handleClosePress(); // there is a timeout for onCloseToast to be called + }), + ); + }); }); diff --git a/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx b/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx index d8739c5f8..f3fbf9257 100644 --- a/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx +++ b/superset-frontend/spec/javascripts/sqllab/QuerySearch_spec.jsx @@ -20,14 +20,18 @@ import React from 'react'; import Button from 'src/components/Button'; import { shallow } from 'enzyme'; import sinon from 'sinon'; - +import fetchMock from 'fetch-mock'; import Select from 'src/components/Select'; import QuerySearch from 'src/SqlLab/components/QuerySearch'; +const SEARCH_ENDPOINT = 'glob:*/superset/search_queries?*'; + +fetchMock.get(SEARCH_ENDPOINT, []); + describe('QuerySearch', () => { const search = sinon.spy(QuerySearch.prototype, 'refreshQueries'); const mockedProps = { - actions: {}, + actions: { addDangerToast: jest.fn() }, height: 0, displayLimit: 50, }; diff --git a/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseModal_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseModal_spec.jsx index fc8472c02..fb1e6e0d0 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseModal_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseModal_spec.jsx @@ -20,10 +20,11 @@ import React from 'react'; import thunk from 'redux-thunk'; import configureStore from 'redux-mock-store'; import { styledMount as mount } from 'spec/helpers/theming'; - import DatabaseModal from 'src/views/CRUD/data/database/DatabaseModal'; import Modal from 'src/common/components/Modal'; import Tabs from 'src/common/components/Tabs'; +import fetchMock from 'fetch-mock'; +import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint'; // store needed for withToasts(DatabaseModal) const mockStore = configureStore([thunk]); @@ -42,9 +43,12 @@ const dbProps = { }, }; +const DATABASE_ENDPOINT = 'glob:*/api/v1/database/*'; + +fetchMock.get(DATABASE_ENDPOINT, {}); + describe('DatabaseModal', () => { const wrapper = mount(); - const editWrapper = mount(); it('renders', () => { expect(wrapper.find(DatabaseModal)).toExist(); @@ -54,11 +58,13 @@ describe('DatabaseModal', () => { expect(wrapper.find(Modal)).toExist(); }); - it('renders "Add Database" header when no database is included', () => { + it('renders "Add database" header when no database is included', () => { expect(wrapper.find('h4').text()).toEqual('Add database'); }); - it('renders "Edit Database" header when database prop is included', () => { + it('renders "Edit database" header when database prop is included', () => { + const editWrapper = mount(); + waitForComponentToPaint(editWrapper); expect(editWrapper.find('h4').text()).toEqual('Edit database'); });