mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
[SIP-4] replace SQL Lab ajax calls with SupersetClient (#5896)
* [superset-client] replace sqllab ajax calls with SupersetClient * [superset-client][sqllab] replace more misc ajax calls * [superset-client][tests] call setupSupersetClient() in test shim * [superset-client] replace more sqllab ajax calls and fix tests * [superset-client][tests] remove commented lines * [sqllab][superset-client] fix eslint and tests, add better error handling tests. * [superset-client] fix tests from rebase * [cypress][sqllab][superset-client] fix * [superset-client] use Promises not callbacks in getShortUrl calls * [superset-client][short-url] don't stringify POST * [superset-client][short-url][cypress] add data-test attribute for more reliable test * [cypress] remove .only() call
This commit is contained in:
@@ -4,8 +4,8 @@ import thunk from 'redux-thunk';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
import $ from 'jquery';
|
||||
import shortid from 'shortid';
|
||||
import { queries, queryWithBadColumns } from './fixtures';
|
||||
import { sqlLabReducer } from '../../../src/SqlLab/reducers';
|
||||
@@ -58,10 +58,10 @@ describe('ExploreResultsButton', () => {
|
||||
requiresTime: true,
|
||||
value: 'bar',
|
||||
};
|
||||
const getExploreResultsButtonWrapper = (props = mockedProps) => (
|
||||
const getExploreResultsButtonWrapper = (props = mockedProps) =>
|
||||
shallow(<ExploreResultsButton {...props} />, {
|
||||
context: { store },
|
||||
}).dive());
|
||||
}).dive();
|
||||
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<ExploreResultsButton />)).toBe(true);
|
||||
@@ -151,64 +151,71 @@ describe('ExploreResultsButton', () => {
|
||||
datasourceName: 'mockDatasourceName',
|
||||
});
|
||||
|
||||
let ajaxSpy;
|
||||
let datasourceSpy;
|
||||
const visualizeURL = '/superset/sqllab_viz/';
|
||||
const visualizeEndpoint = `glob:*${visualizeURL}`;
|
||||
const visualizationPayload = { table_id: 107 };
|
||||
fetchMock.post(visualizeEndpoint, visualizationPayload);
|
||||
|
||||
beforeEach(() => {
|
||||
ajaxSpy = sinon.spy($, 'ajax');
|
||||
sinon.stub(JSON, 'parse').callsFake(() => ({ table_id: 107 }));
|
||||
sinon.stub(exploreUtils, 'getExploreUrlAndPayload').callsFake(() => ({ url: 'mockURL', payload: { datasource: '107__table' } }));
|
||||
sinon
|
||||
.stub(exploreUtils, 'getExploreUrlAndPayload')
|
||||
.callsFake(() => ({ url: 'mockURL', payload: { datasource: '107__table' } }));
|
||||
sinon.spy(exploreUtils, 'exportChart');
|
||||
sinon.stub(wrapper.instance(), 'buildVizOptions').callsFake(() => (mockOptions));
|
||||
datasourceSpy = sinon.stub(actions, 'createDatasource');
|
||||
sinon.stub(wrapper.instance(), 'buildVizOptions').callsFake(() => mockOptions);
|
||||
});
|
||||
afterEach(() => {
|
||||
ajaxSpy.restore();
|
||||
JSON.parse.restore();
|
||||
exploreUtils.getExploreUrlAndPayload.restore();
|
||||
exploreUtils.exportChart.restore();
|
||||
wrapper.instance().buildVizOptions.restore();
|
||||
datasourceSpy.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
it('should build request', () => {
|
||||
it('should build request with correct args', (done) => {
|
||||
wrapper.instance().visualize();
|
||||
expect(ajaxSpy.callCount).toBe(1);
|
||||
|
||||
const spyCall = ajaxSpy.getCall(0);
|
||||
expect(spyCall.args[0].type).toBe('POST');
|
||||
expect(spyCall.args[0].url).toBe('/superset/sqllab_viz/');
|
||||
expect(spyCall.args[0].data.data).toBe(JSON.stringify(mockOptions));
|
||||
});
|
||||
it('should open new window', () => {
|
||||
const infoToastSpy = sinon.spy();
|
||||
setTimeout(() => {
|
||||
const calls = fetchMock.calls(visualizeEndpoint);
|
||||
expect(calls).toHaveLength(1);
|
||||
const formData = calls[0][1].body;
|
||||
|
||||
datasourceSpy.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.resolve('done');
|
||||
return d.promise();
|
||||
Object.keys(mockOptions).forEach((key) => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(formData.get(key)).toBeDefined();
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should export chart and add an info toast', (done) => {
|
||||
const infoToastSpy = sinon.spy();
|
||||
const datasourceSpy = sinon.stub();
|
||||
|
||||
datasourceSpy.callsFake(() => Promise.resolve(visualizationPayload));
|
||||
|
||||
wrapper.setProps({
|
||||
actions: {
|
||||
createDatasource: datasourceSpy,
|
||||
addInfoToast: infoToastSpy,
|
||||
createDatasource: datasourceSpy,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.instance().visualize();
|
||||
expect(exploreUtils.exportChart.callCount).toBe(1);
|
||||
expect(exploreUtils.exportChart.getCall(0).args[0].datasource).toBe('107__table');
|
||||
expect(infoToastSpy.callCount).toBe(1);
|
||||
});
|
||||
it('should add error toast', () => {
|
||||
const dangerToastSpy = sinon.spy();
|
||||
|
||||
datasourceSpy.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.reject('error message');
|
||||
return d.promise();
|
||||
setTimeout(() => {
|
||||
expect(datasourceSpy.callCount).toBe(1);
|
||||
expect(exploreUtils.exportChart.callCount).toBe(1);
|
||||
expect(exploreUtils.exportChart.getCall(0).args[0].datasource).toBe('107__table');
|
||||
expect(infoToastSpy.callCount).toBe(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add error toast', (done) => {
|
||||
const dangerToastSpy = sinon.stub(actions, 'addDangerToast');
|
||||
const datasourceSpy = sinon.stub();
|
||||
|
||||
datasourceSpy.callsFake(() => Promise.reject({ error: 'error' }));
|
||||
|
||||
wrapper.setProps({
|
||||
actions: {
|
||||
@@ -218,8 +225,14 @@ describe('ExploreResultsButton', () => {
|
||||
});
|
||||
|
||||
wrapper.instance().visualize();
|
||||
expect(exploreUtils.exportChart.callCount).toBe(0);
|
||||
expect(dangerToastSpy.callCount).toBe(1);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(datasourceSpy.callCount).toBe(1);
|
||||
expect(exploreUtils.exportChart.callCount).toBe(0);
|
||||
expect(dangerToastSpy.callCount).toBe(1);
|
||||
dangerToastSpy.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
import $ from 'jquery';
|
||||
import { table, defaultQueryEditor, databases, tables } from './fixtures';
|
||||
import SqlEditorLeftBar from '../../../src/SqlLab/components/SqlEditorLeftBar';
|
||||
import TableElement from '../../../src/SqlLab/components/TableElement';
|
||||
@@ -23,23 +23,19 @@ describe('SqlEditorLeftBar', () => {
|
||||
};
|
||||
|
||||
let wrapper;
|
||||
let ajaxStub;
|
||||
|
||||
beforeEach(() => {
|
||||
ajaxStub = sinon.stub($, 'get');
|
||||
wrapper = shallow(<SqlEditorLeftBar {...mockedProps} />);
|
||||
});
|
||||
afterEach(() => {
|
||||
ajaxStub.restore();
|
||||
});
|
||||
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<SqlEditorLeftBar {...mockedProps} />),
|
||||
).toBe(true);
|
||||
expect(React.isValidElement(<SqlEditorLeftBar {...mockedProps} />)).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a TableElement', () => {
|
||||
expect(wrapper.find(TableElement)).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('onDatabaseChange', () => {
|
||||
it('should fetch schemas', () => {
|
||||
sinon.stub(wrapper.instance(), 'fetchSchemas');
|
||||
@@ -52,34 +48,42 @@ describe('SqlEditorLeftBar', () => {
|
||||
expect(wrapper.state().tableOptions).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTableNamesBySubStr', () => {
|
||||
it('should handle empty', () => (
|
||||
wrapper.instance().getTableNamesBySubStr('')
|
||||
const GET_TABLE_NAMES_GLOB = 'glob:*/superset/tables/1/main/*';
|
||||
|
||||
afterEach(fetchMock.resetHistory);
|
||||
afterAll(fetchMock.reset);
|
||||
|
||||
it('should handle empty', () =>
|
||||
wrapper
|
||||
.instance()
|
||||
.getTableNamesBySubStr('')
|
||||
.then((data) => {
|
||||
expect(data).toEqual({ options: [] });
|
||||
})
|
||||
));
|
||||
}));
|
||||
|
||||
it('should handle table name', () => {
|
||||
const queryEditor = Object.assign({}, defaultQueryEditor,
|
||||
{
|
||||
dbId: 1,
|
||||
schema: 'main',
|
||||
});
|
||||
const queryEditor = {
|
||||
...defaultQueryEditor,
|
||||
dbId: 1,
|
||||
schema: 'main',
|
||||
};
|
||||
|
||||
const mockTableOptions = { options: [table] };
|
||||
wrapper.setProps({ queryEditor });
|
||||
ajaxStub.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.resolve(mockTableOptions);
|
||||
return d.promise();
|
||||
});
|
||||
fetchMock.get(GET_TABLE_NAMES_GLOB, mockTableOptions, { overwriteRoutes: true });
|
||||
|
||||
return wrapper.instance().getTableNamesBySubStr('my table')
|
||||
return wrapper
|
||||
.instance()
|
||||
.getTableNamesBySubStr('my table')
|
||||
.then((data) => {
|
||||
expect(ajaxStub.getCall(0).args[0]).toBe('/superset/tables/1/main/my table');
|
||||
expect(fetchMock.calls(GET_TABLE_NAMES_GLOB)).toHaveLength(1);
|
||||
expect(data).toEqual(mockTableOptions);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('dbMutator should build databases options', () => {
|
||||
const options = wrapper.instance().dbMutator(databases);
|
||||
expect(options).toEqual([
|
||||
@@ -87,65 +91,109 @@ describe('SqlEditorLeftBar', () => {
|
||||
{ value: 208, label: 'Presto - Gold' },
|
||||
]);
|
||||
});
|
||||
|
||||
describe('fetchTables', () => {
|
||||
const FETCH_TABLES_GLOB = 'glob:*/superset/tables/1/main/birth_names/true/';
|
||||
afterEach(fetchMock.resetHistory);
|
||||
afterAll(fetchMock.reset);
|
||||
|
||||
it('should clear table options', () => {
|
||||
wrapper.instance().fetchTables(1);
|
||||
expect(wrapper.state().tableOptions).toEqual([]);
|
||||
expect(wrapper.state().filterOptions).toBeNull();
|
||||
});
|
||||
it('should fetch table options', () => {
|
||||
ajaxStub.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.resolve(tables);
|
||||
return d.promise();
|
||||
});
|
||||
wrapper.instance().fetchTables(1, 'main', 'true', 'birth_names');
|
||||
|
||||
expect(ajaxStub.getCall(0).args[0]).toBe('/superset/tables/1/main/birth_names/true/');
|
||||
expect(wrapper.state().tableLength).toBe(3);
|
||||
it('should fetch table options', () => {
|
||||
expect.assertions(2);
|
||||
fetchMock.get(FETCH_TABLES_GLOB, tables, { overwriteRoutes: true });
|
||||
|
||||
return wrapper
|
||||
.instance()
|
||||
.fetchTables(1, 'main', true, 'birth_names')
|
||||
.then(() => {
|
||||
expect(fetchMock.calls(FETCH_TABLES_GLOB)).toHaveLength(1);
|
||||
expect(wrapper.state().tableLength).toBe(3);
|
||||
});
|
||||
});
|
||||
it('should handle error', () => {
|
||||
ajaxStub.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.reject('error message');
|
||||
return d.promise();
|
||||
|
||||
it('should dispatch a danger toast on error', () => {
|
||||
const dangerToastSpy = sinon.spy();
|
||||
|
||||
wrapper.setProps({
|
||||
actions: {
|
||||
addDangerToast: dangerToastSpy,
|
||||
},
|
||||
});
|
||||
wrapper.instance().fetchTables(1, 'main', 'birth_names');
|
||||
expect(wrapper.state().tableOptions).toEqual([]);
|
||||
expect(wrapper.state().tableLength).toBe(0);
|
||||
|
||||
expect.assertions(4);
|
||||
fetchMock.get(FETCH_TABLES_GLOB, { throws: 'error' }, { overwriteRoutes: true });
|
||||
|
||||
return wrapper
|
||||
.instance()
|
||||
.fetchTables(1, 'main', true, 'birth_names')
|
||||
.then(() => {
|
||||
expect(fetchMock.calls(FETCH_TABLES_GLOB)).toHaveLength(1);
|
||||
expect(wrapper.state().tableOptions).toEqual([]);
|
||||
expect(wrapper.state().tableLength).toBe(0);
|
||||
expect(dangerToastSpy.callCount).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchSchemas', () => {
|
||||
const FETCH_SCHEMAS_GLOB = 'glob:*/superset/schemas/*';
|
||||
afterEach(fetchMock.resetHistory);
|
||||
afterAll(fetchMock.reset);
|
||||
|
||||
it('should fetch schema options', () => {
|
||||
expect.assertions(2);
|
||||
const schemaOptions = {
|
||||
schemas: ['main', 'erf', 'superset'],
|
||||
};
|
||||
ajaxStub.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.resolve(schemaOptions);
|
||||
return d.promise();
|
||||
});
|
||||
wrapper.instance().fetchSchemas(1);
|
||||
expect(ajaxStub.getCall(0).args[0]).toBe('/superset/schemas/1/false/');
|
||||
expect(wrapper.state().schemaOptions).toHaveLength(3);
|
||||
fetchMock.get(FETCH_SCHEMAS_GLOB, schemaOptions, { overwriteRoutes: true });
|
||||
|
||||
return wrapper
|
||||
.instance()
|
||||
.fetchSchemas(1)
|
||||
.then(() => {
|
||||
expect(fetchMock.calls(FETCH_SCHEMAS_GLOB)).toHaveLength(1);
|
||||
expect(wrapper.state().schemaOptions).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
it('should handle error', () => {
|
||||
ajaxStub.callsFake(() => {
|
||||
const d = $.Deferred();
|
||||
d.reject('error message');
|
||||
return d.promise();
|
||||
|
||||
it('should dispatch a danger toast on error', () => {
|
||||
const dangerToastSpy = sinon.spy();
|
||||
|
||||
wrapper.setProps({
|
||||
actions: {
|
||||
addDangerToast: dangerToastSpy,
|
||||
},
|
||||
});
|
||||
wrapper.instance().fetchSchemas(123);
|
||||
expect(wrapper.state().schemaOptions).toEqual([]);
|
||||
|
||||
expect.assertions(3);
|
||||
|
||||
fetchMock.get(FETCH_SCHEMAS_GLOB, { throws: 'error' }, { overwriteRoutes: true });
|
||||
|
||||
return wrapper
|
||||
.instance()
|
||||
.fetchSchemas(123)
|
||||
.then(() => {
|
||||
expect(fetchMock.calls(FETCH_SCHEMAS_GLOB)).toHaveLength(1);
|
||||
expect(wrapper.state().schemaOptions).toEqual([]);
|
||||
expect(dangerToastSpy.callCount).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeTable', () => {
|
||||
beforeEach(() => {
|
||||
sinon.stub(wrapper.instance(), 'fetchTables');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.instance().fetchTables.restore();
|
||||
});
|
||||
|
||||
it('test 1', () => {
|
||||
wrapper.instance().changeTable({
|
||||
value: 'birth_names',
|
||||
@@ -153,6 +201,7 @@ describe('SqlEditorLeftBar', () => {
|
||||
});
|
||||
expect(wrapper.state().tableName).toBe('birth_names');
|
||||
});
|
||||
|
||||
it('test 2', () => {
|
||||
wrapper.instance().changeTable({
|
||||
value: 'main.my_table',
|
||||
@@ -161,6 +210,7 @@ describe('SqlEditorLeftBar', () => {
|
||||
expect(wrapper.instance().fetchTables.getCall(0).args[1]).toBe('main');
|
||||
});
|
||||
});
|
||||
|
||||
it('changeSchema', () => {
|
||||
sinon.stub(wrapper.instance(), 'fetchTables');
|
||||
|
||||
|
||||
@@ -1,123 +1,175 @@
|
||||
/* eslint-disable no-unused-expressions */
|
||||
/* eslint no-unused-expressions: 0 */
|
||||
import sinon from 'sinon';
|
||||
import $ from 'jquery';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
import * as actions from '../../../src/SqlLab/actions';
|
||||
import { query } from './fixtures';
|
||||
|
||||
describe('async actions', () => {
|
||||
let ajaxStub;
|
||||
let dispatch;
|
||||
|
||||
beforeEach(() => {
|
||||
dispatch = sinon.spy();
|
||||
ajaxStub = sinon.stub($, 'ajax');
|
||||
});
|
||||
afterEach(() => {
|
||||
ajaxStub.restore();
|
||||
});
|
||||
|
||||
afterEach(fetchMock.resetHistory);
|
||||
|
||||
describe('saveQuery', () => {
|
||||
it('makes the ajax request', () => {
|
||||
const saveQueryEndpoint = 'glob:*/savedqueryviewapi/api/create';
|
||||
fetchMock.post(saveQueryEndpoint, 'ok');
|
||||
|
||||
it('posts to the correct url', () => {
|
||||
expect.assertions(1);
|
||||
const thunk = actions.saveQuery(query);
|
||||
thunk((/* mockDispatch */) => {});
|
||||
expect(ajaxStub.calledOnce).toBe(true);
|
||||
|
||||
return thunk((/* mockDispatch */) => ({})).then(() => {
|
||||
expect(fetchMock.calls(saveQueryEndpoint)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls correct url', () => {
|
||||
const url = '/savedqueryviewapi/api/create';
|
||||
it('posts the correct query object', () => {
|
||||
const thunk = actions.saveQuery(query);
|
||||
thunk((/* mockDispatch */) => {});
|
||||
expect(ajaxStub.getCall(0).args[0].url).toBe(url);
|
||||
|
||||
return thunk((/* mockDispatch */) => ({})).then(() => {
|
||||
const call = fetchMock.calls(saveQueryEndpoint)[0];
|
||||
const formData = call[1].body;
|
||||
Object.keys(query).forEach((key) => {
|
||||
expect(formData.get(key)).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchQueryResults', () => {
|
||||
const fetchQueryEndpoint = 'glob:*/superset/results/*';
|
||||
fetchMock.get(fetchQueryEndpoint, '{ "data": "" }');
|
||||
|
||||
const makeRequest = () => {
|
||||
const request = actions.fetchQueryResults(query);
|
||||
request(dispatch);
|
||||
const actionThunk = actions.fetchQueryResults(query);
|
||||
return actionThunk(dispatch);
|
||||
};
|
||||
|
||||
it('makes the ajax request', () => {
|
||||
makeRequest();
|
||||
expect(ajaxStub.calledOnce).toBe(true);
|
||||
});
|
||||
it('makes the fetch request', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
it('calls correct url', () => {
|
||||
const url = `/superset/results/${query.resultsKey}/`;
|
||||
makeRequest();
|
||||
expect(ajaxStub.getCall(0).args[0].url).toBe(url);
|
||||
return makeRequest().then(() => {
|
||||
expect(fetchMock.calls(fetchQueryEndpoint)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls requestQueryResults', () => {
|
||||
makeRequest();
|
||||
expect(dispatch.args[0][0].type).toBe(actions.REQUEST_QUERY_RESULTS);
|
||||
expect.assertions(1);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.args[0][0].type).toBe(actions.REQUEST_QUERY_RESULTS);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls querySuccess on ajax success', () => {
|
||||
ajaxStub.yieldsTo('success', '{ "data": "" }');
|
||||
makeRequest();
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_SUCCESS);
|
||||
});
|
||||
it('calls querySuccess on fetch success', () =>
|
||||
makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_SUCCESS);
|
||||
}));
|
||||
|
||||
it('calls queryFailed on ajax error', () => {
|
||||
ajaxStub.yieldsTo('error', { responseJSON: { error: 'error text' } });
|
||||
makeRequest();
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_FAILED);
|
||||
it('calls queryFailed on fetch error', () => {
|
||||
expect.assertions(2);
|
||||
fetchMock.get(
|
||||
fetchQueryEndpoint,
|
||||
{ throws: { error: 'error text' } },
|
||||
{ overwriteRoutes: true },
|
||||
);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_FAILED);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('runQuery', () => {
|
||||
const runQueryEndpoint = 'glob:*/superset/sql_json/*';
|
||||
fetchMock.post(runQueryEndpoint, { data: '' });
|
||||
|
||||
const makeRequest = () => {
|
||||
const request = actions.runQuery(query);
|
||||
request(dispatch);
|
||||
return request(dispatch);
|
||||
};
|
||||
|
||||
it('makes the ajax request', () => {
|
||||
makeRequest();
|
||||
expect(ajaxStub.calledOnce).toBe(true);
|
||||
it('makes the fetch request', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(fetchMock.calls(runQueryEndpoint)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls startQuery', () => {
|
||||
makeRequest();
|
||||
expect(dispatch.args[0][0].type).toBe(actions.START_QUERY);
|
||||
expect.assertions(1);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.args[0][0].type).toBe(actions.START_QUERY);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls queryFailed on ajax error', () => {
|
||||
ajaxStub.yieldsTo('error', { responseJSON: { error: 'error text' } });
|
||||
makeRequest();
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_FAILED);
|
||||
it('calls querySuccess on fetch success', () => {
|
||||
expect.assertions(3);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(0).args[0].type).toBe(actions.START_QUERY);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_SUCCESS);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls queryFailed on fetch error', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
fetchMock.post(
|
||||
runQueryEndpoint,
|
||||
{ throws: { error: 'error text' } },
|
||||
{ overwriteRoutes: true },
|
||||
);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0].type).toBe(actions.QUERY_FAILED);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('postStopQuery', () => {
|
||||
const stopQueryEndpoint = 'glob:*/superset/stop_query/*';
|
||||
fetchMock.post(stopQueryEndpoint, {});
|
||||
|
||||
const makeRequest = () => {
|
||||
const request = actions.postStopQuery(query);
|
||||
request(dispatch);
|
||||
return request(dispatch);
|
||||
};
|
||||
|
||||
it('makes the ajax request', () => {
|
||||
makeRequest();
|
||||
expect(ajaxStub.calledOnce).toBe(true);
|
||||
it('makes the fetch request', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(fetchMock.calls(stopQueryEndpoint)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('calls stopQuery', () => {
|
||||
makeRequest();
|
||||
expect(dispatch.args[0][0].type).toBe(actions.STOP_QUERY);
|
||||
});
|
||||
expect.assertions(1);
|
||||
|
||||
it('calls the correct url', () => {
|
||||
const url = '/superset/stop_query/';
|
||||
makeRequest();
|
||||
expect(ajaxStub.getCall(0).args[0].url).toBe(url);
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.getCall(0).args[0].type).toBe(actions.STOP_QUERY);
|
||||
});
|
||||
});
|
||||
|
||||
it('sends the correct data', () => {
|
||||
const data = { client_id: query.id };
|
||||
makeRequest();
|
||||
expect(ajaxStub.getCall(0).args[0].data).toEqual(data);
|
||||
expect.assertions(1);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
const call = fetchMock.calls(stopQueryEndpoint)[0];
|
||||
expect(call[1].body.get('client_id')).toBe(query.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,32 +20,24 @@ export const table = {
|
||||
indexes: [
|
||||
{
|
||||
unique: true,
|
||||
column_names: [
|
||||
'username',
|
||||
],
|
||||
column_names: ['username'],
|
||||
type: 'UNIQUE',
|
||||
name: 'username',
|
||||
},
|
||||
{
|
||||
unique: true,
|
||||
column_names: [
|
||||
'email',
|
||||
],
|
||||
column_names: ['email'],
|
||||
type: 'UNIQUE',
|
||||
name: 'email',
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'created_by_fk',
|
||||
],
|
||||
column_names: ['created_by_fk'],
|
||||
name: 'created_by_fk',
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'changed_by_fk',
|
||||
],
|
||||
column_names: ['changed_by_fk'],
|
||||
name: 'changed_by_fk',
|
||||
},
|
||||
],
|
||||
@@ -70,13 +62,9 @@ export const table = {
|
||||
name: 'first_name',
|
||||
keys: [
|
||||
{
|
||||
column_names: [
|
||||
'first_name',
|
||||
],
|
||||
column_names: ['first_name'],
|
||||
name: 'slices_ibfk_1',
|
||||
referred_columns: [
|
||||
'id',
|
||||
],
|
||||
referred_columns: ['id'],
|
||||
referred_table: 'datasources',
|
||||
type: 'fk',
|
||||
referred_schema: 'carapal',
|
||||
@@ -84,9 +72,7 @@ export const table = {
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'druid_datasource_id',
|
||||
],
|
||||
column_names: ['druid_datasource_id'],
|
||||
type: 'index',
|
||||
name: 'druid_datasource_id',
|
||||
},
|
||||
@@ -205,21 +191,21 @@ export const queries = [
|
||||
serverId: 141,
|
||||
resultsKey: null,
|
||||
results: {
|
||||
columns: [{
|
||||
is_date: true,
|
||||
is_dim: false,
|
||||
name: 'ds',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'gender',
|
||||
type: 'STRING',
|
||||
}],
|
||||
data: [
|
||||
{ col1: 0, col2: 1 },
|
||||
{ col1: 2, col2: 3 },
|
||||
columns: [
|
||||
{
|
||||
is_date: true,
|
||||
is_dim: false,
|
||||
name: 'ds',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'gender',
|
||||
type: 'STRING',
|
||||
},
|
||||
],
|
||||
data: [{ col1: 0, col2: 1 }, { col1: 2, col2: 3 }],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -237,12 +223,11 @@ export const queries = [
|
||||
changedOn: 1476910572000,
|
||||
tempTable: null,
|
||||
userId: 1,
|
||||
executedSql: (
|
||||
executedSql:
|
||||
'SELECT * \nFROM (SELECT created_on, changed_on, id, slice_name, ' +
|
||||
'druid_datasource_id, table_id, datasource_type, datasource_name, ' +
|
||||
'viz_type, params, created_by_fk, changed_by_fk, description, ' +
|
||||
'cache_timeout, perm\nFROM superset.slices) AS inner_qry \n LIMIT 1000'
|
||||
),
|
||||
'cache_timeout, perm\nFROM superset.slices) AS inner_qry \n LIMIT 1000',
|
||||
changed_on: '2016-10-19T20:56:12',
|
||||
rows: 42,
|
||||
endDttm: 1476910579693,
|
||||
@@ -261,72 +246,86 @@ export const queryWithBadColumns = {
|
||||
...queries[0],
|
||||
results: {
|
||||
data: queries[0].results.data,
|
||||
columns: [{
|
||||
is_date: true,
|
||||
is_dim: false,
|
||||
name: 'COUNT(*)',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'this_col_is_ok',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'a',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: '1',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: '123',
|
||||
type: 'STRING',
|
||||
}, {
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'CASE WHEN 1=1 THEN 1 ELSE 0 END',
|
||||
type: 'STRING',
|
||||
}],
|
||||
columns: [
|
||||
{
|
||||
is_date: true,
|
||||
is_dim: false,
|
||||
name: 'COUNT(*)',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'this_col_is_ok',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'a',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: '1',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: '123',
|
||||
type: 'STRING',
|
||||
},
|
||||
{
|
||||
is_date: false,
|
||||
is_dim: true,
|
||||
name: 'CASE WHEN 1=1 THEN 1 ELSE 0 END',
|
||||
type: 'STRING',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export const databases = {
|
||||
result: [{
|
||||
allow_ctas: true,
|
||||
allow_dml: true,
|
||||
allow_run_async: false,
|
||||
allow_run_sync: true,
|
||||
database_name: 'main',
|
||||
expose_in_sqllab: true,
|
||||
force_ctas_schema: '',
|
||||
id: 1,
|
||||
}, {
|
||||
allow_ctas: true,
|
||||
allow_dml: false,
|
||||
allow_run_async: true,
|
||||
allow_run_sync: true,
|
||||
database_name: 'Presto - Gold',
|
||||
expose_in_sqllab: true,
|
||||
force_ctas_schema: 'tmp',
|
||||
id: 208,
|
||||
}],
|
||||
result: [
|
||||
{
|
||||
allow_ctas: true,
|
||||
allow_dml: true,
|
||||
allow_run_async: false,
|
||||
allow_run_sync: true,
|
||||
database_name: 'main',
|
||||
expose_in_sqllab: true,
|
||||
force_ctas_schema: '',
|
||||
id: 1,
|
||||
},
|
||||
{
|
||||
allow_ctas: true,
|
||||
allow_dml: false,
|
||||
allow_run_async: true,
|
||||
allow_run_sync: true,
|
||||
database_name: 'Presto - Gold',
|
||||
expose_in_sqllab: true,
|
||||
force_ctas_schema: 'tmp',
|
||||
id: 208,
|
||||
},
|
||||
],
|
||||
};
|
||||
export const tables = {
|
||||
tableLength: 3,
|
||||
options: [{
|
||||
value: 'birth_names',
|
||||
label: 'birth_names',
|
||||
}, {
|
||||
value: 'energy_usage',
|
||||
label: 'energy_usage',
|
||||
}, {
|
||||
value: 'wb_health_population',
|
||||
label: 'wb_health_population',
|
||||
}],
|
||||
options: [
|
||||
{
|
||||
value: 'birth_names',
|
||||
label: 'birth_names',
|
||||
},
|
||||
{
|
||||
value: 'energy_usage',
|
||||
label: 'energy_usage',
|
||||
},
|
||||
{
|
||||
value: 'wb_health_population',
|
||||
label: 'wb_health_population',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const stoppedQuery = {
|
||||
@@ -371,6 +370,7 @@ export const initialState = {
|
||||
};
|
||||
|
||||
export const query = {
|
||||
id: 'clientId2353',
|
||||
dbId: 1,
|
||||
sql: 'SELECT * FROM something',
|
||||
sqlEditorId: defaultQueryEditor.id,
|
||||
|
||||
Reference in New Issue
Block a user