mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Set default query type values in Explore only for new queries (#41263)
* Prometheus: Override query type only for new queries * Update comment * Add tests * Fix test
This commit is contained in:
parent
ed030f9c21
commit
9e996eaca7
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import { PromExploreExtraFieldProps, PromExploreExtraField } from './PromExploreExtraField';
|
import { PromExploreExtraFieldProps, PromExploreExtraField, testIds } from './PromExploreExtraField';
|
||||||
|
|
||||||
const setup = (propOverrides?: PromExploreExtraFieldProps) => {
|
const setup = (propOverrides?: PromExploreExtraFieldProps) => {
|
||||||
const query = { exemplar: false };
|
const query = { exemplar: false };
|
||||||
@ -23,11 +23,11 @@ const setup = (propOverrides?: PromExploreExtraFieldProps) => {
|
|||||||
describe('PromExploreExtraField', () => {
|
describe('PromExploreExtraField', () => {
|
||||||
it('should render step field', () => {
|
it('should render step field', () => {
|
||||||
setup();
|
setup();
|
||||||
expect(screen.getByTestId('stepField')).toBeInTheDocument();
|
expect(screen.getByTestId(testIds.stepField)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render query type field', () => {
|
it('should render query type field', () => {
|
||||||
setup();
|
setup();
|
||||||
expect(screen.getByTestId('queryTypeField')).toBeInTheDocument();
|
expect(screen.getByTestId(testIds.queryTypeField)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -66,10 +66,10 @@ export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div aria-label="Prometheus extra field" className="gf-form-inline">
|
<div aria-label="Prometheus extra field" className="gf-form-inline" data-testid={testIds.extraFieldEditor}>
|
||||||
{/*Query type field*/}
|
{/*Query type field*/}
|
||||||
<div
|
<div
|
||||||
data-testid="queryTypeField"
|
data-testid={testIds.queryTypeField}
|
||||||
className={cx(
|
className={cx(
|
||||||
'gf-form explore-input-margin',
|
'gf-form explore-input-margin',
|
||||||
css`
|
css`
|
||||||
@ -82,13 +82,13 @@ export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
|
|||||||
|
|
||||||
<RadioButtonGroup
|
<RadioButtonGroup
|
||||||
options={rangeOptions}
|
options={rangeOptions}
|
||||||
value={query.range === query.instant ? 'both' : query.instant ? 'instant' : 'range'}
|
value={query.range && query.instant ? 'both' : query.instant ? 'instant' : 'range'}
|
||||||
onChange={onQueryTypeChange}
|
onChange={onQueryTypeChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/*Step field*/}
|
{/*Step field*/}
|
||||||
<div
|
<div
|
||||||
data-testid="stepField"
|
data-testid={testIds.stepField}
|
||||||
className={cx(
|
className={cx(
|
||||||
'gf-form',
|
'gf-form',
|
||||||
css`
|
css`
|
||||||
@ -120,3 +120,9 @@ export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const testIds = {
|
||||||
|
extraFieldEditor: 'prom-editor-extra-field',
|
||||||
|
stepField: 'prom-editor-extra-field-step',
|
||||||
|
queryTypeField: 'prom-editor-extra-field-query-type',
|
||||||
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { render, screen } from '@testing-library/react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import PromExploreQueryEditor, { testIds } from './PromExploreQueryEditor';
|
||||||
import PromExploreQueryEditor from './PromExploreQueryEditor';
|
import { testIds as extraFieldTestIds } from './PromExploreExtraField';
|
||||||
import { PrometheusDatasource } from '../datasource';
|
import { PrometheusDatasource } from '../datasource';
|
||||||
import { PromQuery } from '../types';
|
import { PromQuery } from '../types';
|
||||||
import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data';
|
import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data';
|
||||||
@ -16,18 +16,21 @@ jest.mock('./monaco-query-field/MonacoQueryFieldWrapper', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const setup = (renderMethod: any, propOverrides?: object) => {
|
const setup = (propOverrides?: object) => {
|
||||||
const datasourceMock: unknown = {
|
const datasourceMock: unknown = {
|
||||||
languageProvider: {
|
languageProvider: {
|
||||||
syntax: () => {},
|
syntax: () => {},
|
||||||
getLabelKeys: () => [],
|
getLabelKeys: () => [],
|
||||||
metrics: [],
|
metrics: [],
|
||||||
|
start: () => Promise.resolve([]),
|
||||||
},
|
},
|
||||||
|
getInitHints: () => [],
|
||||||
|
exemplarsAvailable: true,
|
||||||
};
|
};
|
||||||
const datasource: PrometheusDatasource = datasourceMock as PrometheusDatasource;
|
const datasource: PrometheusDatasource = datasourceMock as PrometheusDatasource;
|
||||||
const onRunQuery = jest.fn();
|
const onRunQuery = jest.fn();
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const query: PromQuery = { expr: '', refId: 'A', interval: '1s' };
|
const query: PromQuery = { expr: '', refId: 'A', interval: '1s', exemplar: true };
|
||||||
const range: TimeRange = {
|
const range: TimeRange = {
|
||||||
from: toUtc('2020-01-01', 'YYYY-MM-DD'),
|
from: toUtc('2020-01-01', 'YYYY-MM-DD'),
|
||||||
to: toUtc('2020-01-02', 'YYYY-MM-DD'),
|
to: toUtc('2020-01-02', 'YYYY-MM-DD'),
|
||||||
@ -84,30 +87,55 @@ const setup = (renderMethod: any, propOverrides?: object) => {
|
|||||||
|
|
||||||
Object.assign(props, propOverrides);
|
Object.assign(props, propOverrides);
|
||||||
|
|
||||||
return renderMethod(<PromExploreQueryEditor {...props} />);
|
return <PromExploreQueryEditor {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('PromExploreQueryEditor', () => {
|
describe('PromExploreQueryEditor', () => {
|
||||||
let originalGetSelection: typeof window.getSelection;
|
|
||||||
beforeAll(() => {
|
|
||||||
originalGetSelection = window.getSelection;
|
|
||||||
window.getSelection = () => null;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
window.getSelection = originalGetSelection;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render component', () => {
|
it('should render component', () => {
|
||||||
const wrapper = setup(shallow);
|
render(setup());
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(screen.getByTestId(testIds.editor)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render PromQueryField with ExtraFieldElement', async () => {
|
it('should render PromQueryField with ExtraFieldElement', async () => {
|
||||||
// @ts-ignore strict null errpr TS2345: Argument of type '() => Promise<void>' is not assignable to parameter of type '() => void | undefined'.
|
render(setup());
|
||||||
await act(async () => {
|
expect(screen.getByTestId(extraFieldTestIds.extraFieldEditor)).toBeInTheDocument();
|
||||||
const wrapper = setup(shallow);
|
});
|
||||||
expect(wrapper.html()).toContain('aria-label="Prometheus extra field"');
|
|
||||||
});
|
it('should set default value for expr if it is undefined', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const query = { expr: undefined, exemplar: false, instant: false, range: true };
|
||||||
|
render(setup({ onChange, query }));
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ expr: '' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set default value for exemplars if it is undefined', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const query = { expr: '', instant: false, range: true };
|
||||||
|
render(setup({ onChange, query }));
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ exemplar: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set default value for instant and range if expr is falsy', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
let query = { expr: '', exemplar: true };
|
||||||
|
render(setup({ onChange, query }));
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ instant: true, range: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set default value for instant and range with truthy expr', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
let query = { expr: 'foo', exemplar: true };
|
||||||
|
render(setup({ onChange, query }));
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add default values for multiple missing values', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
let query = {};
|
||||||
|
render(setup({ onChange, query }));
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,8 @@ export const PromExploreQueryEditor: FC<Props> = (props: Props) => {
|
|||||||
onChange({ ...query, exemplar: true });
|
onChange({ ...query, exemplar: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.instant && !query.range) {
|
// Override query type to "Both" only for new queries (no query.expr).
|
||||||
|
if (!query.instant && !query.range && !query.expr) {
|
||||||
onChange({ ...query, instant: true, range: true });
|
onChange({ ...query, instant: true, range: true });
|
||||||
}
|
}
|
||||||
}, [onChange, query]);
|
}, [onChange, query]);
|
||||||
@ -35,6 +36,7 @@ export const PromExploreQueryEditor: FC<Props> = (props: Props) => {
|
|||||||
onBlur={() => {}}
|
onBlur={() => {}}
|
||||||
history={history}
|
history={history}
|
||||||
data={data}
|
data={data}
|
||||||
|
data-testid={testIds.editor}
|
||||||
ExtraFieldElement={
|
ExtraFieldElement={
|
||||||
<PromExploreExtraField query={query} onChange={onChange} datasource={datasource} onRunQuery={onRunQuery} />
|
<PromExploreExtraField query={query} onChange={onChange} datasource={datasource} onRunQuery={onRunQuery} />
|
||||||
}
|
}
|
||||||
@ -43,3 +45,7 @@ export const PromExploreQueryEditor: FC<Props> = (props: Props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default memo(PromExploreQueryEditor);
|
export default memo(PromExploreQueryEditor);
|
||||||
|
|
||||||
|
export const testIds = {
|
||||||
|
editor: 'prom-editor-explore',
|
||||||
|
};
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`PromExploreQueryEditor should render component 1`] = `
|
|
||||||
<PromQueryField
|
|
||||||
ExtraFieldElement={
|
|
||||||
<Memo
|
|
||||||
datasource={
|
|
||||||
Object {
|
|
||||||
"languageProvider": Object {
|
|
||||||
"getLabelKeys": [Function],
|
|
||||||
"metrics": Array [],
|
|
||||||
"syntax": [Function],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onChange={[MockFunction]}
|
|
||||||
onRunQuery={[MockFunction]}
|
|
||||||
query={
|
|
||||||
Object {
|
|
||||||
"expr": "",
|
|
||||||
"interval": "1s",
|
|
||||||
"refId": "A",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
app="explore"
|
|
||||||
data={
|
|
||||||
Object {
|
|
||||||
"request": Object {
|
|
||||||
"app": "Grafana",
|
|
||||||
"dashboardId": 1,
|
|
||||||
"interval": "1s",
|
|
||||||
"intervalMs": 1000,
|
|
||||||
"panelId": 1,
|
|
||||||
"range": Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"raw": Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
},
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
},
|
|
||||||
"requestId": "1",
|
|
||||||
"scopedVars": Object {},
|
|
||||||
"startTime": 0,
|
|
||||||
"targets": Array [],
|
|
||||||
"timezone": "GMT",
|
|
||||||
},
|
|
||||||
"series": Array [],
|
|
||||||
"state": "NotStarted",
|
|
||||||
"timeRange": Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"raw": Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
},
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
datasource={
|
|
||||||
Object {
|
|
||||||
"languageProvider": Object {
|
|
||||||
"getLabelKeys": [Function],
|
|
||||||
"metrics": Array [],
|
|
||||||
"syntax": [Function],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
history={Array []}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onChange={[MockFunction]}
|
|
||||||
onRunQuery={[MockFunction]}
|
|
||||||
query={
|
|
||||||
Object {
|
|
||||||
"expr": "",
|
|
||||||
"interval": "1s",
|
|
||||||
"refId": "A",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
range={
|
|
||||||
Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"raw": Object {
|
|
||||||
"from": "2020-01-01T00:00:00.000Z",
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
},
|
|
||||||
"to": "2020-01-02T00:00:00.000Z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
`;
|
|
Loading…
Reference in New Issue
Block a user