mirror of
https://github.com/apache/superset.git
synced 2026-04-23 10:04:45 +00:00
Prettify the frontend code (#8648)
* Add Prettier global configs * Format js/jsx/ts/tsx/less files
This commit is contained in:
@@ -16,7 +16,10 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../src/explore/AdhocFilter';
|
||||
|
||||
describe('AdhocFilter', () => {
|
||||
it('sets filterOptionName in constructor', () => {
|
||||
@@ -93,7 +96,9 @@ describe('AdhocFilter', () => {
|
||||
sqlExpression: 'value > 10',
|
||||
clause: CLAUSES.WHERE,
|
||||
});
|
||||
const adhocFilter4 = adhocFilter3.duplicateWith({ sqlExpression: 'value = 5' });
|
||||
const adhocFilter4 = adhocFilter3.duplicateWith({
|
||||
sqlExpression: 'value = 5',
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocFilter3.equals(adhocFilter4)).toBe(false);
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import AdhocMetric, { EXPRESSION_TYPES } from '../../../src/explore/AdhocMetric';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from '../../../src/explore/AdhocMetric';
|
||||
import { AGGREGATES } from '../../../src/explore/constants';
|
||||
|
||||
const valueColumn = { type: 'DOUBLE', column_name: 'value' };
|
||||
@@ -45,7 +47,9 @@ describe('AdhocMetric', () => {
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({ aggregate: AGGREGATES.AVG });
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric1.column).toBe(adhocMetric2.column);
|
||||
expect(adhocMetric1.column).toBe(valueColumn);
|
||||
@@ -83,7 +87,9 @@ describe('AdhocMetric', () => {
|
||||
label: 'old label',
|
||||
hasCustomLabel: true,
|
||||
});
|
||||
const adhocMetric4 = adhocMetric3.duplicateWith({ sqlExpression: 'COUNT(1)' });
|
||||
const adhocMetric4 = adhocMetric3.duplicateWith({
|
||||
sqlExpression: 'COUNT(1)',
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric3.equals(adhocMetric4)).toBe(false);
|
||||
@@ -94,7 +100,9 @@ describe('AdhocMetric', () => {
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({ aggregate: AGGREGATES.AVG });
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric2.label).toBe('AVG(value)');
|
||||
});
|
||||
@@ -106,7 +114,9 @@ describe('AdhocMetric', () => {
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({ aggregate: AGGREGATES.AVG });
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric2.label).toBe('label1');
|
||||
});
|
||||
@@ -160,51 +170,45 @@ describe('AdhocMetric', () => {
|
||||
expect(adhocMetric5.isValid()).toBe(false);
|
||||
});
|
||||
|
||||
it(
|
||||
'can translate back from sql expressions to simple expressions when possible',
|
||||
() => {
|
||||
const adhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(my_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
expect(adhocMetric.inferSqlExpressionColumn()).toBe('my_column');
|
||||
expect(adhocMetric.inferSqlExpressionAggregate()).toBe('AVG');
|
||||
it('can translate back from sql expressions to simple expressions when possible', () => {
|
||||
const adhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(my_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
expect(adhocMetric.inferSqlExpressionColumn()).toBe('my_column');
|
||||
expect(adhocMetric.inferSqlExpressionAggregate()).toBe('AVG');
|
||||
|
||||
const adhocMetric2 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(SUM(my_column)) / MAX(other_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
expect(adhocMetric2.inferSqlExpressionColumn()).toBeNull();
|
||||
expect(adhocMetric2.inferSqlExpressionAggregate()).toBeNull();
|
||||
},
|
||||
);
|
||||
const adhocMetric2 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(SUM(my_column)) / MAX(other_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
expect(adhocMetric2.inferSqlExpressionColumn()).toBeNull();
|
||||
expect(adhocMetric2.inferSqlExpressionAggregate()).toBeNull();
|
||||
});
|
||||
|
||||
it(
|
||||
'will infer columns and aggregates when converting to a simple expression',
|
||||
() => {
|
||||
const adhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(my_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
const adhocMetric2 = adhocMetric.duplicateWith({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
expect(adhocMetric2.aggregate).toBe(AGGREGATES.SUM);
|
||||
expect(adhocMetric2.column.column_name).toBe('my_column');
|
||||
it('will infer columns and aggregates when converting to a simple expression', () => {
|
||||
const adhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'AVG(my_column)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
const adhocMetric2 = adhocMetric.duplicateWith({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
expect(adhocMetric2.aggregate).toBe(AGGREGATES.SUM);
|
||||
expect(adhocMetric2.column.column_name).toBe('my_column');
|
||||
|
||||
const adhocMetric3 = adhocMetric.duplicateWith({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
});
|
||||
expect(adhocMetric3.aggregate).toBe(AGGREGATES.AVG);
|
||||
expect(adhocMetric3.column.column_name).toBe('value');
|
||||
},
|
||||
);
|
||||
const adhocMetric3 = adhocMetric.duplicateWith({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
});
|
||||
expect(adhocMetric3.aggregate).toBe(AGGREGATES.AVG);
|
||||
expect(adhocMetric3.column.column_name).toBe('value');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,10 @@ import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilterControl from '../../../../src/explore/components/controls/AdhocFilterControl';
|
||||
import AdhocMetric from '../../../../src/explore/AdhocMetric';
|
||||
import { AGGREGATES, OPERATORS } from '../../../../src/explore/constants';
|
||||
@@ -82,15 +85,17 @@ describe('AdhocFilterControl', () => {
|
||||
|
||||
const adhocFilter = onChange.lastCall.args[0][0];
|
||||
expect(adhocFilter instanceof AdhocFilter).toBe(true);
|
||||
expect(adhocFilter.equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
subject: savedMetric.expression,
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
})
|
||||
))).toBe(true);
|
||||
expect(
|
||||
adhocFilter.equals(
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
subject: savedMetric.expression,
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('handles adhoc metrics being selected to filter on', () => {
|
||||
@@ -100,15 +105,17 @@ describe('AdhocFilterControl', () => {
|
||||
|
||||
const adhocFilter = onChange.lastCall.args[0][0];
|
||||
expect(adhocFilter instanceof AdhocFilter).toBe(true);
|
||||
expect(adhocFilter.equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
subject: sumValueAdhocMetric.label,
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
})
|
||||
))).toBe(true);
|
||||
expect(
|
||||
adhocFilter.equals(
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
subject: sumValueAdhocMetric.label,
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('handles columns being selected to filter on', () => {
|
||||
@@ -118,15 +125,17 @@ describe('AdhocFilterControl', () => {
|
||||
|
||||
const adhocFilter = onChange.lastCall.args[0][0];
|
||||
expect(adhocFilter instanceof AdhocFilter).toBe(true);
|
||||
expect(adhocFilter.equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: columns[0].column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
})
|
||||
))).toBe(true);
|
||||
expect(
|
||||
adhocFilter.equals(
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: columns[0].column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('persists existing filters even when new filters are added', () => {
|
||||
@@ -140,14 +149,16 @@ describe('AdhocFilterControl', () => {
|
||||
|
||||
const newAdhocFilter = onChange.lastCall.args[0][1];
|
||||
expect(newAdhocFilter instanceof AdhocFilter).toBe(true);
|
||||
expect(newAdhocFilter.equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: columns[0].column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
})
|
||||
))).toBe(true);
|
||||
expect(
|
||||
newAdhocFilter.equals(
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: columns[0].column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,10 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormGroup } from 'react-bootstrap';
|
||||
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocMetric from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocFilterEditPopoverSimpleTabContent from '../../../../src/explore/components/AdhocFilterEditPopoverSimpleTabContent';
|
||||
import { AGGREGATES } from '../../../../src/explore/constants';
|
||||
@@ -68,7 +71,9 @@ function setup(overrides) {
|
||||
datasource: {},
|
||||
...overrides,
|
||||
};
|
||||
const wrapper = shallow(<AdhocFilterEditPopoverSimpleTabContent {...props} />);
|
||||
const wrapper = shallow(
|
||||
<AdhocFilterEditPopoverSimpleTabContent {...props} />,
|
||||
);
|
||||
return { wrapper, onChange, onHeightChange };
|
||||
}
|
||||
|
||||
@@ -80,23 +85,29 @@ describe('AdhocFilterEditPopoverSimpleTabContent', () => {
|
||||
|
||||
it('passes the new adhocFilter to onChange after onSubjectChange', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
wrapper.instance().onSubjectChange({ type: 'VARCHAR(255)', column_name: 'source' });
|
||||
wrapper
|
||||
.instance()
|
||||
.onSubjectChange({ type: 'VARCHAR(255)', column_name: 'source' });
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
simpleAdhocFilter.duplicateWith({ subject: 'source' })
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
simpleAdhocFilter.duplicateWith({ subject: 'source' }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('may alter the clause in onSubjectChange if the old clause is not appropriate', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
wrapper.instance().onSubjectChange(sumValueAdhocMetric);
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
simpleAdhocFilter.duplicateWith({
|
||||
subject: sumValueAdhocMetric.label,
|
||||
clause: CLAUSES.HAVING,
|
||||
})
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
simpleAdhocFilter.duplicateWith({
|
||||
subject: sumValueAdhocMetric.label,
|
||||
clause: CLAUSES.HAVING,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('will convert from individual comparator to array if the operator changes to multi', () => {
|
||||
@@ -109,21 +120,27 @@ describe('AdhocFilterEditPopoverSimpleTabContent', () => {
|
||||
});
|
||||
|
||||
it('will convert from array to individual comparators if the operator changes from multi', () => {
|
||||
const { wrapper, onChange } = setup({ adhocFilter: simpleMultiAdhocFilter });
|
||||
const { wrapper, onChange } = setup({
|
||||
adhocFilter: simpleMultiAdhocFilter,
|
||||
});
|
||||
wrapper.instance().onOperatorChange({ operator: '<' });
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
simpleAdhocFilter.duplicateWith({ operator: '<', comparator: '10' })
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
simpleAdhocFilter.duplicateWith({ operator: '<', comparator: '10' }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('passes the new adhocFilter to onChange after onComparatorChange', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
wrapper.instance().onComparatorChange('20');
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
simpleAdhocFilter.duplicateWith({ comparator: '20' })
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
simpleAdhocFilter.duplicateWith({ comparator: '20' }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('will filter operators for table datasources', () => {
|
||||
@@ -141,8 +158,9 @@ describe('AdhocFilterEditPopoverSimpleTabContent', () => {
|
||||
it('expands when its multi comparator input field expands', () => {
|
||||
const { wrapper, onHeightChange } = setup();
|
||||
|
||||
wrapper.instance().multiComparatorComponent =
|
||||
{ _selectRef: { select: { control: { clientHeight: 57 } } } };
|
||||
wrapper.instance().multiComparatorComponent = {
|
||||
_selectRef: { select: { control: { clientHeight: 57 } } },
|
||||
};
|
||||
wrapper.instance().handleMultiComparatorInputHeightChange();
|
||||
|
||||
expect(onHeightChange.calledOnce).toBe(true);
|
||||
|
||||
@@ -22,7 +22,10 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormGroup } from 'react-bootstrap';
|
||||
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilterEditPopoverSqlTabContent from '../../../../src/explore/components/AdhocFilterEditPopoverSqlTabContent';
|
||||
|
||||
const sqlAdhocFilter = new AdhocFilter({
|
||||
@@ -54,17 +57,21 @@ describe('AdhocFilterEditPopoverSqlTabContent', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
wrapper.instance().onSqlExpressionClauseChange(CLAUSES.HAVING);
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
sqlAdhocFilter.duplicateWith({ clause: CLAUSES.HAVING })
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
sqlAdhocFilter.duplicateWith({ clause: CLAUSES.HAVING }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('passes the new query to onChange after onSqlExpressionChange', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
wrapper.instance().onSqlExpressionChange('value < 5');
|
||||
expect(onChange.calledOnce).toBe(true);
|
||||
expect(onChange.lastCall.args[0].equals((
|
||||
sqlAdhocFilter.duplicateWith({ sqlExpression: 'value < 5' })
|
||||
))).toBe(true);
|
||||
expect(
|
||||
onChange.lastCall.args[0].equals(
|
||||
sqlAdhocFilter.duplicateWith({ sqlExpression: 'value < 5' }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,10 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Button, Popover, Tab, Tabs } from 'react-bootstrap';
|
||||
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocMetric from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocFilterEditPopover from '../../../../src/explore/components/AdhocFilterEditPopover';
|
||||
import AdhocFilterEditPopoverSimpleTabContent from '../../../../src/explore/components/AdhocFilterEditPopoverSimpleTabContent';
|
||||
@@ -81,7 +84,9 @@ describe('AdhocFilterEditPopover', () => {
|
||||
expect(wrapper.find(Tabs)).toHaveLength(1);
|
||||
expect(wrapper.find(Tab)).toHaveLength(2);
|
||||
expect(wrapper.find(Button)).toHaveLength(2);
|
||||
expect(wrapper.find(AdhocFilterEditPopoverSimpleTabContent)).toHaveLength(1);
|
||||
expect(wrapper.find(AdhocFilterEditPopoverSimpleTabContent)).toHaveLength(
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders sql tab content when the adhoc filter expressionType is sql', () => {
|
||||
@@ -102,7 +107,9 @@ describe('AdhocFilterEditPopover', () => {
|
||||
it('prevents saving if the filter is invalid', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
|
||||
wrapper.instance().onAdhocFilterChange(simpleAdhocFilter.duplicateWith({ operator: null }));
|
||||
wrapper
|
||||
.instance()
|
||||
.onAdhocFilterChange(simpleAdhocFilter.duplicateWith({ operator: null }));
|
||||
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(1);
|
||||
wrapper.instance().onAdhocFilterChange(sqlAdhocFilter);
|
||||
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
|
||||
|
||||
@@ -22,7 +22,10 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Label, OverlayTrigger } from 'react-bootstrap';
|
||||
|
||||
import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from '../../../../src/explore/AdhocFilter';
|
||||
import AdhocFilterOption from '../../../../src/explore/components/AdhocFilterOption';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
|
||||
@@ -52,7 +52,12 @@ describe('AdhocMetricEditPopoverTitle', () => {
|
||||
it('renders an OverlayTrigger wrapper with the title', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
|
||||
expect(wrapper.find(OverlayTrigger).find('span').text()).toBe('My Metric\xa0');
|
||||
expect(
|
||||
wrapper
|
||||
.find(OverlayTrigger)
|
||||
.find('span')
|
||||
.text(),
|
||||
).toBe('My Metric\xa0');
|
||||
});
|
||||
|
||||
it('transfers to edit mode when clicked', () => {
|
||||
|
||||
@@ -22,7 +22,9 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Button, FormGroup, Popover } from 'react-bootstrap';
|
||||
|
||||
import AdhocMetric, { EXPRESSION_TYPES } from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocMetricEditPopover from '../../../../src/explore/components/AdhocMetricEditPopover';
|
||||
import { AGGREGATES } from '../../../../src/explore/constants';
|
||||
|
||||
@@ -68,19 +70,25 @@ describe('AdhocMetricEditPopover', () => {
|
||||
it('overwrites the adhocMetric in state with onColumnChange', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onColumnChange(columns[0]);
|
||||
expect(wrapper.state('adhocMetric')).toEqual(sumValueAdhocMetric.duplicateWith({ column: columns[0] }));
|
||||
expect(wrapper.state('adhocMetric')).toEqual(
|
||||
sumValueAdhocMetric.duplicateWith({ column: columns[0] }),
|
||||
);
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onAggregateChange', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onAggregateChange({ aggregate: AGGREGATES.AVG });
|
||||
expect(wrapper.state('adhocMetric')).toEqual(sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG }));
|
||||
expect(wrapper.state('adhocMetric')).toEqual(
|
||||
sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG }),
|
||||
);
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onSqlExpressionChange', () => {
|
||||
const { wrapper } = setup({ adhocMetric: sqlExpressionAdhocMetric });
|
||||
wrapper.instance().onSqlExpressionChange('COUNT(1)');
|
||||
expect(wrapper.state('adhocMetric')).toEqual(sqlExpressionAdhocMetric.duplicateWith({ sqlExpression: 'COUNT(1)' }));
|
||||
expect(wrapper.state('adhocMetric')).toEqual(
|
||||
sqlExpressionAdhocMetric.duplicateWith({ sqlExpression: 'COUNT(1)' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onLabelChange', () => {
|
||||
|
||||
@@ -21,7 +21,9 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import AdhocMetricStaticOption from '../../../../src/explore/components/AdhocMetricStaticOption';
|
||||
import AdhocMetric, { EXPRESSION_TYPES } from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from '../../../../src/explore/AdhocMetric';
|
||||
import { AGGREGATES } from '../../../../src/explore/constants';
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
@@ -32,7 +34,9 @@ const sumValueAdhocMetric = new AdhocMetric({
|
||||
|
||||
describe('AdhocMetricStaticOption', () => {
|
||||
it('renders the adhoc metrics label', () => {
|
||||
const wrapper = shallow(<AdhocMetricStaticOption adhocMetric={sumValueAdhocMetric} />);
|
||||
const wrapper = shallow(
|
||||
<AdhocMetricStaticOption adhocMetric={sumValueAdhocMetric} />,
|
||||
);
|
||||
expect(wrapper.text()).toBe('SUM(source)');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,9 @@ import AggregateOption from '../../../../src/explore/components/AggregateOption'
|
||||
|
||||
describe('AggregateOption', () => {
|
||||
it('renders the aggregate', () => {
|
||||
const wrapper = shallow(<AggregateOption aggregate={{ aggregate_name: 'SUM' }} />);
|
||||
const wrapper = shallow(
|
||||
<AggregateOption aggregate={{ aggregate_name: 'SUM' }} />,
|
||||
);
|
||||
expect(wrapper.text()).toBe('SUM');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -42,13 +42,24 @@ describe('BoundsControl', () => {
|
||||
});
|
||||
|
||||
it('errors on non-numeric', () => {
|
||||
wrapper.find(FormControl).first().simulate('change', { target: { value: 's' } });
|
||||
wrapper
|
||||
.find(FormControl)
|
||||
.first()
|
||||
.simulate('change', { target: { value: 's' } });
|
||||
expect(defaultProps.onChange.calledWith([null, null])).toBe(true);
|
||||
expect(defaultProps.onChange.getCall(0).args[1][0]).toContain('value should be numeric');
|
||||
expect(defaultProps.onChange.getCall(0).args[1][0]).toContain(
|
||||
'value should be numeric',
|
||||
);
|
||||
});
|
||||
it('casts to numeric', () => {
|
||||
wrapper.find(FormControl).first().simulate('change', { target: { value: '1' } });
|
||||
wrapper.find(FormControl).last().simulate('change', { target: { value: '5' } });
|
||||
wrapper
|
||||
.find(FormControl)
|
||||
.first()
|
||||
.simulate('change', { target: { value: '1' } });
|
||||
wrapper
|
||||
.find(FormControl)
|
||||
.last()
|
||||
.simulate('change', { target: { value: '5' } });
|
||||
expect(defaultProps.onChange.calledWith([1, 5])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,7 +54,10 @@ describe('CheckboxControl', () => {
|
||||
|
||||
fullComponent.instance().forceUpdate();
|
||||
|
||||
fullComponent.find('label span').last().simulate('click');
|
||||
fullComponent
|
||||
.find('label span')
|
||||
.last()
|
||||
.simulate('click');
|
||||
|
||||
expect(spy.calledOnce).toBe(true);
|
||||
});
|
||||
|
||||
@@ -21,14 +21,16 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { OverlayTrigger } from 'react-bootstrap';
|
||||
import { SketchPicker } from 'react-color';
|
||||
import { CategoricalScheme, getCategoricalSchemeRegistry } from '@superset-ui/color';
|
||||
import {
|
||||
CategoricalScheme,
|
||||
getCategoricalSchemeRegistry,
|
||||
} from '@superset-ui/color';
|
||||
|
||||
import ColorPickerControl from
|
||||
'../../../../src/explore/components/controls/ColorPickerControl';
|
||||
import ColorPickerControl from '../../../../src/explore/components/controls/ColorPickerControl';
|
||||
import ControlHeader from '../../../../src/explore/components/ControlHeader';
|
||||
|
||||
const defaultProps = {
|
||||
value: { },
|
||||
value: {},
|
||||
};
|
||||
|
||||
describe('ColorPickerControl', () => {
|
||||
@@ -36,10 +38,13 @@ describe('ColorPickerControl', () => {
|
||||
let inst;
|
||||
beforeEach(() => {
|
||||
getCategoricalSchemeRegistry()
|
||||
.registerValue('test', new CategoricalScheme({
|
||||
id: 'test',
|
||||
colors: ['red', 'green', 'blue'],
|
||||
}))
|
||||
.registerValue(
|
||||
'test',
|
||||
new CategoricalScheme({
|
||||
id: 'test',
|
||||
colors: ['red', 'green', 'blue'],
|
||||
}),
|
||||
)
|
||||
.setDefaultKey('test');
|
||||
wrapper = shallow(<ColorPickerControl {...defaultProps} />);
|
||||
inst = wrapper.instance();
|
||||
|
||||
@@ -22,11 +22,12 @@ import { mount } from 'enzyme';
|
||||
import { Creatable } from 'react-select';
|
||||
import { getCategoricalSchemeRegistry } from '@superset-ui/color';
|
||||
|
||||
import ColorSchemeControl from
|
||||
'../../../../src/explore/components/controls/ColorSchemeControl';
|
||||
import ColorSchemeControl from '../../../../src/explore/components/controls/ColorSchemeControl';
|
||||
|
||||
const defaultProps = {
|
||||
options: getCategoricalSchemeRegistry().keys().map(s => ([s, s])),
|
||||
options: getCategoricalSchemeRegistry()
|
||||
.keys()
|
||||
.map(s => [s, s]),
|
||||
};
|
||||
|
||||
describe('ColorSchemeControl', () => {
|
||||
|
||||
@@ -20,11 +20,9 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Panel } from 'react-bootstrap';
|
||||
|
||||
import InfoTooltipWithTrigger from
|
||||
'../../../../src/components/InfoTooltipWithTrigger';
|
||||
import InfoTooltipWithTrigger from '../../../../src/components/InfoTooltipWithTrigger';
|
||||
|
||||
import ControlPanelSection from
|
||||
'../../../../src/explore/components/ControlPanelSection';
|
||||
import ControlPanelSection from '../../../../src/explore/components/ControlPanelSection';
|
||||
|
||||
const defaultProps = {
|
||||
children: <div>a child element</div>,
|
||||
@@ -57,11 +55,21 @@ describe('ControlPanelSection', () => {
|
||||
});
|
||||
|
||||
it('renders a label if present', () => {
|
||||
expect(wrapper.find(Panel).dive().text()).toContain('my label');
|
||||
expect(
|
||||
wrapper
|
||||
.find(Panel)
|
||||
.dive()
|
||||
.text(),
|
||||
).toContain('my label');
|
||||
});
|
||||
|
||||
it('renders a InfoTooltipWithTrigger if label and tooltip is present', () => {
|
||||
expect(wrapper.find(Panel).dive().find(InfoTooltipWithTrigger)).toHaveLength(1);
|
||||
expect(
|
||||
wrapper
|
||||
.find(Panel)
|
||||
.dive()
|
||||
.find(InfoTooltipWithTrigger),
|
||||
).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,15 +29,18 @@ import * as featureFlags from 'src/featureFlags';
|
||||
describe('ControlPanelsContainer', () => {
|
||||
let wrapper;
|
||||
let scopedFilterOn = false;
|
||||
const isFeatureEnabledMock = jest.spyOn(featureFlags, 'isFeatureEnabled')
|
||||
.mockImplementation(() => scopedFilterOn);
|
||||
const isFeatureEnabledMock = jest
|
||||
.spyOn(featureFlags, 'isFeatureEnabled')
|
||||
.mockImplementation(() => scopedFilterOn);
|
||||
|
||||
beforeAll(() => {
|
||||
getChartControlPanelRegistry().registerValue('table', {
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('GROUP BY'),
|
||||
description: t('Use this section if you want a query that aggregates'),
|
||||
description: t(
|
||||
'Use this section if you want a query that aggregates',
|
||||
),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['groupby'],
|
||||
@@ -60,9 +63,7 @@ describe('ControlPanelsContainer', () => {
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
controlSetRows: [['adhoc_filters']],
|
||||
},
|
||||
{
|
||||
label: t('Options'),
|
||||
|
||||
@@ -47,7 +47,9 @@ describe('DatasourceControl', () => {
|
||||
function setup() {
|
||||
const mockStore = configureStore([]);
|
||||
const store = mockStore({});
|
||||
return shallow(<DatasourceControl {...defaultProps} />, { context: { store } });
|
||||
return shallow(<DatasourceControl {...defaultProps} />, {
|
||||
context: { store },
|
||||
});
|
||||
}
|
||||
|
||||
it('renders a Modal', () => {
|
||||
|
||||
@@ -70,7 +70,9 @@ describe('DateFilterControl', () => {
|
||||
label.simulate('click');
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('.popover')).toHaveLength(1);
|
||||
expect(wrapper.find('.ok')).first().simulate('click');
|
||||
expect(wrapper.find('.ok'))
|
||||
.first()
|
||||
.simulate('click');
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('.popover')).toHaveLength(0);
|
||||
}, 10);
|
||||
|
||||
@@ -37,7 +37,9 @@ describe('DisplayQueryButton', () => {
|
||||
};
|
||||
|
||||
it('is valid', () => {
|
||||
expect(React.isValidElement(<DisplayQueryButton {...defaultProps} />)).toBe(true);
|
||||
expect(React.isValidElement(<DisplayQueryButton {...defaultProps} />)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
it('renders a dropdown', () => {
|
||||
const wrapper = mount(<DisplayQueryButton {...defaultProps} />);
|
||||
|
||||
@@ -30,7 +30,9 @@ describe('EmbedCodeButton', () => {
|
||||
};
|
||||
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<EmbedCodeButton {...defaultProps} />)).toBe(true);
|
||||
expect(React.isValidElement(<EmbedCodeButton {...defaultProps} />)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders overlay trigger', () => {
|
||||
@@ -39,13 +41,15 @@ describe('EmbedCodeButton', () => {
|
||||
});
|
||||
|
||||
it('returns correct embed code', () => {
|
||||
const stub = sinon.stub(exploreUtils, 'getExploreLongUrl').callsFake(() => ('endpoint_url'));
|
||||
const stub = sinon
|
||||
.stub(exploreUtils, 'getExploreLongUrl')
|
||||
.callsFake(() => 'endpoint_url');
|
||||
const wrapper = mount(<EmbedCodeButton {...defaultProps} />);
|
||||
wrapper.setState({
|
||||
height: '1000',
|
||||
width: '2000',
|
||||
});
|
||||
const embedHTML = (
|
||||
const embedHTML =
|
||||
'<iframe\n' +
|
||||
' width="2000"\n' +
|
||||
' height="1000"\n' +
|
||||
@@ -54,8 +58,7 @@ describe('EmbedCodeButton', () => {
|
||||
' scrolling="no"\n' +
|
||||
' src="http://localhostendpoint_url&height=1000"\n' +
|
||||
'>\n' +
|
||||
'</iframe>'
|
||||
);
|
||||
'</iframe>';
|
||||
expect(wrapper.instance().generateEmbedHTML()).toBe(embedHTML);
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import ExploreActionButtons from
|
||||
'../../../../src/explore/components/ExploreActionButtons';
|
||||
import ExploreActionButtons from '../../../../src/explore/components/ExploreActionButtons';
|
||||
|
||||
describe('ExploreActionButtons', () => {
|
||||
const defaultProps = {
|
||||
|
||||
@@ -44,9 +44,9 @@ describe('ExploreChartHeader', () => {
|
||||
});
|
||||
|
||||
it('is valid', () => {
|
||||
expect(
|
||||
React.isValidElement(<ExploreChartHeader {...mockProps} />),
|
||||
).toBe(true);
|
||||
expect(React.isValidElement(<ExploreChartHeader {...mockProps} />)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
|
||||
@@ -28,8 +28,6 @@ describe('ChartContainer', () => {
|
||||
};
|
||||
|
||||
it('renders when vizType is line', () => {
|
||||
expect(
|
||||
React.isValidElement(<ChartContainer {...mockProps} />),
|
||||
).toBe(true);
|
||||
expect(React.isValidElement(<ChartContainer {...mockProps} />)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,8 +37,9 @@ describe('ExploreViewContainer', () => {
|
||||
let isFeatureEnabledMock;
|
||||
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest.spyOn(featureFlags, 'isFeatureEnabled')
|
||||
.mockReturnValue(false);
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(featureFlags, 'isFeatureEnabled')
|
||||
.mockReturnValue(false);
|
||||
|
||||
const bootstrapData = {
|
||||
common: {
|
||||
@@ -63,9 +64,7 @@ describe('ExploreViewContainer', () => {
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(
|
||||
React.isValidElement(<ExploreViewContainer />),
|
||||
).toBe(true);
|
||||
expect(React.isValidElement(<ExploreViewContainer />)).toBe(true);
|
||||
});
|
||||
|
||||
it('renders QueryAndSaveButtons', () => {
|
||||
@@ -83,8 +82,14 @@ describe('ExploreViewContainer', () => {
|
||||
describe('componentWillReceiveProps()', () => {
|
||||
it('when controls change, should call resetControls', () => {
|
||||
expect(wrapper.instance().props.controls.viz_type.value).toBe('table');
|
||||
const resetControls = sinon.stub(wrapper.instance().props.actions, 'resetControls');
|
||||
const triggerQuery = sinon.stub(wrapper.instance().props.actions, 'triggerQuery');
|
||||
const resetControls = sinon.stub(
|
||||
wrapper.instance().props.actions,
|
||||
'resetControls',
|
||||
);
|
||||
const triggerQuery = sinon.stub(
|
||||
wrapper.instance().props.actions,
|
||||
'triggerQuery',
|
||||
);
|
||||
|
||||
// triggers componentWillReceiveProps
|
||||
wrapper.setProps({
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('FilterBoxItemControl', () => {
|
||||
let wrapper;
|
||||
let inst;
|
||||
|
||||
const getWrapper = (propOverrides) => {
|
||||
const getWrapper = propOverrides => {
|
||||
const props = { ...defaultProps, ...propOverrides };
|
||||
return shallow(<FilterBoxItemControl {...props} />);
|
||||
};
|
||||
|
||||
@@ -23,7 +23,9 @@ import { shallow } from 'enzyme';
|
||||
import FilterDefinitionOption from '../../../../src/explore/components/FilterDefinitionOption';
|
||||
import ColumnOption from '../../../../src/components/ColumnOption';
|
||||
import AdhocMetricStaticOption from '../../../../src/explore/components/AdhocMetricStaticOption';
|
||||
import AdhocMetric, { EXPRESSION_TYPES } from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from '../../../../src/explore/AdhocMetric';
|
||||
import { AGGREGATES } from '../../../../src/explore/constants';
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
@@ -34,19 +36,25 @@ const sumValueAdhocMetric = new AdhocMetric({
|
||||
|
||||
describe('FilterDefinitionOption', () => {
|
||||
it('renders a ColumnOption given a column', () => {
|
||||
const wrapper = shallow(<FilterDefinitionOption option={{ column_name: 'a_column' }} />);
|
||||
const wrapper = shallow(
|
||||
<FilterDefinitionOption option={{ column_name: 'a_column' }} />,
|
||||
);
|
||||
expect(wrapper.find(ColumnOption)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders a AdhocMetricStaticOption given an adhoc metric', () => {
|
||||
const wrapper = shallow(<FilterDefinitionOption option={sumValueAdhocMetric} />);
|
||||
const wrapper = shallow(
|
||||
<FilterDefinitionOption option={sumValueAdhocMetric} />,
|
||||
);
|
||||
expect(wrapper.find(AdhocMetricStaticOption)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders the metric name given a saved metric', () => {
|
||||
const wrapper = shallow((
|
||||
<FilterDefinitionOption option={{ saved_metric_name: 'my_custom_metric' }} />
|
||||
));
|
||||
const wrapper = shallow(
|
||||
<FilterDefinitionOption
|
||||
option={{ saved_metric_name: 'my_custom_metric' }}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.text()).toBe('<ColumnTypeLabel />my_custom_metric');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,16 +20,13 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import FixedOrMetricControl from
|
||||
'../../../../src/explore/components/controls/FixedOrMetricControl';
|
||||
import TextControl from
|
||||
'../../../../src/explore/components/controls/TextControl';
|
||||
import MetricsControl from
|
||||
'../../../../src/explore/components/controls/MetricsControl';
|
||||
import FixedOrMetricControl from '../../../../src/explore/components/controls/FixedOrMetricControl';
|
||||
import TextControl from '../../../../src/explore/components/controls/TextControl';
|
||||
import MetricsControl from '../../../../src/explore/components/controls/MetricsControl';
|
||||
|
||||
const defaultProps = {
|
||||
value: { },
|
||||
datasource: { },
|
||||
value: {},
|
||||
datasource: {},
|
||||
};
|
||||
|
||||
describe('FixedOrMetricControl', () => {
|
||||
|
||||
@@ -30,7 +30,9 @@ describe('MetricDefinitionOption', () => {
|
||||
const store = mockStore({});
|
||||
|
||||
function setup(props) {
|
||||
return shallow(<MetricDefinitionOption {...props} />, { context: { store } }).dive();
|
||||
return shallow(<MetricDefinitionOption {...props} />, {
|
||||
context: { store },
|
||||
}).dive();
|
||||
}
|
||||
|
||||
it('renders a MetricOption given a saved metric', () => {
|
||||
|
||||
@@ -33,14 +33,19 @@ const sumValueAdhocMetric = new AdhocMetric({
|
||||
|
||||
describe('MetricDefinitionValue', () => {
|
||||
it('renders a MetricOption given a saved metric', () => {
|
||||
const wrapper = shallow(<MetricDefinitionValue option={{ metric_name: 'a_saved_metric' }} />);
|
||||
const wrapper = shallow(
|
||||
<MetricDefinitionValue option={{ metric_name: 'a_saved_metric' }} />,
|
||||
);
|
||||
expect(wrapper.find(MetricOption)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders an AdhocMetricOption given an adhoc metric', () => {
|
||||
const wrapper = shallow((
|
||||
<MetricDefinitionValue onMetricEdit={() => {}} option={sumValueAdhocMetric} />
|
||||
));
|
||||
const wrapper = shallow(
|
||||
<MetricDefinitionValue
|
||||
onMetricEdit={() => {}}
|
||||
option={sumValueAdhocMetric}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find(AdhocMetricOption)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,9 @@ import { shallow } from 'enzyme';
|
||||
import MetricsControl from '../../../../src/explore/components/controls/MetricsControl';
|
||||
import { AGGREGATES } from '../../../../src/explore/constants';
|
||||
import OnPasteSelect from '../../../../src/components/OnPasteSelect';
|
||||
import AdhocMetric, { EXPRESSION_TYPES } from '../../../../src/explore/AdhocMetric';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from '../../../../src/explore/AdhocMetric';
|
||||
|
||||
const defaultProps = {
|
||||
name: 'metrics',
|
||||
@@ -63,33 +65,56 @@ const sumValueAdhocMetric = new AdhocMetric({
|
||||
});
|
||||
|
||||
describe('MetricsControl', () => {
|
||||
|
||||
it('renders an OnPasteSelect', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(OnPasteSelect)).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
|
||||
it('unifies options for the dropdown select with aggregates', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.state('options')).toEqual([
|
||||
{ optionName: '_col_source', type: 'VARCHAR(255)', column_name: 'source' },
|
||||
{ optionName: '_col_target', type: 'VARCHAR(255)', column_name: 'target' },
|
||||
{
|
||||
optionName: '_col_source',
|
||||
type: 'VARCHAR(255)',
|
||||
column_name: 'source',
|
||||
},
|
||||
{
|
||||
optionName: '_col_target',
|
||||
type: 'VARCHAR(255)',
|
||||
column_name: 'target',
|
||||
},
|
||||
{ optionName: '_col_value', type: 'DOUBLE', column_name: 'value' },
|
||||
...Object.keys(AGGREGATES).map(
|
||||
aggregate => ({ aggregate_name: aggregate, optionName: '_aggregate_' + aggregate }),
|
||||
),
|
||||
{ optionName: 'sum__value', metric_name: 'sum__value', expression: 'SUM(energy_usage.value)' },
|
||||
{ optionName: 'avg__value', metric_name: 'avg__value', expression: 'AVG(energy_usage.value)' },
|
||||
...Object.keys(AGGREGATES).map(aggregate => ({
|
||||
aggregate_name: aggregate,
|
||||
optionName: '_aggregate_' + aggregate,
|
||||
})),
|
||||
{
|
||||
optionName: 'sum__value',
|
||||
metric_name: 'sum__value',
|
||||
expression: 'SUM(energy_usage.value)',
|
||||
},
|
||||
{
|
||||
optionName: 'avg__value',
|
||||
metric_name: 'avg__value',
|
||||
expression: 'AVG(energy_usage.value)',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not show aggregates in options if no columns', () => {
|
||||
const { wrapper } = setup({ columns: [] });
|
||||
expect(wrapper.state('options')).toEqual([
|
||||
{ optionName: 'sum__value', metric_name: 'sum__value', expression: 'SUM(energy_usage.value)' },
|
||||
{ optionName: 'avg__value', metric_name: 'avg__value', expression: 'AVG(energy_usage.value)' },
|
||||
{
|
||||
optionName: 'sum__value',
|
||||
metric_name: 'sum__value',
|
||||
expression: 'SUM(energy_usage.value)',
|
||||
},
|
||||
{
|
||||
optionName: 'avg__value',
|
||||
metric_name: 'avg__value',
|
||||
expression: 'AVG(energy_usage.value)',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -124,11 +149,9 @@ describe('MetricsControl', () => {
|
||||
'avg__value',
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('onChange', () => {
|
||||
|
||||
it('handles saved metrics being selected', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
const select = wrapper.find(OnPasteSelect);
|
||||
@@ -143,16 +166,20 @@ describe('MetricsControl', () => {
|
||||
|
||||
const adhocMetric = onChange.lastCall.args[0][0];
|
||||
expect(adhocMetric instanceof AdhocMetric).toBe(true);
|
||||
expect(onChange.lastCall.args).toEqual([[{
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
fromFormData: false,
|
||||
hasCustomLabel: false,
|
||||
optionName: adhocMetric.optionName,
|
||||
sqlExpression: null,
|
||||
}]]);
|
||||
expect(onChange.lastCall.args).toEqual([
|
||||
[
|
||||
{
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
fromFormData: false,
|
||||
hasCustomLabel: false,
|
||||
optionName: adhocMetric.optionName,
|
||||
sqlExpression: null,
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles aggregates being selected', () => {
|
||||
@@ -171,15 +198,22 @@ describe('MetricsControl', () => {
|
||||
select.simulate('change', [{ aggregate_name: 'SUM', optionName: 'SUM' }]);
|
||||
|
||||
expect(setInputSpy.calledWith('SUM()')).toBe(true);
|
||||
expect(handleInputSpy.calledWith({ target: { value: 'SUM()' } })).toBe(true);
|
||||
expect(handleInputSpy.calledWith({ target: { value: 'SUM()' } })).toBe(
|
||||
true,
|
||||
);
|
||||
expect(onChange.lastCall.args).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('preserves existing selected AdhocMetrics', () => {
|
||||
const { wrapper, onChange } = setup();
|
||||
const select = wrapper.find(OnPasteSelect);
|
||||
select.simulate('change', [{ metric_name: 'sum__value' }, sumValueAdhocMetric]);
|
||||
expect(onChange.lastCall.args).toEqual([['sum__value', sumValueAdhocMetric]]);
|
||||
select.simulate('change', [
|
||||
{ metric_name: 'sum__value' },
|
||||
sumValueAdhocMetric,
|
||||
]);
|
||||
expect(onChange.lastCall.args).toEqual([
|
||||
['sum__value', sumValueAdhocMetric],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -189,12 +223,12 @@ describe('MetricsControl', () => {
|
||||
value: [sumValueAdhocMetric],
|
||||
});
|
||||
|
||||
const editedMetric = sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG });
|
||||
const editedMetric = sumValueAdhocMetric.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
wrapper.instance().onMetricEdit(editedMetric);
|
||||
|
||||
expect(onChange.lastCall.args).toEqual([[
|
||||
editedMetric,
|
||||
]]);
|
||||
expect(onChange.lastCall.args).toEqual([[editedMetric]]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -220,118 +254,151 @@ describe('MetricsControl', () => {
|
||||
it('includes user defined metrics', () => {
|
||||
const { wrapper } = setup({ datasourceType: 'druid' });
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'a_metric',
|
||||
optionName: 'a_metric',
|
||||
expression: 'SUM(FANCY(metric))',
|
||||
},
|
||||
'a',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'a_metric',
|
||||
optionName: 'a_metric',
|
||||
expression: 'SUM(FANCY(metric))',
|
||||
},
|
||||
'a',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('includes auto generated avg metrics for druid', () => {
|
||||
const { wrapper } = setup({ datasourceType: 'druid' });
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'avg__metric',
|
||||
optionName: 'avg__metric',
|
||||
expression: 'AVG(metric)',
|
||||
},
|
||||
'a',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'avg__metric',
|
||||
optionName: 'avg__metric',
|
||||
expression: 'AVG(metric)',
|
||||
},
|
||||
'a',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('includes columns and aggregates', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{ type: 'VARCHAR(255)', column_name: 'source', optionName: '_col_source' },
|
||||
'sou',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
type: 'VARCHAR(255)',
|
||||
column_name: 'source',
|
||||
optionName: '_col_source',
|
||||
},
|
||||
'sou',
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{ aggregate_name: 'AVG', optionName: '_aggregate_AVG' },
|
||||
'av',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper
|
||||
.instance()
|
||||
.selectFilterOption(
|
||||
{ aggregate_name: 'AVG', optionName: '_aggregate_AVG' },
|
||||
'av',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('includes columns based on verbose_name', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{ metric_name: 'sum__num', verbose_name: 'babies', optionName: '_col_sum_num' },
|
||||
'bab',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'sum__num',
|
||||
verbose_name: 'babies',
|
||||
optionName: '_col_sum_num',
|
||||
},
|
||||
'bab',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('excludes auto generated avg metrics for sqla', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'avg__metric',
|
||||
optionName: 'avg__metric',
|
||||
expression: 'AVG(metric)',
|
||||
},
|
||||
'a',
|
||||
)).toBe(false);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'avg__metric',
|
||||
optionName: 'avg__metric',
|
||||
expression: 'AVG(metric)',
|
||||
},
|
||||
'a',
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('includes custom made simple saved metrics', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'my_fancy_sum_metric',
|
||||
optionName: 'my_fancy_sum_metric',
|
||||
expression: 'SUM(value)',
|
||||
},
|
||||
'sum',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'my_fancy_sum_metric',
|
||||
optionName: 'my_fancy_sum_metric',
|
||||
expression: 'SUM(value)',
|
||||
},
|
||||
'sum',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('excludes auto generated metrics', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'sum__value',
|
||||
optionName: 'sum__value',
|
||||
expression: 'SUM(value)',
|
||||
},
|
||||
'sum',
|
||||
)).toBe(false);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'sum__value',
|
||||
optionName: 'sum__value',
|
||||
expression: 'SUM(value)',
|
||||
},
|
||||
'sum',
|
||||
),
|
||||
).toBe(false);
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'sum__value',
|
||||
optionName: 'sum__value',
|
||||
expression: 'SUM("table"."value")',
|
||||
},
|
||||
'sum',
|
||||
)).toBe(false);
|
||||
expect(
|
||||
!!wrapper.instance().selectFilterOption(
|
||||
{
|
||||
metric_name: 'sum__value',
|
||||
optionName: 'sum__value',
|
||||
expression: 'SUM("table"."value")',
|
||||
},
|
||||
'sum',
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('filters out metrics if the input begins with an aggregate', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.setState({ aggregateInInput: true });
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{ metric_name: 'metric', expression: 'SUM(FANCY(metric))' },
|
||||
'SUM(',
|
||||
)).toBe(false);
|
||||
expect(
|
||||
!!wrapper
|
||||
.instance()
|
||||
.selectFilterOption(
|
||||
{ metric_name: 'metric', expression: 'SUM(FANCY(metric))' },
|
||||
'SUM(',
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('includes columns if the input begins with an aggregate', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.setState({ aggregateInInput: true });
|
||||
|
||||
expect(!!wrapper.instance().selectFilterOption(
|
||||
{ type: 'DOUBLE', column_name: 'value' },
|
||||
'SUM(',
|
||||
)).toBe(true);
|
||||
expect(
|
||||
!!wrapper
|
||||
.instance()
|
||||
.selectFilterOption({ type: 'DOUBLE', column_name: 'value' }, 'SUM('),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('Removes metrics if savedMetrics changes', () => {
|
||||
|
||||
@@ -31,7 +31,9 @@ describe('QueryAndSaveButtons', () => {
|
||||
|
||||
// It must render
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<QueryAndSaveButtons {...defaultProps} />)).toBe(true);
|
||||
expect(
|
||||
React.isValidElement(<QueryAndSaveButtons {...defaultProps} />),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
// Test the output
|
||||
|
||||
@@ -31,7 +31,9 @@ describe('RowCountLabel', () => {
|
||||
};
|
||||
|
||||
it('is valid', () => {
|
||||
expect(React.isValidElement(<RowCountLabel {...defaultProps} />)).toBe(true);
|
||||
expect(React.isValidElement(<RowCountLabel {...defaultProps} />)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
it('renders a Label and a TooltipWrapper', () => {
|
||||
const wrapper = shallow(<RowCountLabel {...defaultProps} />);
|
||||
@@ -44,6 +46,11 @@ describe('RowCountLabel', () => {
|
||||
limit: 100,
|
||||
};
|
||||
const wrapper = shallow(<RowCountLabel {...props} />);
|
||||
expect(wrapper.find(Label).first().props().bsStyle).toBe('danger');
|
||||
expect(
|
||||
wrapper
|
||||
.find(Label)
|
||||
.first()
|
||||
.props().bsStyle,
|
||||
).toBe('danger');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import RunQueryActionButton
|
||||
from '../../../../src/SqlLab/components/RunQueryActionButton';
|
||||
import RunQueryActionButton from '../../../../src/SqlLab/components/RunQueryActionButton';
|
||||
import Button from '../../../../src/components/Button';
|
||||
|
||||
describe('RunQueryActionButton', () => {
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('SaveModal', () => {
|
||||
|
||||
const defaultProps = {
|
||||
onHide: () => ({}),
|
||||
actions: bindActionCreators(saveModalActions, (arg) => {
|
||||
actions: bindActionCreators(saveModalActions, arg => {
|
||||
if (typeof arg === 'function') {
|
||||
return arg(jest.fn);
|
||||
}
|
||||
@@ -144,11 +144,11 @@ describe('SaveModal', () => {
|
||||
.stub(exploreUtils, 'getExploreUrlAndPayload')
|
||||
.callsFake(() => ({ url: 'mockURL', payload: defaultProps.form_data }));
|
||||
|
||||
sinon
|
||||
.stub(defaultProps.actions, 'saveSlice')
|
||||
.callsFake(() =>
|
||||
Promise.resolve({ data: { dashboard: '/mock/', slice: { slice_url: '/mock/' } } }),
|
||||
);
|
||||
sinon.stub(defaultProps.actions, 'saveSlice').callsFake(() =>
|
||||
Promise.resolve({
|
||||
data: { dashboard: '/mock/', slice: { slice_url: '/mock/' } },
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -223,15 +223,14 @@ describe('SaveModal', () => {
|
||||
return actionThunk(dispatch);
|
||||
};
|
||||
|
||||
it('makes the fetch request', () => (
|
||||
it('makes the fetch request', () =>
|
||||
makeRequest().then(() => {
|
||||
expect(fetchMock.calls(saveEndpoint)).toHaveLength(1);
|
||||
|
||||
return Promise.resolve();
|
||||
})
|
||||
));
|
||||
}));
|
||||
|
||||
it('calls correct actions on success', () => (
|
||||
it('calls correct actions on success', () =>
|
||||
makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0].type).toBe(
|
||||
@@ -239,17 +238,24 @@ describe('SaveModal', () => {
|
||||
);
|
||||
|
||||
return Promise.resolve();
|
||||
})
|
||||
));
|
||||
}));
|
||||
|
||||
it('calls correct actions on error', () => {
|
||||
fetchMock.get(saveEndpoint, { throws: 'error' }, { overwriteRoutes: true });
|
||||
fetchMock.get(
|
||||
saveEndpoint,
|
||||
{ throws: 'error' },
|
||||
{ overwriteRoutes: true },
|
||||
);
|
||||
|
||||
return makeRequest().then(() => {
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0].type).toBe(saveModalActions.FETCH_DASHBOARDS_FAILED);
|
||||
expect(dispatch.getCall(0).args[0].type).toBe(
|
||||
saveModalActions.FETCH_DASHBOARDS_FAILED,
|
||||
);
|
||||
|
||||
fetchMock.get(saveEndpoint, mockDashboardData, { overwriteRoutes: true });
|
||||
fetchMock.get(saveEndpoint, mockDashboardData, {
|
||||
overwriteRoutes: true,
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
@@ -27,7 +27,10 @@ import VirtualizedRendererWrap from '../../../../src/components/VirtualizedRende
|
||||
import SelectControl from '../../../../src/explore/components/controls/SelectControl';
|
||||
|
||||
const defaultProps = {
|
||||
choices: [['1 year ago', '1 year ago'], ['today', 'today']],
|
||||
choices: [
|
||||
['1 year ago', '1 year ago'],
|
||||
['today', 'today'],
|
||||
],
|
||||
name: 'row_limit',
|
||||
label: 'Row Limit',
|
||||
valueKey: 'value', // shallow isn't passing SelectControl.defaultProps.valueKey through
|
||||
@@ -115,8 +118,11 @@ describe('SelectControl', () => {
|
||||
valueKey: 'value',
|
||||
};
|
||||
wrapper.setProps(selectAllProps);
|
||||
expect(wrapper.instance().getOptions(selectAllProps))
|
||||
.toContainEqual({ label: 'Select All', meta: true, value: 'Select All' });
|
||||
expect(wrapper.instance().getOptions(selectAllProps)).toContainEqual({
|
||||
label: 'Select All',
|
||||
meta: true,
|
||||
value: 'Select All',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the correct options when freeform is set to true', () => {
|
||||
@@ -145,7 +151,10 @@ describe('SelectControl', () => {
|
||||
{ value: 'four', label: 'four' },
|
||||
];
|
||||
const newProps = {
|
||||
choices: [['three', 'three'], ['four', 'four']],
|
||||
choices: [
|
||||
['three', 'three'],
|
||||
['four', 'four'],
|
||||
],
|
||||
name: 'name',
|
||||
freeForm: false,
|
||||
value: null,
|
||||
|
||||
@@ -21,10 +21,8 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { OverlayTrigger, Label } from 'react-bootstrap';
|
||||
|
||||
import ViewportControl from
|
||||
'../../../../src/explore/components/controls/ViewportControl';
|
||||
import TextControl from
|
||||
'../../../../src/explore/components/controls/TextControl';
|
||||
import ViewportControl from '../../../../src/explore/components/controls/ViewportControl';
|
||||
import TextControl from '../../../../src/explore/components/controls/TextControl';
|
||||
import ControlHeader from '../../../../src/explore/components/ControlHeader';
|
||||
|
||||
const defaultProps = {
|
||||
@@ -57,6 +55,12 @@ describe('ViewportControl', () => {
|
||||
});
|
||||
|
||||
it('renders a summary in the label', () => {
|
||||
expect(wrapper.find(Label).first().render().text()).toBe('6° 51\' 8.50" | 31° 13\' 21.56"');
|
||||
expect(
|
||||
wrapper
|
||||
.find(Label)
|
||||
.first()
|
||||
.render()
|
||||
.text(),
|
||||
).toBe('6° 51\' 8.50" | 31° 13\' 21.56"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,14 +35,20 @@ describe('VizTypeControl', () => {
|
||||
|
||||
const registry = getChartMetadataRegistry();
|
||||
registry
|
||||
.registerValue('vis1', new ChartMetadata({
|
||||
name: 'vis1',
|
||||
thumbnail: '',
|
||||
}))
|
||||
.registerValue('vis2', new ChartMetadata({
|
||||
name: 'vis2',
|
||||
thumbnail: '',
|
||||
}));
|
||||
.registerValue(
|
||||
'vis1',
|
||||
new ChartMetadata({
|
||||
name: 'vis1',
|
||||
thumbnail: '',
|
||||
}),
|
||||
)
|
||||
.registerValue(
|
||||
'vis2',
|
||||
new ChartMetadata({
|
||||
name: 'vis2',
|
||||
thumbnail: '',
|
||||
}),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<VizTypeControl {...defaultProps} />);
|
||||
|
||||
@@ -42,7 +42,10 @@ const defaultProps = {
|
||||
getEndpoint: controlValues => `valid_metrics?data=${controlValues}`,
|
||||
};
|
||||
|
||||
const VALID_METRIC = { metric_name: 'sum__value', expression: 'SUM(energy_usage.value)' };
|
||||
const VALID_METRIC = {
|
||||
metric_name: 'sum__value',
|
||||
expression: 'SUM(energy_usage.value)',
|
||||
};
|
||||
|
||||
function setup(overrides, validMetric) {
|
||||
const onChange = sinon.spy();
|
||||
@@ -51,16 +54,22 @@ function setup(overrides, validMetric) {
|
||||
...defaultProps,
|
||||
...overrides,
|
||||
};
|
||||
const VerifiedControl = withVerification(MetricsControl, 'metric_name', 'savedMetrics');
|
||||
const VerifiedControl = withVerification(
|
||||
MetricsControl,
|
||||
'metric_name',
|
||||
'savedMetrics',
|
||||
);
|
||||
const wrapper = shallow(<VerifiedControl {...props} />);
|
||||
fetchMock.mock('glob:*/valid_metrics*', validMetric || `["${VALID_METRIC.metric_name}"]`);
|
||||
fetchMock.mock(
|
||||
'glob:*/valid_metrics*',
|
||||
validMetric || `["${VALID_METRIC.metric_name}"]`,
|
||||
);
|
||||
return { props, wrapper, onChange };
|
||||
}
|
||||
|
||||
afterEach(fetchMock.restore);
|
||||
|
||||
describe('VerifiedMetricsControl', () => {
|
||||
|
||||
it('Gets valid options', () => {
|
||||
const { wrapper } = setup();
|
||||
setTimeout(() => {
|
||||
@@ -92,7 +101,9 @@ describe('VerifiedMetricsControl', () => {
|
||||
});
|
||||
|
||||
it('Calls endpoint if control values change', () => {
|
||||
const { props, wrapper } = setup({ controlValues: { metrics: 'sum__value' } });
|
||||
const { props, wrapper } = setup({
|
||||
controlValues: { metrics: 'sum__value' },
|
||||
});
|
||||
setTimeout(() => {
|
||||
expect(fetchMock.calls(defaultProps.getEndpoint())).toHaveLength(1);
|
||||
fetchMock.reset();
|
||||
|
||||
@@ -27,57 +27,55 @@ import {
|
||||
describe('controlUtils', () => {
|
||||
const state = {
|
||||
datasource: {
|
||||
columns: [
|
||||
'a', 'b', 'c',
|
||||
],
|
||||
metrics: [
|
||||
{ metric_name: 'first' },
|
||||
{ metric_name: 'second' },
|
||||
],
|
||||
columns: ['a', 'b', 'c'],
|
||||
metrics: [{ metric_name: 'first' }, { metric_name: 'second' }],
|
||||
},
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
getChartControlPanelRegistry().registerValue('test-chart', {
|
||||
requiresTime: true,
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['color_scheme', {
|
||||
name: 'rose_area_proportion',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Use Area Proportions'),
|
||||
description: t(
|
||||
'Check if the Rose Chart should use segment area instead of ' +
|
||||
'segment radius for proportioning',
|
||||
),
|
||||
default: false,
|
||||
renderTrigger: true,
|
||||
},
|
||||
}],
|
||||
],
|
||||
getChartControlPanelRegistry()
|
||||
.registerValue('test-chart', {
|
||||
requiresTime: true,
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[
|
||||
'color_scheme',
|
||||
{
|
||||
name: 'rose_area_proportion',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Use Area Proportions'),
|
||||
description: t(
|
||||
'Check if the Rose Chart should use segment area instead of ' +
|
||||
'segment radius for proportioning',
|
||||
),
|
||||
default: false,
|
||||
renderTrigger: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
.registerValue('test-chart-override', {
|
||||
requiresTime: true,
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [['color_scheme']],
|
||||
},
|
||||
],
|
||||
controlOverrides: {
|
||||
color_scheme: {
|
||||
label: t('My beautiful colors'),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).registerValue('test-chart-override', {
|
||||
requiresTime: true,
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['color_scheme'],
|
||||
],
|
||||
},
|
||||
],
|
||||
controlOverrides: {
|
||||
color_scheme: {
|
||||
label: t('My beautiful colors'),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
@@ -101,20 +99,26 @@ describe('controlUtils', () => {
|
||||
expect(control.label).toEqual('My beautiful colors');
|
||||
});
|
||||
|
||||
it('returns correct control config when control config is defined ' +
|
||||
'in the control panel definition', () => {
|
||||
const roseAreaProportionControlConfig = getControlConfig('rose_area_proportion', 'test-chart');
|
||||
it(
|
||||
'returns correct control config when control config is defined ' +
|
||||
'in the control panel definition',
|
||||
() => {
|
||||
const roseAreaProportionControlConfig = getControlConfig(
|
||||
'rose_area_proportion',
|
||||
'test-chart',
|
||||
);
|
||||
expect(roseAreaProportionControlConfig).toEqual({
|
||||
type: 'CheckboxControl',
|
||||
label: t('Use Area Proportions'),
|
||||
description: t(
|
||||
'Check if the Rose Chart should use segment area instead of ' +
|
||||
'segment radius for proportioning',
|
||||
'segment radius for proportioning',
|
||||
),
|
||||
default: false,
|
||||
renderTrigger: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('applyMapStateToPropsToControl,', () => {
|
||||
@@ -129,7 +133,6 @@ describe('controlUtils', () => {
|
||||
control = applyMapStateToPropsToControl(control, state);
|
||||
expect(control.mapStateToProps).toBe(undefined);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getControlState', () => {
|
||||
|
||||
@@ -24,12 +24,16 @@ import * as actions from '../../../src/explore/actions/exploreActions';
|
||||
describe('reducers', () => {
|
||||
it('sets correct control value given a key and value', () => {
|
||||
const newState = exploreReducer(
|
||||
defaultState, actions.setControlValue('x_axis_label', 'x', []));
|
||||
defaultState,
|
||||
actions.setControlValue('x_axis_label', 'x', []),
|
||||
);
|
||||
expect(newState.controls.x_axis_label.value).toBe('x');
|
||||
});
|
||||
it('setControlValue works as expected with a checkbox', () => {
|
||||
const newState = exploreReducer(defaultState,
|
||||
actions.setControlValue('show_legend', true, []));
|
||||
const newState = exploreReducer(
|
||||
defaultState,
|
||||
actions.setControlValue('show_legend', true, []),
|
||||
);
|
||||
expect(newState.controls.show_legend.value).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,7 +37,6 @@ describe('store', () => {
|
||||
});
|
||||
|
||||
describe('applyDefaultFormData', () => {
|
||||
|
||||
window.featureFlags = {
|
||||
SCOPED_FILTER: false,
|
||||
};
|
||||
@@ -77,6 +76,5 @@ describe('store', () => {
|
||||
const outputFormData = applyDefaultFormData(inputFormData);
|
||||
expect(outputFormData.this_should_no_be_here).toBe(undefined);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
import sinon from 'sinon';
|
||||
|
||||
import URI from 'urijs';
|
||||
import { getExploreUrlAndPayload, getExploreLongUrl } from '../../../src/explore/exploreUtils';
|
||||
import {
|
||||
getExploreUrlAndPayload,
|
||||
getExploreLongUrl,
|
||||
} from '../../../src/explore/exploreUtils';
|
||||
import * as hostNamesConfig from '../../../src/utils/hostNamesConfig';
|
||||
|
||||
describe('exploreUtils', () => {
|
||||
@@ -44,10 +47,7 @@ describe('exploreUtils', () => {
|
||||
force: false,
|
||||
curUrl: 'http://superset.com',
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore/'),
|
||||
);
|
||||
compareURI(URI(url), URI('/superset/explore/'));
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
it('generates proper json url', () => {
|
||||
@@ -57,10 +57,7 @@ describe('exploreUtils', () => {
|
||||
force: false,
|
||||
curUrl: 'http://superset.com',
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/'),
|
||||
);
|
||||
compareURI(URI(url), URI('/superset/explore_json/'));
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
it('generates proper json forced url', () => {
|
||||
@@ -72,8 +69,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/')
|
||||
.search({ force: 'true' }),
|
||||
URI('/superset/explore_json/').search({ force: 'true' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -86,8 +82,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/')
|
||||
.search({ csv: 'true' }),
|
||||
URI('/superset/explore_json/').search({ csv: 'true' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -100,8 +95,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore/')
|
||||
.search({ standalone: 'true' }),
|
||||
URI('/superset/explore/').search({ standalone: 'true' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -114,8 +108,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/')
|
||||
.search({ foo: 'bar' }),
|
||||
URI('/superset/explore_json/').search({ foo: 'bar' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -128,8 +121,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/')
|
||||
.search({ foo: 'bar' }),
|
||||
URI('/superset/explore_json/').search({ foo: 'bar' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -142,8 +134,7 @@ describe('exploreUtils', () => {
|
||||
});
|
||||
compareURI(
|
||||
URI(url),
|
||||
URI('/superset/explore_json/')
|
||||
.search({ foo: 'bar' }),
|
||||
URI('/superset/explore_json/').search({ foo: 'bar' }),
|
||||
);
|
||||
expect(payload).toEqual(formData);
|
||||
});
|
||||
@@ -153,10 +144,14 @@ describe('exploreUtils', () => {
|
||||
let stub;
|
||||
const availableDomains = [
|
||||
'http://localhost/',
|
||||
'domain1.com', 'domain2.com', 'domain3.com',
|
||||
'domain1.com',
|
||||
'domain2.com',
|
||||
'domain3.com',
|
||||
];
|
||||
beforeEach(() => {
|
||||
stub = sinon.stub(hostNamesConfig, 'availableDomains').value(availableDomains);
|
||||
stub = sinon
|
||||
.stub(hostNamesConfig, 'availableDomains')
|
||||
.value(availableDomains);
|
||||
});
|
||||
afterEach(() => {
|
||||
stub.restore();
|
||||
|
||||
Reference in New Issue
Block a user