Skip to content

Commit

Permalink
[table editor] allow selecting physical table (#6046)
Browse files Browse the repository at this point in the history
* [table editor] allow selecting physical table

* Using classes for padding
  • Loading branch information
mistercrunch authored Jan 15, 2019
1 parent 4667f0c commit da813b7
Show file tree
Hide file tree
Showing 13 changed files with 628 additions and 472 deletions.
201 changes: 201 additions & 0 deletions superset/assets/spec/javascripts/components/TableSelector_spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import React from 'react';

This comment has been minimized.

Copy link
@bolkedebruin

bolkedebruin Jan 15, 2019

Contributor

@mistercrunch Grrrrr why without the license header...

import configureStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import fetchMock from 'fetch-mock';
import thunk from 'redux-thunk';

import { table, defaultQueryEditor, initialState, tables } from '../sqllab/fixtures';
import TableSelector from '../../../src/components/TableSelector';

describe('TableSelector', () => {
let mockedProps;
const middlewares = [thunk];
const mockStore = configureStore(middlewares);
const store = mockStore(initialState);
let wrapper;
let inst;

beforeEach(() => {
mockedProps = {
dbId: 1,
schema: 'main',
onSchemaChange: sinon.stub(),
onDbChange: sinon.stub(),
getDbList: sinon.stub(),
onTableChange: sinon.stub(),
onChange: sinon.stub(),
tableNameSticky: true,
tableName: '',
database: { id: 1, database_name: 'main' },
horizontal: false,
sqlLabMode: true,
clearable: false,
handleError: sinon.stub(),
};
wrapper = shallow(<TableSelector {...mockedProps} />, {
context: { store },
});
inst = wrapper.instance();
});

it('is valid', () => {
expect(React.isValidElement(<TableSelector {...mockedProps} />)).toBe(true);
});

describe('onDatabaseChange', () => {
it('should fetch schemas', () => {
sinon.stub(inst, 'fetchSchemas');
inst.onDatabaseChange({ id: 1 });
expect(inst.fetchSchemas.getCall(0).args[0]).toBe(1);
inst.fetchSchemas.restore();
});
it('should clear tableOptions', () => {
inst.onDatabaseChange();
expect(wrapper.state().tableOptions).toEqual([]);
});
});

describe('getTableNamesBySubStr', () => {
const GET_TABLE_NAMES_GLOB = 'glob:*/superset/tables/1/main/*';

afterEach(fetchMock.resetHistory);
afterAll(fetchMock.reset);

it('should handle empty', () =>
inst
.getTableNamesBySubStr('')
.then((data) => {
expect(data).toEqual({ options: [] });
}));

it('should handle table name', () => {
const queryEditor = {
...defaultQueryEditor,
dbId: 1,
schema: 'main',
};

const mockTableOptions = { options: [table] };
wrapper.setProps({ queryEditor });
fetchMock.get(GET_TABLE_NAMES_GLOB, mockTableOptions, { overwriteRoutes: true });

wrapper
.instance()
.getTableNamesBySubStr('my table')
.then((data) => {
expect(fetchMock.calls(GET_TABLE_NAMES_GLOB)).toHaveLength(1);
expect(data).toEqual(mockTableOptions);
});
});
});

describe('fetchTables', () => {
const FETCH_TABLES_GLOB = 'glob:*/superset/tables/1/main/*/*/';
afterEach(fetchMock.resetHistory);
afterAll(fetchMock.reset);

it('should clear table options', () => {
inst.fetchTables(true);
expect(wrapper.state().tableOptions).toEqual([]);
expect(wrapper.state().filterOptions).toBeNull();
});

it('should fetch table options', () => {
fetchMock.get(FETCH_TABLES_GLOB, tables, { overwriteRoutes: true });
inst
.fetchTables(true, 'birth_names')
.then(() => {
expect(wrapper.state().tableOptions).toHaveLength(3);
});
});

it('should dispatch a danger toast on error', () => {
fetchMock.get(FETCH_TABLES_GLOB, { throws: 'error' }, { overwriteRoutes: true });

wrapper
.instance()
.fetchTables(true, 'birth_names')
.then(() => {
expect(wrapper.state().tableOptions).toEqual([]);
expect(wrapper.state().tableOptions).toHaveLength(0);
expect(mockedProps.handleError.callCount).toBe(1);
});
});
});

describe('fetchSchemas', () => {
const FETCH_SCHEMAS_GLOB = 'glob:*/superset/schemas/*/*/';
afterEach(fetchMock.resetHistory);
afterAll(fetchMock.reset);

it('should fetch schema options', () => {
const schemaOptions = {
schemas: ['main', 'erf', 'superset'],
};
fetchMock.get(FETCH_SCHEMAS_GLOB, schemaOptions, { overwriteRoutes: true });

wrapper
.instance()
.fetchSchemas(1)
.then(() => {
expect(fetchMock.calls(FETCH_SCHEMAS_GLOB)).toHaveLength(1);
expect(wrapper.state().schemaOptions).toHaveLength(3);
});
});

it('should dispatch a danger toast on error', () => {
const handleErrors = sinon.stub();
expect(handleErrors.callCount).toBe(0);
wrapper.setProps({ handleErrors });
fetchMock.get(FETCH_SCHEMAS_GLOB, { throws: new Error('Bad kitty') }, { overwriteRoutes: true });
wrapper
.instance()
.fetchSchemas(123)
.then(() => {
expect(wrapper.state().schemaOptions).toEqual([]);
expect(handleErrors.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',
label: 'birth_names',
});
expect(wrapper.state().tableName).toBe('birth_names');
});

it('test 2', () => {
wrapper.instance().changeTable({
value: 'main.my_table',
label: 'my_table',
});
expect(mockedProps.onTableChange.getCall(0).args[0]).toBe('my_table');
expect(mockedProps.onTableChange.getCall(0).args[1]).toBe('main');
});
});

it('changeSchema', () => {
sinon.stub(wrapper.instance(), 'fetchTables');

wrapper.instance().changeSchema({ label: 'main', value: 'main' });
expect(wrapper.instance().fetchTables.callCount).toBe(1);
expect(mockedProps.onChange.callCount).toBe(1);
wrapper.instance().changeSchema();
expect(wrapper.instance().fetchTables.callCount).toBe(2);
expect(mockedProps.onChange.callCount).toBe(2);

wrapper.instance().fetchTables.restore();
});
});
Loading

0 comments on commit da813b7

Please sign in to comment.