mirror of
https://github.com/apache/superset.git
synced 2026-06-01 05:39:17 +00:00
chore: Moves spec files to the src folder - iteration 10 (#17902)
* chore: Moves spec files to the src folder - iteration 10 * Fixes test * Fixes lint problem * Uses styledMount in test
This commit is contained in:
committed by
GitHub
parent
bb7e979142
commit
647bbf1ea1
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
|
||||
const valueColumn = { type: 'DOUBLE', column_name: 'value' };
|
||||
|
||||
describe('AdhocMetric', () => {
|
||||
it('sets label, hasCustomLabel and optionName in constructor', () => {
|
||||
const adhocMetric = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
expect(adhocMetric.optionName.length).toBeGreaterThan(10);
|
||||
expect(adhocMetric).toEqual({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
hasCustomLabel: false,
|
||||
optionName: adhocMetric.optionName,
|
||||
sqlExpression: null,
|
||||
isNew: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('can create altered duplicates', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
isNew: true,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric1.column).toBe(adhocMetric2.column);
|
||||
expect(adhocMetric1.column).toBe(valueColumn);
|
||||
|
||||
expect(adhocMetric1.aggregate).toBe(AGGREGATES.SUM);
|
||||
expect(adhocMetric2.aggregate).toBe(AGGREGATES.AVG);
|
||||
|
||||
// duplicated clone should not be new
|
||||
expect(adhocMetric1.isNew).toBe(true);
|
||||
expect(adhocMetric2.isNew).toStrictEqual(false);
|
||||
});
|
||||
|
||||
it('can verify equality', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({});
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric1.equals(adhocMetric2)).toBe(true);
|
||||
});
|
||||
|
||||
it('can verify inequality', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'old label',
|
||||
hasCustomLabel: true,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({ label: 'new label' });
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric1.equals(adhocMetric2)).toBe(false);
|
||||
|
||||
const adhocMetric3 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'COUNT(*)',
|
||||
label: 'old label',
|
||||
hasCustomLabel: true,
|
||||
});
|
||||
const adhocMetric4 = adhocMetric3.duplicateWith({
|
||||
sqlExpression: 'COUNT(1)',
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric3.equals(adhocMetric4)).toBe(false);
|
||||
});
|
||||
|
||||
it('updates label if hasCustomLabel is false', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric2.label).toBe('AVG(value)');
|
||||
});
|
||||
|
||||
it('keeps label if hasCustomLabel is true', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
const adhocMetric2 = adhocMetric1.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
|
||||
expect(adhocMetric2.label).toBe('label1');
|
||||
});
|
||||
|
||||
it('can determine if it is valid', () => {
|
||||
const adhocMetric1 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric1.isValid()).toBe(true);
|
||||
|
||||
const adhocMetric2 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
aggregate: null,
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric2.isValid()).toBe(false);
|
||||
|
||||
const adhocMetric3 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'COUNT(*)',
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric3.isValid()).toBe(true);
|
||||
|
||||
const adhocMetric4 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(adhocMetric4.isValid()).toBe(false);
|
||||
|
||||
const adhocMetric5 = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
hasCustomLabel: true,
|
||||
label: 'label1',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
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');
|
||||
|
||||
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');
|
||||
|
||||
const adhocMetric3 = adhocMetric.duplicateWith({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: valueColumn,
|
||||
});
|
||||
expect(adhocMetric3.aggregate).toBe(AGGREGATES.AVG);
|
||||
expect(adhocMetric3.column.column_name).toBe('value');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormItem } from 'src/components/Form';
|
||||
import Button from 'src/components/Button';
|
||||
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import AdhocMetricEditPopover from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopover';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
|
||||
const columns = [
|
||||
{ type: 'VARCHAR(255)', column_name: 'source', id: 1 },
|
||||
{ type: 'VARCHAR(255)', column_name: 'target', id: 2 },
|
||||
{ type: 'DOUBLE', column_name: 'value', id: 3 },
|
||||
];
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: columns[2],
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
|
||||
const sqlExpressionAdhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'COUNT(*)',
|
||||
});
|
||||
|
||||
function setup(overrides) {
|
||||
const onChange = sinon.spy();
|
||||
const onClose = sinon.spy();
|
||||
const props = {
|
||||
adhocMetric: sumValueAdhocMetric,
|
||||
savedMetric: { metric_name: 'foo', expression: 'COUNT(*)' },
|
||||
savedMetrics: [],
|
||||
onChange,
|
||||
onClose,
|
||||
onResize: () => {},
|
||||
getCurrentLabel: () => {},
|
||||
columns,
|
||||
...overrides,
|
||||
};
|
||||
const wrapper = shallow(<AdhocMetricEditPopover {...props} />);
|
||||
return { wrapper, onChange, onClose };
|
||||
}
|
||||
|
||||
describe('AdhocMetricEditPopover', () => {
|
||||
it('renders a popover with edit metric form contents', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(FormItem)).toHaveLength(3);
|
||||
expect(wrapper.find(Button)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onColumnChange', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onColumnChange(columns[0].column_name);
|
||||
expect(wrapper.state('adhocMetric')).toEqual(
|
||||
sumValueAdhocMetric.duplicateWith({ column: columns[0] }),
|
||||
);
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onAggregateChange', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onAggregateChange(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)' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('prevents saving if no column or aggregate is chosen', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
||||
wrapper.instance().onColumnChange(null);
|
||||
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
||||
wrapper.instance().onColumnChange(columns[0].column_name);
|
||||
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
||||
wrapper.instance().onAggregateChange(null);
|
||||
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
||||
});
|
||||
|
||||
it('highlights save if changes are present', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).not.toExist();
|
||||
wrapper.instance().onColumnChange(columns[1].column_name);
|
||||
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).toExist();
|
||||
});
|
||||
|
||||
it('will initiate a drag when clicked', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onDragDown = sinon.spy();
|
||||
wrapper.instance().forceUpdate();
|
||||
|
||||
expect(wrapper.find('.fa-expand')).toExist();
|
||||
expect(wrapper.instance().onDragDown.calledOnce).toBe(false);
|
||||
wrapper.find('.fa-expand').simulate('mouseDown');
|
||||
expect(wrapper.instance().onDragDown.calledOnce).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
|
||||
import AdhocMetricEditPopoverTitle from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle';
|
||||
|
||||
const title = {
|
||||
label: 'Title',
|
||||
hasCustomLabel: false,
|
||||
};
|
||||
|
||||
function setup(overrides) {
|
||||
const onChange = sinon.spy();
|
||||
const props = {
|
||||
title,
|
||||
onChange,
|
||||
...overrides,
|
||||
};
|
||||
const wrapper = shallow(<AdhocMetricEditPopoverTitle {...props} />);
|
||||
return { wrapper, onChange };
|
||||
}
|
||||
|
||||
describe('AdhocMetricEditPopoverTitle', () => {
|
||||
it('renders an OverlayTrigger wrapper with the title', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(Tooltip)).toExist();
|
||||
expect(
|
||||
wrapper.find('[data-test="AdhocMetricEditTitle#trigger"]').text(),
|
||||
).toBe(`${title.label}\xa0`);
|
||||
});
|
||||
|
||||
it('transfers to edit mode when clicked', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.state('isEditMode')).toBe(false);
|
||||
wrapper
|
||||
.find('[data-test="AdhocMetricEditTitle#trigger"]')
|
||||
.simulate('click');
|
||||
expect(wrapper.state('isEditMode')).toBe(true);
|
||||
});
|
||||
|
||||
it('Render non-interactive span with title when edit is disabled', () => {
|
||||
const { wrapper } = setup({ isEditDisabled: true });
|
||||
expect(
|
||||
wrapper.find('[data-test="AdhocMetricTitle"]').exists(),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
wrapper.find('[data-test="AdhocMetricEditTitle#trigger"]').exists(),
|
||||
).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import Popover from 'src/components/Popover';
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import AdhocMetricOption from 'src/explore/components/controls/MetricControl/AdhocMetricOption';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
|
||||
const columns = [
|
||||
{ type: 'VARCHAR(255)', column_name: 'source' },
|
||||
{ type: 'VARCHAR(255)', column_name: 'target' },
|
||||
{ type: 'DOUBLE', column_name: 'value' },
|
||||
];
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
column: columns[2],
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
|
||||
function setup(overrides) {
|
||||
const onMetricEdit = sinon.spy();
|
||||
const props = {
|
||||
adhocMetric: sumValueAdhocMetric,
|
||||
savedMetric: {},
|
||||
savedMetrics: [],
|
||||
onMetricEdit,
|
||||
columns,
|
||||
onMoveLabel: () => {},
|
||||
onDropLabel: () => {},
|
||||
index: 0,
|
||||
...overrides,
|
||||
};
|
||||
const wrapper = shallow(<AdhocMetricOption {...props} />)
|
||||
.find('AdhocMetricPopoverTrigger')
|
||||
.shallow();
|
||||
return { wrapper, onMetricEdit };
|
||||
}
|
||||
|
||||
describe('AdhocMetricOption', () => {
|
||||
it('renders an overlay trigger wrapper for the label', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.find(Popover)).toExist();
|
||||
expect(wrapper.find('OptionControlLabel')).toExist();
|
||||
});
|
||||
|
||||
it('overwrites the adhocMetric in state with onLabelChange', () => {
|
||||
const { wrapper } = setup();
|
||||
wrapper.instance().onLabelChange({ target: { value: 'new label' } });
|
||||
expect(wrapper.state('title').label).toBe('new label');
|
||||
expect(wrapper.state('title').hasCustomLabel).toBe(true);
|
||||
});
|
||||
|
||||
it('returns to default labels when the custom label is cleared', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.state('title').label).toBe('SUM(value)');
|
||||
|
||||
wrapper.instance().onLabelChange({ target: { value: 'new label' } });
|
||||
expect(wrapper.state('title').label).toBe('new label');
|
||||
|
||||
wrapper.instance().onLabelChange({ target: { value: '' } });
|
||||
|
||||
expect(wrapper.state('title').label).toBe('SUM(value)');
|
||||
expect(wrapper.state('title').hasCustomLabel).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
|
||||
import AggregateOption from 'src/explore/components/controls/MetricControl/AggregateOption';
|
||||
|
||||
describe('AggregateOption', () => {
|
||||
it('renders the aggregate', () => {
|
||||
render(<AggregateOption aggregate={{ aggregate_name: 'SUM' }} />);
|
||||
|
||||
const aggregateOption = screen.getByText(/sum/i);
|
||||
expect(aggregateOption).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
import { StyledColumnOption } from 'src/explore/components/optionRenderers';
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: { type: 'VARCHAR(255)', column_name: 'source' },
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
|
||||
describe('FilterDefinitionOption', () => {
|
||||
it('renders a StyledColumnOption given a column', () => {
|
||||
const wrapper = shallow(
|
||||
<FilterDefinitionOption option={{ column_name: 'a_column' }} />,
|
||||
);
|
||||
expect(wrapper.find(StyledColumnOption)).toExist();
|
||||
});
|
||||
|
||||
it('renders a StyledColumnOption given an adhoc metric', () => {
|
||||
const wrapper = shallow(
|
||||
<FilterDefinitionOption option={sumValueAdhocMetric} />,
|
||||
);
|
||||
expect(wrapper.find(StyledColumnOption)).toExist();
|
||||
});
|
||||
|
||||
it('renders the metric name given a saved metric', () => {
|
||||
const wrapper = mount(
|
||||
<FilterDefinitionOption
|
||||
option={{ saved_metric_name: 'my_custom_metric' }}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('.option-label').text()).toBe('my_custom_metric');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import MetricDefinitionOption from 'src/explore/components/controls/MetricControl/MetricDefinitionOption';
|
||||
import AggregateOption from 'src/explore/components/controls/MetricControl/AggregateOption';
|
||||
import {
|
||||
StyledMetricOption,
|
||||
StyledColumnOption,
|
||||
} from 'src/explore/components/optionRenderers';
|
||||
|
||||
describe('MetricDefinitionOption', () => {
|
||||
const mockStore = configureStore([]);
|
||||
const store = mockStore({});
|
||||
|
||||
function setup(props) {
|
||||
return shallow(<MetricDefinitionOption store={store} {...props} />).dive();
|
||||
}
|
||||
|
||||
it('renders a StyledMetricOption given a saved metric', () => {
|
||||
const wrapper = setup({
|
||||
option: { metric_name: 'a_saved_metric', expression: 'COUNT(*)' },
|
||||
});
|
||||
expect(wrapper.find(StyledMetricOption)).toExist();
|
||||
});
|
||||
|
||||
it('renders a StyledColumnOption given a column', () => {
|
||||
const wrapper = setup({ option: { column_name: 'a_column' } });
|
||||
expect(wrapper.find(StyledColumnOption)).toExist();
|
||||
});
|
||||
|
||||
it('renders an AggregateOption given an aggregate metric', () => {
|
||||
const wrapper = setup({ option: { aggregate_name: 'an_aggregate' } });
|
||||
expect(wrapper.find(AggregateOption)).toExist();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import MetricDefinitionValue from 'src/explore/components/controls/MetricControl/MetricDefinitionValue';
|
||||
import AdhocMetricOption from 'src/explore/components/controls/MetricControl/AdhocMetricOption';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
column: { type: 'DOUBLE', column_name: 'value' },
|
||||
aggregate: AGGREGATES.SUM,
|
||||
});
|
||||
|
||||
describe('MetricDefinitionValue', () => {
|
||||
it('renders a MetricOption given a saved metric', () => {
|
||||
const wrapper = shallow(
|
||||
<MetricDefinitionValue
|
||||
onMetricEdit={() => {}}
|
||||
option={{ metric_name: 'a_saved_metric', expression: 'COUNT(*)' }}
|
||||
index={1}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('AdhocMetricOption')).toExist();
|
||||
});
|
||||
|
||||
it('renders an AdhocMetricOption given an adhoc metric', () => {
|
||||
const wrapper = shallow(
|
||||
<MetricDefinitionValue
|
||||
onMetricEdit={() => {}}
|
||||
option={sumValueAdhocMetric}
|
||||
index={1}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find(AdhocMetricOption)).toExist();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import { LabelsContainer } from 'src/explore/components/controls/OptionControls';
|
||||
import { supersetTheme } from '@superset-ui/core';
|
||||
import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
|
||||
import AdhocMetric, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
|
||||
const defaultProps = {
|
||||
name: 'metrics',
|
||||
label: 'Metrics',
|
||||
value: undefined,
|
||||
multi: true,
|
||||
columns: [
|
||||
{ type: 'VARCHAR(255)', column_name: 'source' },
|
||||
{ type: 'VARCHAR(255)', column_name: 'target' },
|
||||
{ type: 'DOUBLE', column_name: 'value' },
|
||||
],
|
||||
savedMetrics: [
|
||||
{ metric_name: 'sum__value', expression: 'SUM(energy_usage.value)' },
|
||||
{ metric_name: 'avg__value', expression: 'AVG(energy_usage.value)' },
|
||||
],
|
||||
datasourceType: 'sqla',
|
||||
};
|
||||
|
||||
function setup(overrides) {
|
||||
const onChange = sinon.spy();
|
||||
const props = {
|
||||
onChange,
|
||||
theme: supersetTheme,
|
||||
...defaultProps,
|
||||
...overrides,
|
||||
};
|
||||
const wrapper = shallow(<MetricsControl {...props} />);
|
||||
const component = wrapper.shallow();
|
||||
return { wrapper, component, onChange };
|
||||
}
|
||||
|
||||
const valueColumn = { type: 'DOUBLE', column_name: 'value' };
|
||||
|
||||
const sumValueAdhocMetric = new AdhocMetric({
|
||||
column: valueColumn,
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
});
|
||||
|
||||
// TODO: rewrite the tests to RTL
|
||||
describe.skip('MetricsControl', () => {
|
||||
it('renders Select', () => {
|
||||
const { component } = setup();
|
||||
expect(component.find(LabelsContainer)).toExist();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('coerces Adhoc Metrics from form data into instances of the AdhocMetric class and leaves saved metrics', () => {
|
||||
const { component } = setup({
|
||||
value: [
|
||||
{
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: { type: 'double', column_name: 'value' },
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
optionName: 'blahblahblah',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const adhocMetric = component.state('value')[0];
|
||||
expect(adhocMetric instanceof AdhocMetric).toBe(true);
|
||||
expect(adhocMetric.optionName.length).toBeGreaterThan(10);
|
||||
expect(component.state('value')).toEqual([
|
||||
{
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: { type: 'double', column_name: 'value' },
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
hasCustomLabel: false,
|
||||
optionName: 'blahblahblah',
|
||||
sqlExpression: null,
|
||||
isNew: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onChange', () => {
|
||||
it('handles creating a new metric', () => {
|
||||
const { component, onChange } = setup();
|
||||
component.instance().onNewMetric({
|
||||
metric_name: 'sum__value',
|
||||
expression: 'SUM(energy_usage.value)',
|
||||
});
|
||||
expect(onChange.lastCall.args).toEqual([['sum__value']]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onMetricEdit', () => {
|
||||
it('accepts an edited metric from an AdhocMetricEditPopover', () => {
|
||||
const { component, onChange } = setup({
|
||||
value: [sumValueAdhocMetric],
|
||||
});
|
||||
|
||||
const editedMetric = sumValueAdhocMetric.duplicateWith({
|
||||
aggregate: AGGREGATES.AVG,
|
||||
});
|
||||
component.instance().onMetricEdit(editedMetric, sumValueAdhocMetric);
|
||||
|
||||
expect(onChange.lastCall.args).toEqual([[editedMetric]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('option filter', () => {
|
||||
it('Removes metrics if savedMetrics changes', () => {
|
||||
const { props, component, onChange } = setup({
|
||||
value: [
|
||||
{
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
column: { type: 'double', column_name: 'value' },
|
||||
aggregate: AGGREGATES.SUM,
|
||||
label: 'SUM(value)',
|
||||
optionName: 'blahblahblah',
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(component.state('value')).toHaveLength(1);
|
||||
|
||||
component.setProps({ ...props, columns: [] });
|
||||
expect(onChange.lastCall.args).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('Does not remove custom sql metric if savedMetrics changes', () => {
|
||||
const { props, component, onChange } = setup({
|
||||
value: [
|
||||
{
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'COUNT(*)',
|
||||
label: 'old label',
|
||||
hasCustomLabel: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(component.state('value')).toHaveLength(1);
|
||||
|
||||
component.setProps({ ...props, columns: [] });
|
||||
expect(onChange.calledOnce).toEqual(false);
|
||||
});
|
||||
it('Does not fail if no columns or savedMetrics are passed', () => {
|
||||
const { component } = setup({
|
||||
savedMetrics: null,
|
||||
columns: null,
|
||||
});
|
||||
expect(component.exists('.metrics-select')).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user