blob: 359db207f0bf3459b5d4942b0ea2fbca11b4769e [file] [log] [blame]
/**
* 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 { render } from 'spec/helpers/testing-library';
import withAsyncVerification, {
ControlPropsWithExtras,
WithAsyncVerificationOptions,
} from 'src/explore/components/controls/withAsyncVerification';
import { ExtraControlProps } from '@superset-ui/chart-controls';
import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
const VALID_METRIC = {
metric_name: 'sum__value',
expression: 'SUM(energy_usage.value)',
};
const mockSetControlValue = jest.fn();
const defaultProps = {
name: 'metrics',
label: 'Metrics',
value: undefined,
multi: true,
needAsyncVerification: true,
actions: { setControlValue: mockSetControlValue },
onChange: (p0: string[]) => {
console.log('onChange called with:', p0);
},
columns: [
{ type: 'VARCHAR(255)', column_name: 'source' },
{ type: 'VARCHAR(255)', column_name: 'target' },
{ type: 'DOUBLE', column_name: 'value' },
],
savedMetrics: [
VALID_METRIC,
{ metric_name: 'avg__value', expression: 'AVG(energy_usage.value)' },
],
datasourceType: 'sqla',
};
function verify(sourceProp: string) {
const mock = jest.fn();
mock.mockImplementation(async (props: ControlPropsWithExtras) => ({
[sourceProp]: props.validMetrics || [VALID_METRIC],
}));
return mock;
}
async function setup({
extraProps,
baseControl = MetricsControl as WithAsyncVerificationOptions['baseControl'],
onChange,
}: Partial<WithAsyncVerificationOptions> & {
extraProps?: ExtraControlProps;
} = {}) {
const props = {
...defaultProps,
...extraProps,
};
const verifier = verify('savedMetrics');
const VerifiedControl = withAsyncVerification({
baseControl,
verify: verifier,
onChange,
});
const utils = render(<VerifiedControl {...props} />);
return { props, ...utils, verifier, VerifiedControl };
}
// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
describe('VerifiedMetricsControl', () => {
test('should call verify correctly', async () => {
expect.assertions(3);
const { verifier, props, rerender, VerifiedControl } = await setup();
expect(verifier).toHaveBeenCalledTimes(1);
expect(verifier).toHaveBeenCalledWith(
expect.objectContaining({ savedMetrics: props.savedMetrics }),
);
// should call verifier with new props when props are updated
rerender(<VerifiedControl {...props} validMetric={['abc']} />);
expect(verifier).toHaveBeenCalledWith(
expect.objectContaining({ validMetric: ['abc'] }),
);
});
test('should trigger onChange event', async () => {
expect.assertions(2);
const mockOnChange = jest.fn();
const { verifier, props } = await setup({
baseControl: 'MetricsControl',
onChange: mockOnChange,
extraProps: {
onChange: (value: any) => {
// Simulate the MetricsControl onChange
mockOnChange(value, props);
},
},
});
// Wait for the initial verification to complete
await verifier;
// Call the onChange from props
props.onChange(['sum__value']);
expect(mockOnChange).toHaveBeenCalledTimes(1);
expect(mockOnChange).toHaveBeenCalledWith(['sum__value'], props);
});
});