diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.jsx
index bfc7349107a2c..dd2c3e9e10436 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.jsx
@@ -16,16 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-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 { screen, render, selectOption } from 'spec/helpers/testing-library';
+import userEvent from '@testing-library/user-event';
import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
import AdhocMetric, {
EXPRESSION_TYPES,
} from 'src/explore/components/controls/MetricControl/AdhocMetric';
+import { AGGREGATES } from 'src/explore/constants';
const defaultProps = {
name: 'metrics',
@@ -45,131 +43,140 @@ const defaultProps = {
};
function setup(overrides) {
- const onChange = sinon.spy();
+ const onChange = jest.fn();
const props = {
onChange,
- theme: supersetTheme,
...defaultProps,
...overrides,
};
- const wrapper = shallow();
- const component = wrapper.shallow();
- return { wrapper, component, onChange };
+ render(, { useDnd: true });
+ return { onChange };
}
-const valueColumn = { type: 'DOUBLE', column_name: 'value' };
+const valueColumn = { type: 'double', column_name: 'value' };
const sumValueAdhocMetric = new AdhocMetric({
+ expressionType: EXPRESSION_TYPES.SIMPLE,
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();
- });
+test('renders the LabelsContainer', () => {
+ setup();
+ expect(screen.getByText('Metrics')).toBeInTheDocument();
+});
- 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,
- },
- ]);
- });
+test('coerces Adhoc Metrics from form data into instances of the AdhocMetric class and leaves saved metrics', () => {
+ setup({
+ value: [sumValueAdhocMetric],
});
- 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']]);
- });
+ const adhocMetric = screen.getByText('SUM(value)');
+ expect(adhocMetric).toBeInTheDocument();
+});
+
+test('handles creating a new metric', async () => {
+ const { onChange } = setup();
+
+ userEvent.click(screen.getByText(/add metric/i));
+ await selectOption('sum__value', /select saved metrics/i);
+ userEvent.click(screen.getByRole('button', { name: /save/i }));
+ expect(onChange).toHaveBeenCalledWith(['sum__value']);
+});
+
+test('accepts an edited metric from an AdhocMetricEditPopover', async () => {
+ const { onChange } = setup({
+ value: [sumValueAdhocMetric],
});
- describe('onMetricEdit', () => {
- it('accepts an edited metric from an AdhocMetricEditPopover', () => {
- const { component, onChange } = setup({
- value: [sumValueAdhocMetric],
- });
+ const metricLabel = screen.getByText('SUM(value)');
+ userEvent.click(metricLabel);
- const editedMetric = sumValueAdhocMetric.duplicateWith({
- aggregate: AGGREGATES.AVG,
- });
- component.instance().onMetricEdit(editedMetric, sumValueAdhocMetric);
+ await screen.findByText('aggregate');
+ selectOption('AVG', /select aggregate options/i);
- expect(onChange.lastCall.args).toEqual([[editedMetric]]);
- });
+ await screen.findByText('AVG(value)');
+
+ userEvent.click(screen.getByRole('button', { name: /save/i }));
+
+ expect(onChange).toHaveBeenCalledWith([
+ expect.objectContaining({
+ aggregate: AGGREGATES.AVG,
+ label: 'AVG(value)',
+ }),
+ ]);
+});
+
+test('removes metrics if savedMetrics changes', async () => {
+ setup({
+ value: [sumValueAdhocMetric],
});
- 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);
- });
+ expect(screen.getByText('SUM(value)')).toBeInTheDocument();
+ userEvent.click(screen.getByText('SUM(value)'));
+
+ const savedTab = screen.getByRole('tab', { name: /saved/i });
+ userEvent.click(savedTab);
+ await selectOption('avg__value', /select saved metrics/i);
+
+ const simpleTab = screen.getByRole('tab', { name: /simple/i });
+ userEvent.click(simpleTab);
+ await screen.findByText('aggregate');
+
+ expect(screen.queryByText('SUM')).not.toBeInTheDocument();
+ expect(screen.queryByText('value')).not.toBeInTheDocument();
+});
+
+test('does not remove custom SQL metric if savedMetrics changes', async () => {
+ const { rerender } = render(
+ ,
+ { useDnd: true },
+ );
+
+ expect(screen.getByText('old label')).toBeInTheDocument();
+
+ // Simulate removing columns
+ rerender(
+ ,
+ );
+
+ expect(screen.getByText('old label')).toBeInTheDocument();
+});
+
+test('does not fail if no columns or savedMetrics are passed', () => {
+ setup({
+ savedMetrics: null,
+ columns: null,
});
+ expect(screen.getByText(/add metric/i)).toBeInTheDocument();
});