diff --git a/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx b/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx index 52f3566f70c..77db226068a 100644 --- a/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx +++ b/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx @@ -45,10 +45,12 @@ const store = mockStore(initialState); describe('ResultSet', () => { const clearQuerySpy = sinon.spy(); const fetchQuerySpy = sinon.spy(); + const reRunQuerySpy = sinon.spy(); const mockedProps = { actions: { clearQueryResults: clearQuerySpy, fetchQueryResults: fetchQuerySpy, + reRunQuery: reRunQuerySpy, }, cache: true, query: queries[0], @@ -83,6 +85,29 @@ describe('ResultSet', () => { const wrapper = shallow(); expect(wrapper.find(FilterableTable)).toExist(); }); + describe('componentDidMount', () => { + const propsWithError = { + ...mockedProps, + query: { ...queries[0], errorMessage: 'Your session timed out' }, + }; + let spy; + beforeEach(() => { + reRunQuerySpy.resetHistory(); + spy = sinon.spy(ResultSet.prototype, 'componentDidMount'); + }); + afterEach(() => { + spy.restore(); + }); + it('should call reRunQuery if timed out', () => { + shallow(); + expect(reRunQuerySpy.callCount).toBe(1); + }); + + it('should not call reRunQuery if no error', () => { + shallow(); + expect(reRunQuerySpy.callCount).toBe(0); + }); + }); describe('UNSAFE_componentWillReceiveProps', () => { const wrapper = shallow(); let spy; diff --git a/superset-frontend/spec/javascripts/sqllab/actions/sqlLab_spec.js b/superset-frontend/spec/javascripts/sqllab/actions/sqlLab_spec.js index 4a83786bc9d..44e468cf57e 100644 --- a/superset-frontend/spec/javascripts/sqllab/actions/sqlLab_spec.js +++ b/superset-frontend/spec/javascripts/sqllab/actions/sqlLab_spec.js @@ -173,7 +173,7 @@ describe('async actions', () => { fetchMock.get( fetchQueryEndpoint, - { throws: { error: 'error text' } }, + { throws: { message: 'error text' } }, { overwriteRoutes: true }, ); @@ -238,7 +238,7 @@ describe('async actions', () => { fetchMock.post( runQueryEndpoint, - { throws: { error: 'error text' } }, + { throws: { message: 'error text' } }, { overwriteRoutes: true }, ); @@ -252,6 +252,29 @@ describe('async actions', () => { }); }); + describe('reRunQuery', () => { + let stub; + beforeEach(() => { + stub = sinon.stub(shortid, 'generate').returns('abcd'); + }); + afterEach(() => { + stub.restore(); + }); + + it('creates new query with a new id', () => { + const id = 'id'; + const state = { + sqlLab: { + tabHistory: [id], + queryEditors: [{ id, title: 'Dummy query editor' }], + }, + }; + const store = mockStore(state); + store.dispatch(actions.reRunQuery(query)); + expect(store.getActions()[0].query.id).toEqual('abcd'); + }); + }); + describe('postStopQuery', () => { const stopQueryEndpoint = 'glob:*/superset/stop_query/*'; fetchMock.post(stopQueryEndpoint, {}); diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js b/superset-frontend/src/SqlLab/actions/sqlLab.js index 02a523a2348..a1bc59eafbd 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.js +++ b/superset-frontend/src/SqlLab/actions/sqlLab.js @@ -352,6 +352,13 @@ export function runQuery(query) { }; } +export function reRunQuery(query) { + // run Query with a new id + return function (dispatch) { + dispatch(runQuery({ ...query, id: shortid.generate() })); + }; +} + export function validateQuery(query) { return function (dispatch) { dispatch(startQueryValidation(query)); diff --git a/superset-frontend/src/SqlLab/components/ResultSet.tsx b/superset-frontend/src/SqlLab/components/ResultSet.tsx index f0c3d47de26..a33fcd1ce72 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet.tsx +++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx @@ -416,7 +416,7 @@ export default class ResultSet extends React.PureComponent< query.errorMessage && query.errorMessage.indexOf('session timed out') > 0 ) { - this.props.actions.runQuery(query, true); + this.props.actions.reRunQuery(query); } }