mirror of
https://github.com/apache/superset.git
synced 2026-04-19 16:14:52 +00:00
[WiP] rename project from Caravel to Superset (#1576)
* Change in files * Renamin files and folders * cleaning up a single piece of lint * Removing boat picture from docs * add superset word mark * Update rename note in docs * Fixing images * Pinning datatables * Fixing issues with mapbox-gl * Forgot to rename one file * Linting * v0.13.0 * adding pyyaml to dev-reqs
This commit is contained in:
committed by
GitHub
parent
973537fd9a
commit
15b67b2c6c
24
superset/assets/spec/javascripts/sqllab/Alerts_spec.jsx
Normal file
24
superset/assets/spec/javascripts/sqllab/Alerts_spec.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import Alerts from '../../../javascripts/SqlLab/components/Alerts';
|
||||
import { Alert } from 'react-bootstrap';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { alert } from './fixtures';
|
||||
|
||||
|
||||
describe('Alerts', () => {
|
||||
const mockedProps = {
|
||||
alerts: [alert],
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(React.isValidElement(<Alerts />)).to.equal(true);
|
||||
});
|
||||
it('is valid with props', () => {
|
||||
expect(React.isValidElement(<Alerts {...mockedProps} />)).to.equal(true);
|
||||
});
|
||||
it('renders an Alert', () => {
|
||||
const wrapper = shallow(<Alerts {...mockedProps} />);
|
||||
expect(wrapper.find(Alert)).to.have.length(1);
|
||||
});
|
||||
});
|
||||
11
superset/assets/spec/javascripts/sqllab/App_spec.jsx
Normal file
11
superset/assets/spec/javascripts/sqllab/App_spec.jsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import App from '../../../javascripts/SqlLab/components/App';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('App', () => {
|
||||
it('is valid', () => {
|
||||
expect(React.isValidElement(<App />)).to.equal(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import ColumnElement from '../../../javascripts/SqlLab/components/ColumnElement';
|
||||
import { mockedActions, table } from './fixtures';
|
||||
import { mount } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('ColumnElement', () => {
|
||||
const mockedProps = {
|
||||
actions: mockedActions,
|
||||
column: table.columns[0],
|
||||
};
|
||||
it('is valid with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<ColumnElement {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders a proper primary key', () => {
|
||||
const wrapper = mount(<ColumnElement column={table.columns[0]} />);
|
||||
expect(wrapper.find('i.fa-key')).to.have.length(1);
|
||||
expect(wrapper.find('.col-name').first().text()).to.equal('id');
|
||||
});
|
||||
it('renders a multi-key column', () => {
|
||||
const wrapper = mount(<ColumnElement column={table.columns[1]} />);
|
||||
expect(wrapper.find('i.fa-link')).to.have.length(1);
|
||||
expect(wrapper.find('i.fa-bookmark')).to.have.length(1);
|
||||
expect(wrapper.find('.col-name').first().text()).to.equal('first_name');
|
||||
});
|
||||
it('renders a column with no keys', () => {
|
||||
const wrapper = mount(<ColumnElement column={table.columns[2]} />);
|
||||
expect(wrapper.find('i')).to.have.length(0);
|
||||
expect(wrapper.find('.col-name').first().text()).to.equal('last_name');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import CopyQueryTabUrl from '../../../javascripts/SqlLab/components/CopyQueryTabUrl';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { initialState } from './fixtures';
|
||||
|
||||
describe('CopyQueryTabUrl', () => {
|
||||
const mockedProps = {
|
||||
queryEditor: initialState.queryEditors[0],
|
||||
};
|
||||
it('is valid with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<CopyQueryTabUrl {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import DatabaseSelect from '../../../javascripts/SqlLab/components/DatabaseSelect';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
|
||||
describe('DatabaseSelect', () => {
|
||||
const mockedProps = {
|
||||
actions: {},
|
||||
};
|
||||
it('is valid element', () => {
|
||||
expect(
|
||||
React.isValidElement(<DatabaseSelect {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
|
||||
it('has one select', () => {
|
||||
const wrapper = shallow(
|
||||
<DatabaseSelect {...mockedProps} />
|
||||
);
|
||||
expect(wrapper.find(Select)).to.have.length(1);
|
||||
});
|
||||
|
||||
it('calls onChange on select change', () => {
|
||||
const onChange = sinon.spy();
|
||||
const wrapper = shallow(
|
||||
<DatabaseSelect onChange={onChange} />
|
||||
);
|
||||
wrapper.find(Select).simulate('change', { value: 1 });
|
||||
expect(onChange).to.have.property('callCount', 1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import HighlightedSql from '../../../javascripts/SqlLab/components/HighlightedSql';
|
||||
import ModalTrigger from '../../../javascripts/components/ModalTrigger';
|
||||
import SyntaxHighlighter from 'react-syntax-highlighter';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('HighlightedSql', () => {
|
||||
const sql = "SELECT * FROM test WHERE something='fkldasjfklajdslfkjadlskfjkldasjfkladsjfkdjsa'";
|
||||
it('renders with props', () => {
|
||||
expect(React.isValidElement(<HighlightedSql sql={sql} />))
|
||||
.to.equal(true);
|
||||
});
|
||||
it('renders a ModalTrigger', () => {
|
||||
const wrapper = shallow(<HighlightedSql sql={sql} />);
|
||||
expect(wrapper.find(ModalTrigger)).to.have.length(1);
|
||||
});
|
||||
it('renders a ModalTrigger while using shrink', () => {
|
||||
const wrapper = shallow(<HighlightedSql sql={sql} shrink maxWidth={20} />);
|
||||
expect(wrapper.find(ModalTrigger)).to.have.length(1);
|
||||
});
|
||||
it('renders two SyntaxHighlighter in modal', () => {
|
||||
const wrapper = mount(
|
||||
<HighlightedSql sql={sql} rawSql="SELECT * FORM foo" shrink maxWidth={5} />);
|
||||
const well = wrapper.find('.well');
|
||||
expect(well).to.have.length(1);
|
||||
well.simulate('click');
|
||||
const modalBody = mount(wrapper.state().modalBody);
|
||||
expect(modalBody.find(SyntaxHighlighter)).to.have.length(2);
|
||||
});
|
||||
});
|
||||
25
superset/assets/spec/javascripts/sqllab/Link_spec.jsx
Normal file
25
superset/assets/spec/javascripts/sqllab/Link_spec.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import Link from '../../../javascripts/SqlLab/components/Link';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('Link', () => {
|
||||
const mockedProps = {
|
||||
tooltip: 'This is a tooltip',
|
||||
href: 'http://www.airbnb.com',
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<Link>TEST</Link>)).to.equal(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<Link {...mockedProps} >TEST</Link>)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders an anchor tag', () => {
|
||||
const wrapper = shallow(<Link {...mockedProps} >TEST</Link>);
|
||||
expect(wrapper.find('a')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
68
superset/assets/spec/javascripts/sqllab/QuerySearch_spec.jsx
Normal file
68
superset/assets/spec/javascripts/sqllab/QuerySearch_spec.jsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import QuerySearch from '../../../javascripts/SqlLab/components/QuerySearch';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
|
||||
describe('QuerySearch', () => {
|
||||
const mockedProps = {
|
||||
actions: {},
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<QuerySearch {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
const wrapper = shallow(<QuerySearch {...mockedProps} />);
|
||||
|
||||
it('should have four Select', () => {
|
||||
expect(wrapper.find(Select)).to.have.length(4);
|
||||
});
|
||||
|
||||
it('updates userId on user selects change', () => {
|
||||
wrapper.find('[name="select-user"]')
|
||||
.simulate('change', { value: 1 });
|
||||
expect(wrapper.state().userId).to.equal(1);
|
||||
});
|
||||
|
||||
it('updates fromTime on user selects from time', () => {
|
||||
wrapper.find('[name="select-from"]')
|
||||
.simulate('change', { value: 0 });
|
||||
expect(wrapper.state().from).to.equal(0);
|
||||
});
|
||||
|
||||
it('updates toTime on user selects to time', () => {
|
||||
wrapper.find('[name="select-to"]')
|
||||
.simulate('change', { value: 0 });
|
||||
expect(wrapper.state().to).to.equal(0);
|
||||
});
|
||||
|
||||
it('updates status on user selects status', () => {
|
||||
wrapper.find('[name="select-status"]')
|
||||
.simulate('change', { value: 'success' });
|
||||
expect(wrapper.state().status).to.equal('success');
|
||||
});
|
||||
|
||||
it('should have one input for searchText', () => {
|
||||
expect(wrapper.find('input')).to.have.length(1);
|
||||
});
|
||||
|
||||
it('updates search text on user inputs search text', () => {
|
||||
wrapper.find('input').simulate('change', { target: { value: 'text' } });
|
||||
expect(wrapper.state().searchText).to.equal('text');
|
||||
});
|
||||
|
||||
it('should have one Button', () => {
|
||||
expect(wrapper.find(Button)).to.have.length(1);
|
||||
});
|
||||
|
||||
it('refreshes queries when clicked', () => {
|
||||
const search = sinon.spy(QuerySearch.prototype, 'refreshQueries');
|
||||
wrapper.find(Button).simulate('click');
|
||||
/* eslint-disable no-unused-expressions */
|
||||
expect(search).to.have.been.called;
|
||||
});
|
||||
});
|
||||
26
superset/assets/spec/javascripts/sqllab/QueryTable_spec.jsx
Normal file
26
superset/assets/spec/javascripts/sqllab/QueryTable_spec.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import QueryTable from '../../../javascripts/SqlLab/components/QueryTable';
|
||||
import { queries } from './fixtures';
|
||||
import { mount } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('QueryTable', () => {
|
||||
const mockedProps = {
|
||||
queries,
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(React.isValidElement(<QueryTable />)).to.equal(true);
|
||||
});
|
||||
it('is valid with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<QueryTable {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders a proper table', () => {
|
||||
const wrapper = mount(<QueryTable {...mockedProps} />);
|
||||
expect(wrapper.find('table')).to.have.length(1);
|
||||
expect(wrapper.find('tr')).to.have.length(3);
|
||||
});
|
||||
});
|
||||
25
superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx
Normal file
25
superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import ResultSet from '../../../javascripts/SqlLab/components/ResultSet';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { queries } from './fixtures';
|
||||
import { Table } from 'reactable';
|
||||
|
||||
describe('ResultSet', () => {
|
||||
const mockedProps = {
|
||||
query: queries[0],
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<ResultSet />)).to.equal(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<ResultSet />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders a Table', () => {
|
||||
const wrapper = shallow(<ResultSet {...mockedProps} />);
|
||||
expect(wrapper.find(Table)).to.have.length(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import SqlEditorLeftBar from '../../../javascripts/SqlLab/components/SqlEditorLeftBar';
|
||||
import TableElement from '../../../javascripts/SqlLab/components/TableElement';
|
||||
import { mount } from 'enzyme';
|
||||
import { table, defaultQueryEditor } from './fixtures';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('SqlEditorLeftBar', () => {
|
||||
const mockedProps = {
|
||||
tables: [table],
|
||||
queryEditor: defaultQueryEditor,
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<SqlEditorLeftBar {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders a TableElement', () => {
|
||||
const wrapper = mount(<SqlEditorLeftBar {...mockedProps} />);
|
||||
expect(wrapper.find(TableElement)).to.have.length(1);
|
||||
});
|
||||
});
|
||||
27
superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx
Normal file
27
superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import SqlEditor from '../../../javascripts/SqlLab/components/SqlEditor';
|
||||
import SqlEditorLeftBar from '../../../javascripts/SqlLab/components/SqlEditorLeftBar';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { initialState, queries, table } from './fixtures';
|
||||
|
||||
describe('SqlEditor', () => {
|
||||
const mockedProps = {
|
||||
actions: {},
|
||||
database: {},
|
||||
queryEditor: initialState.queryEditors[0],
|
||||
latestQuery: queries[0],
|
||||
tables: [table],
|
||||
queries,
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<SqlEditor {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('render a SqlEditorLeftBar', () => {
|
||||
const wrapper = shallow(<SqlEditor {...mockedProps} />);
|
||||
expect(wrapper.find(SqlEditorLeftBar)).to.have.length(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { TabbedSqlEditors } from '../../../javascripts/SqlLab/components/TabbedSqlEditors';
|
||||
import { Tab } from 'react-bootstrap';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { initialState } from './fixtures';
|
||||
|
||||
describe('TabbedSqlEditors', () => {
|
||||
const mockedProps = {
|
||||
actions: {},
|
||||
databases: {},
|
||||
tables: [],
|
||||
queries: {},
|
||||
queryEditors: initialState.queryEditors,
|
||||
tabHistory: initialState.tabHistory,
|
||||
};
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<TabbedSqlEditors {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('shallow mounts', () => {
|
||||
const wrapper = shallow(<TabbedSqlEditors {...mockedProps} />);
|
||||
expect(wrapper.find(Tab)).to.have.length(2);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import Link from '../../../javascripts/SqlLab/components/Link';
|
||||
import TableElement from '../../../javascripts/SqlLab/components/TableElement';
|
||||
import ColumnElement from '../../../javascripts/SqlLab/components/ColumnElement';
|
||||
import { mockedActions, table } from './fixtures';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('TableElement', () => {
|
||||
const mockedProps = {
|
||||
actions: mockedActions,
|
||||
table,
|
||||
timeout: 0,
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(
|
||||
React.isValidElement(<TableElement />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<TableElement {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('has 2 Link elements', () => {
|
||||
const wrapper = shallow(<TableElement {...mockedProps} />);
|
||||
expect(wrapper.find(Link)).to.have.length(2);
|
||||
});
|
||||
it('has 14 columns', () => {
|
||||
const wrapper = shallow(<TableElement {...mockedProps} />);
|
||||
expect(wrapper.find(ColumnElement)).to.have.length(14);
|
||||
});
|
||||
it('mounts', () => {
|
||||
mount(<TableElement {...mockedProps} />);
|
||||
});
|
||||
it('sorts columns', () => {
|
||||
const wrapper = mount(<TableElement {...mockedProps} />);
|
||||
expect(wrapper.state().sortColumns).to.equal(false);
|
||||
expect(wrapper.find(ColumnElement).first().props().column.name).to.equal('id');
|
||||
wrapper.find('.sort-cols').simulate('click');
|
||||
expect(wrapper.state().sortColumns).to.equal(true);
|
||||
expect(wrapper.find(ColumnElement).first().props().column.name).to.equal('last_login');
|
||||
});
|
||||
it('calls the collapseTable action', () => {
|
||||
const wrapper = mount(<TableElement {...mockedProps} />);
|
||||
expect(mockedActions.collapseTable.called).to.equal(false);
|
||||
wrapper.find('.table-name').simulate('click');
|
||||
expect(mockedActions.collapseTable.called).to.equal(true);
|
||||
});
|
||||
it('removes the table', () => {
|
||||
const wrapper = mount(<TableElement {...mockedProps} />);
|
||||
expect(wrapper.state().expanded).to.equal(true);
|
||||
wrapper.find('.table-remove').simulate('click');
|
||||
expect(wrapper.state().expanded).to.equal(false);
|
||||
setTimeout(() => {
|
||||
expect(mockedActions.removeTable.called).to.equal(true);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
24
superset/assets/spec/javascripts/sqllab/Timer_spec.jsx
Normal file
24
superset/assets/spec/javascripts/sqllab/Timer_spec.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import Timer from '../../../javascripts/SqlLab/components/Timer';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { queries } from './fixtures';
|
||||
|
||||
|
||||
describe('Timer', () => {
|
||||
const mockedProps = {
|
||||
query: queries[0],
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<Timer />)).to.equal(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(React.isValidElement(<Timer {...mockedProps} />))
|
||||
.to.equal(true);
|
||||
});
|
||||
it('renders a span', () => {
|
||||
const wrapper = shallow(<Timer {...mockedProps} />);
|
||||
expect(wrapper.find('span')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import VisualizeModal from '../../../javascripts/SqlLab/components/VisualizeModal';
|
||||
import { queries } from './fixtures';
|
||||
import { Modal } from 'react-bootstrap';
|
||||
import { shallow } from 'enzyme';
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
|
||||
describe('VisualizeModal', () => {
|
||||
const mockedProps = {
|
||||
show: true,
|
||||
query: queries[0],
|
||||
};
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<VisualizeModal />)).to.equal(true);
|
||||
});
|
||||
it('renders with props', () => {
|
||||
expect(
|
||||
React.isValidElement(<VisualizeModal {...mockedProps} />)
|
||||
).to.equal(true);
|
||||
});
|
||||
it('renders a Modal', () => {
|
||||
const wrapper = shallow(<VisualizeModal {...mockedProps} />);
|
||||
expect(wrapper.find(Modal)).to.have.length(1);
|
||||
});
|
||||
});
|
||||
273
superset/assets/spec/javascripts/sqllab/fixtures.js
Normal file
273
superset/assets/spec/javascripts/sqllab/fixtures.js
Normal file
@@ -0,0 +1,273 @@
|
||||
import * as actions from '../../../javascripts/SqlLab/actions';
|
||||
import sinon from 'sinon';
|
||||
|
||||
export const mockedActions = sinon.stub(Object.assign({}, actions));
|
||||
|
||||
export const alert = { bsStyle: 'danger', msg: 'Ooops', id: 'lksvmcx32' };
|
||||
export const table = {
|
||||
dbId: 1,
|
||||
selectStar: 'SELECT * FROM ab_user',
|
||||
queryEditorId: 'rJ-KP47a',
|
||||
schema: 'superset',
|
||||
name: 'ab_user',
|
||||
id: 'r11Vgt60',
|
||||
dataPreviewQueryId: null,
|
||||
partitions: {
|
||||
cols: ['username'],
|
||||
latest: 'bob',
|
||||
partitionQuery: 'SHOW PARTITIONS FROM ab_user',
|
||||
},
|
||||
indexes: [
|
||||
{
|
||||
unique: true,
|
||||
column_names: [
|
||||
'username',
|
||||
],
|
||||
type: 'UNIQUE',
|
||||
name: 'username',
|
||||
},
|
||||
{
|
||||
unique: true,
|
||||
column_names: [
|
||||
'email',
|
||||
],
|
||||
type: 'UNIQUE',
|
||||
name: 'email',
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'created_by_fk',
|
||||
],
|
||||
name: 'created_by_fk',
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'changed_by_fk',
|
||||
],
|
||||
name: 'changed_by_fk',
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'INTEGER(11)',
|
||||
type: 'INTEGER',
|
||||
name: 'id',
|
||||
keys: [
|
||||
{
|
||||
column_names: ['id'],
|
||||
type: 'pk',
|
||||
name: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'VARCHAR(64)',
|
||||
type: 'VARCHAR',
|
||||
name: 'first_name',
|
||||
keys: [
|
||||
{
|
||||
column_names: [
|
||||
'first_name',
|
||||
],
|
||||
name: 'slices_ibfk_1',
|
||||
referred_columns: [
|
||||
'id',
|
||||
],
|
||||
referred_table: 'datasources',
|
||||
type: 'fk',
|
||||
referred_schema: 'carapal',
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
column_names: [
|
||||
'druid_datasource_id',
|
||||
],
|
||||
type: 'index',
|
||||
name: 'druid_datasource_id',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'VARCHAR(64)',
|
||||
type: 'VARCHAR',
|
||||
name: 'last_name',
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
longType: 'VARCHAR(64)',
|
||||
type: 'VARCHAR',
|
||||
name: 'username',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'VARCHAR(256)',
|
||||
type: 'VARCHAR',
|
||||
name: 'password',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'TINYINT(1)',
|
||||
type: 'TINYINT',
|
||||
name: 'active',
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
longType: 'VARCHAR(64)',
|
||||
type: 'VARCHAR',
|
||||
name: 'email',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'DATETIME',
|
||||
type: 'DATETIME',
|
||||
name: 'last_login',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'INTEGER(11)',
|
||||
type: 'INTEGER',
|
||||
name: 'login_count',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'INTEGER(11)',
|
||||
type: 'INTEGER',
|
||||
name: 'fail_login_count',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'DATETIME',
|
||||
type: 'DATETIME',
|
||||
name: 'created_on',
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
longType: 'DATETIME',
|
||||
type: 'DATETIME',
|
||||
name: 'changed_on',
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
longType: 'INTEGER(11)',
|
||||
type: 'INTEGER',
|
||||
name: 'created_by_fk',
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
longType: 'INTEGER(11)',
|
||||
type: 'INTEGER',
|
||||
name: 'changed_by_fk',
|
||||
},
|
||||
],
|
||||
expanded: true,
|
||||
};
|
||||
export const defaultQueryEditor = {
|
||||
id: 'dfsadfs',
|
||||
autorun: false,
|
||||
dbId: null,
|
||||
latestQueryId: null,
|
||||
selectedText: null,
|
||||
sql: 'SELECT *\nFROM\nWHERE',
|
||||
title: 'Untitled Query',
|
||||
};
|
||||
export const queries = [
|
||||
{
|
||||
dbId: 1,
|
||||
sql: 'SELECT *FROM superset.slices',
|
||||
sqlEditorId: 'SJ8YO72R',
|
||||
tab: 'Demo',
|
||||
runAsync: false,
|
||||
ctas: false,
|
||||
cached: false,
|
||||
id: 'BkA1CLrJg',
|
||||
progress: 100,
|
||||
startDttm: 1476910566092.96,
|
||||
state: 'success',
|
||||
changedOn: 1476910566000,
|
||||
tempTable: null,
|
||||
userId: 1,
|
||||
executedSql: null,
|
||||
changed_on: '2016-10-19T20:56:06',
|
||||
rows: 42,
|
||||
endDttm: 1476910566798,
|
||||
limit_reached: false,
|
||||
schema: null,
|
||||
errorMessage: null,
|
||||
db: 'main',
|
||||
user: 'admin',
|
||||
limit: 1000,
|
||||
serverId: 141,
|
||||
resultsKey: null,
|
||||
results: {
|
||||
columns: ['col1', 'col2'],
|
||||
data: [
|
||||
{ col1: 0, col2: 1 },
|
||||
{ col1: 2, col2: 3 },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
dbId: 1,
|
||||
sql: 'SELECT *FROM superset.slices',
|
||||
sqlEditorId: 'SJ8YO72R',
|
||||
tab: 'Demo',
|
||||
runAsync: true,
|
||||
ctas: false,
|
||||
cached: false,
|
||||
id: 'S1zeAISkx',
|
||||
progress: 100,
|
||||
startDttm: 1476910570802.2,
|
||||
state: 'success',
|
||||
changedOn: 1476910572000,
|
||||
tempTable: null,
|
||||
userId: 1,
|
||||
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'
|
||||
),
|
||||
changed_on: '2016-10-19T20:56:12',
|
||||
rows: 42,
|
||||
endDttm: 1476910579693,
|
||||
limit_reached: false,
|
||||
schema: null,
|
||||
errorMessage: null,
|
||||
db: 'main',
|
||||
user: 'admin',
|
||||
limit: 1000,
|
||||
serverId: 142,
|
||||
resultsKey: '417149f4-cd27-4f80-91f3-c45c871003f7',
|
||||
results: null,
|
||||
},
|
||||
];
|
||||
|
||||
export const initialState = {
|
||||
alerts: [],
|
||||
networkOn: true,
|
||||
queries: {},
|
||||
databases: {},
|
||||
queryEditors: [defaultQueryEditor],
|
||||
tabHistory: [defaultQueryEditor.id],
|
||||
tables: [],
|
||||
workspaceQueries: [],
|
||||
queriesLastUpdate: 0,
|
||||
activeSouthPaneTab: 'Results',
|
||||
};
|
||||
|
||||
export const query = {
|
||||
dbId: 1,
|
||||
sql: 'SELECT * FROM something',
|
||||
sqlEditorId: defaultQueryEditor.id,
|
||||
tab: 'unimportant',
|
||||
tempTableName: null,
|
||||
runAsync: false,
|
||||
ctas: false,
|
||||
cached: false,
|
||||
};
|
||||
156
superset/assets/spec/javascripts/sqllab/reducers_spec.js
Normal file
156
superset/assets/spec/javascripts/sqllab/reducers_spec.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import * as r from '../../../javascripts/SqlLab/reducers';
|
||||
import * as actions from '../../../javascripts/SqlLab/actions';
|
||||
import { beforeEach, describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { alert, table, initialState } from './fixtures';
|
||||
|
||||
describe('sqlLabReducer', () => {
|
||||
describe('CLONE_QUERY_TO_NEW_TAB', () => {
|
||||
const testQuery = { sql: 'SELECT * FROM...', dbId: 1, id: 'flasj233' };
|
||||
let newState = Object.assign({}, initialState, { queries: { [testQuery.id]: testQuery } });
|
||||
newState = r.sqlLabReducer(newState, actions.cloneQueryToNewTab(testQuery));
|
||||
|
||||
it('should have at most one more tab', () => {
|
||||
expect(newState.queryEditors).have.length(2);
|
||||
});
|
||||
|
||||
it('should have the same SQL as the cloned query', () => {
|
||||
expect(newState.queryEditors[1].sql).to.equal(testQuery.sql);
|
||||
});
|
||||
|
||||
it('should prefix the new tab title with "Copy of"', () => {
|
||||
expect(newState.queryEditors[1].title).to.include('Copy of');
|
||||
});
|
||||
|
||||
it('should push the cloned tab onto tab history stack', () => {
|
||||
expect(newState.tabHistory[1]).to.eq(newState.queryEditors[1].id);
|
||||
});
|
||||
});
|
||||
describe('Alerts', () => {
|
||||
const state = Object.assign({}, initialState);
|
||||
let newState;
|
||||
it('should add one alert', () => {
|
||||
newState = r.sqlLabReducer(state, actions.addAlert(alert));
|
||||
expect(newState.alerts).to.have.lengthOf(1);
|
||||
});
|
||||
it('should remove one alert', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.removeAlert(newState.alerts[0]));
|
||||
expect(newState.alerts).to.have.lengthOf(0);
|
||||
});
|
||||
});
|
||||
describe('Query editors actions', () => {
|
||||
let newState;
|
||||
let defaultQueryEditor;
|
||||
let qe;
|
||||
beforeEach(() => {
|
||||
newState = Object.assign({}, initialState);
|
||||
defaultQueryEditor = newState.queryEditors[0];
|
||||
qe = Object.assign({}, defaultQueryEditor);
|
||||
newState = r.sqlLabReducer(newState, actions.addQueryEditor(qe));
|
||||
qe = newState.queryEditors[newState.queryEditors.length - 1];
|
||||
});
|
||||
it('should add a query editor', () => {
|
||||
expect(newState.queryEditors).to.have.lengthOf(2);
|
||||
});
|
||||
it('should remove a query editor', () => {
|
||||
expect(newState.queryEditors).to.have.lengthOf(2);
|
||||
newState = r.sqlLabReducer(newState, actions.removeQueryEditor(qe));
|
||||
expect(newState.queryEditors).to.have.lengthOf(1);
|
||||
});
|
||||
it('should set q query editor active', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.addQueryEditor(qe));
|
||||
newState = r.sqlLabReducer(newState, actions.setActiveQueryEditor(defaultQueryEditor));
|
||||
expect(newState.tabHistory[newState.tabHistory.length - 1]).equals(defaultQueryEditor.id);
|
||||
});
|
||||
it('should not fail while setting DB', () => {
|
||||
const dbId = 9;
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetDb(qe, dbId));
|
||||
expect(newState.queryEditors[1].dbId).to.equal(dbId);
|
||||
});
|
||||
it('should not fail while setting schema', () => {
|
||||
const schema = 'foo';
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetSchema(qe, schema));
|
||||
expect(newState.queryEditors[1].schema).to.equal(schema);
|
||||
});
|
||||
it('should not fail while setting autorun ', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, false));
|
||||
expect(newState.queryEditors[1].autorun).to.equal(false);
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, true));
|
||||
expect(newState.queryEditors[1].autorun).to.equal(true);
|
||||
});
|
||||
it('should not fail while setting title', () => {
|
||||
const title = 'a new title';
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetTitle(qe, title));
|
||||
expect(newState.queryEditors[1].title).to.equal(title);
|
||||
});
|
||||
it('should not fail while setting Sql', () => {
|
||||
const sql = 'SELECT nothing from dev_null';
|
||||
newState = r.sqlLabReducer(newState, actions.queryEditorSetSql(qe, sql));
|
||||
expect(newState.queryEditors[1].sql).to.equal(sql);
|
||||
});
|
||||
it('should set selectedText', () => {
|
||||
const selectedText = 'TEST';
|
||||
expect(newState.queryEditors[0].selectedText).to.equal(null);
|
||||
newState = r.sqlLabReducer(
|
||||
newState, actions.queryEditorSetSelectedText(newState.queryEditors[0], 'TEST'));
|
||||
expect(newState.queryEditors[0].selectedText).to.equal(selectedText);
|
||||
});
|
||||
});
|
||||
describe('Tables', () => {
|
||||
let newState;
|
||||
let newTable;
|
||||
beforeEach(() => {
|
||||
newTable = Object.assign({}, table);
|
||||
newState = r.sqlLabReducer(initialState, actions.mergeTable(newTable));
|
||||
newTable = newState.tables[0];
|
||||
});
|
||||
it('should add a table', () => {
|
||||
// Testing that beforeEach actually added the table
|
||||
expect(newState.tables).to.have.lengthOf(1);
|
||||
});
|
||||
it('should merge the table attributes', () => {
|
||||
// Merging the extra attribute
|
||||
newTable.extra = true;
|
||||
newState = r.sqlLabReducer(newState, actions.mergeTable(newTable));
|
||||
expect(newState.tables).to.have.lengthOf(1);
|
||||
expect(newState.tables[0].extra).to.equal(true);
|
||||
});
|
||||
it('should expand and collapse a table', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.collapseTable(newTable));
|
||||
expect(newState.tables[0].expanded).to.equal(false);
|
||||
newState = r.sqlLabReducer(newState, actions.expandTable(newTable));
|
||||
expect(newState.tables[0].expanded).to.equal(true);
|
||||
});
|
||||
it('should remove a table', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.removeTable(newTable));
|
||||
expect(newState.tables).to.have.lengthOf(0);
|
||||
});
|
||||
});
|
||||
describe('Run Query', () => {
|
||||
let newState;
|
||||
let query;
|
||||
let newQuery;
|
||||
beforeEach(() => {
|
||||
newState = Object.assign({}, initialState);
|
||||
newQuery = Object.assign({}, query);
|
||||
});
|
||||
it('should start a query', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.startQuery(newQuery));
|
||||
expect(Object.keys(newState.queries)).to.have.lengthOf(1);
|
||||
});
|
||||
it('should stop the query', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.startQuery(newQuery));
|
||||
newState = r.sqlLabReducer(newState, actions.stopQuery(newQuery));
|
||||
const q = newState.queries[Object.keys(newState.queries)[0]];
|
||||
expect(q.state).to.equal('stopped');
|
||||
});
|
||||
it('should remove a query', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.startQuery(newQuery));
|
||||
newState = r.sqlLabReducer(newState, actions.removeQuery(newQuery));
|
||||
expect(Object.keys(newState.queries)).to.have.lengthOf(0);
|
||||
});
|
||||
it('should refresh queries when polling returns empty', () => {
|
||||
newState = r.sqlLabReducer(newState, actions.refreshQueries({}));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user