AzureMonitor: Fix metric namespace clear (#41878)

This commit is contained in:
Andres Martinez Gotor 2021-11-19 10:16:56 +01:00 committed by GitHub
parent 11f133b406
commit c5241731de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 12 deletions

View File

@ -0,0 +1,42 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import MetricNamespaceField from './MetricNamespaceField';
import createMockQuery from '../../__mocks__/query';
import createMockDatasource from '../../__mocks__/datasource';
import { AzureMonitorOption } from '../../types';
const props = {
metricNamespaces: [],
query: createMockQuery(),
datasource: createMockDatasource(),
variableOptionGroup: { label: 'Templates', options: [] },
onQueryChange: jest.fn(),
setError: jest.fn(),
};
describe('Azure Monitor QueryEditor', () => {
it('should render the current value', async () => {
const metricNamespaces: AzureMonitorOption[] = [{ label: 'foo', value: 'foo' }];
const query = {
...props.query,
azureMonitor: {
metricNamespace: 'foo',
},
};
render(<MetricNamespaceField {...props} metricNamespaces={metricNamespaces} query={query} />);
expect(screen.queryByText('foo')).toBeInTheDocument();
});
it('should render the current value even if it is not in the list of options', async () => {
const metricNamespaces: AzureMonitorOption[] = [{ label: 'foo', value: 'foo' }];
const query = {
...props.query,
azureMonitor: {
metricNamespace: 'bar',
},
};
render(<MetricNamespaceField {...props} metricNamespaces={metricNamespaces} query={query} />);
expect(screen.queryByText('bar')).toBeInTheDocument();
expect(screen.queryByText('foo')).not.toBeInTheDocument();
});
});

View File

@ -29,6 +29,11 @@ const MetricNamespaceField: React.FC<MetricNamespaceFieldProps> = ({
); );
const options = useMemo(() => [...metricNamespaces, variableOptionGroup], [metricNamespaces, variableOptionGroup]); const options = useMemo(() => [...metricNamespaces, variableOptionGroup], [metricNamespaces, variableOptionGroup]);
const optionValues = metricNamespaces.map((m) => m.value).concat(variableOptionGroup.options.map((p) => p.value));
const value = query.azureMonitor?.metricNamespace;
if (value && !optionValues.includes(value)) {
options.push({ label: value, value });
}
return ( return (
<Field label="Metric namespace"> <Field label="Metric namespace">

View File

@ -5,6 +5,7 @@ import {
updateSubscriptions, updateSubscriptions,
useAsyncState, useAsyncState,
useMetricNames, useMetricNames,
useMetricNamespaces,
useResourceGroups, useResourceGroups,
useResourceNames, useResourceNames,
useResourceTypes, useResourceTypes,
@ -93,7 +94,7 @@ interface TestScenario {
invalidQueryPartial: AzureMetricQuery; invalidQueryPartial: AzureMetricQuery;
templateVariableQueryPartial: AzureMetricQuery; templateVariableQueryPartial: AzureMetricQuery;
expectedClearedQueryPartial: AzureMetricQuery; expectedClearedQueryPartial?: AzureMetricQuery;
expectedOptions: AzureMonitorOption[]; expectedOptions: AzureMonitorOption[];
} }
@ -253,6 +254,47 @@ describe('AzureMonitor: metrics dataHooks', () => {
metricName: undefined, metricName: undefined,
}, },
}, },
{
name: 'useMetricNamespaces',
hook: useMetricNamespaces,
emptyQueryPartial: {
resourceGroup: 'web-app-development',
metricDefinition: 'azure/vm',
resourceName: 'web-server',
metricNamespace: 'azure/vm',
},
validQueryPartial: {
resourceGroup: 'web-app-development',
metricDefinition: 'azure/vm',
resourceName: 'web-server',
metricNamespace: 'azure/vm',
},
invalidQueryPartial: {
resourceGroup: 'web-app-development',
metricDefinition: 'azure/vm',
resourceName: 'web-server',
metricNamespace: 'azure/vm',
metricName: 'invalid-metric',
},
templateVariableQueryPartial: {
resourceGroup: 'web-app-development',
metricDefinition: 'azure/vm',
resourceName: 'web-server',
metricNamespace: 'azure/vm',
metricName: '$variable',
},
expectedOptions: [
{
label: 'Compute Virtual Machine',
value: 'azure/vmc',
},
{
label: 'Database NS',
value: 'azure/dbns',
},
],
},
]; ];
let datasource: MockedObjectDeep<Datasource>; let datasource: MockedObjectDeep<Datasource>;
@ -284,8 +326,11 @@ describe('AzureMonitor: metrics dataHooks', () => {
datasource.getMetricNames = jest datasource.getMetricNames = jest
.fn() .fn()
.mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]); .mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]);
});
datasource.getMetricNamespaces = jest
.fn()
.mockResolvedValue([opt('Compute Virtual Machine', 'azure/vmc'), opt('Database NS', 'azure/dbns')]);
});
describe.each(testTable)('scenario %#: $name', (scenario) => { describe.each(testTable)('scenario %#: $name', (scenario) => {
it('returns values', async () => { it('returns values', async () => {
const query = { const query = {
@ -339,14 +384,18 @@ describe('AzureMonitor: metrics dataHooks', () => {
const { waitForNextUpdate } = renderHook(() => scenario.hook(query, datasource, onChange, setError)); const { waitForNextUpdate } = renderHook(() => scenario.hook(query, datasource, onChange, setError));
await waitForNextUpdate(WAIT_OPTIONS); await waitForNextUpdate(WAIT_OPTIONS);
expect(onChange).toHaveBeenCalledWith({ if (scenario.expectedClearedQueryPartial) {
...query, expect(onChange).toHaveBeenCalledWith({
azureMonitor: { ...query,
...scenario.expectedClearedQueryPartial, azureMonitor: {
dimensionFilters: [], ...scenario.expectedClearedQueryPartial,
timeGrain: '', dimensionFilters: [],
}, timeGrain: '',
}); },
});
} else {
expect(onChange).not.toHaveBeenCalled();
}
}); });
}); });
}); });

View File

@ -193,8 +193,6 @@ export const useMetricNamespaces: DataHook = (query, datasource, onChange, setEr
// Do some cleanup of the query state if need be // Do some cleanup of the query state if need be
if (!metricNamespace && options.length) { if (!metricNamespace && options.length) {
onChange(setMetricNamespace(query, options[0].value)); onChange(setMetricNamespace(query, options[0].value));
} else if (options[0] && isInvalidOption(metricNamespace, options, datasource.getVariables())) {
onChange(setMetricNamespace(query, options[0].value));
} }
return options; return options;