mirror of
https://github.com/grafana/grafana.git
synced 2026-08-26 13:27:30 -05:00
* perf: limit metric names in Code Mode suggestions * feat: configurable metric names limit * feat: code mode autocomplete info/disclaimer * chore: put new functionality behind new feature toggle * refactor: avoid type assertions * refactor: avoid explicit `any` refactor: type guards * refactor: type guards * chore: add testdata results * fix: add missing feature toggle guard * perf: prefer array access to `Array.prototype.at` * test: add missing config override * test: refactor for brevity & clarity * perf: avoid unnecessary mapping * chore: undo testdata changes * fix: use correct limit; perf optimizations * refactor: avoid unnecessary `async`s * types: simplify * test: add missing tests * fix: avoid hardcoding * test: update mock path * docs: fix typo style: remove formatting artifact style: remove formatting artifact style: remove formatting artifact * fix: event scope regression * style: refactor for clarity * refactor: prefer `useCallback` to in-effect handler * refactor: simplify & broaden `filter` * refactor: rename file to keep with conventions * chore: mirror Prometheus package changes in app * refactor: prefer no `@ts-ignore` * chore: update betterer results * docs: use type in TSDoc `@link` without `@ts-ignore` * test: add missing provider * test: fix jest mock path * fix: display disclaimer in empty input case
143 lines
4.9 KiB
TypeScript
143 lines
4.9 KiB
TypeScript
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import React, { SyntheticEvent } from 'react';
|
|
import { Provider } from 'react-redux';
|
|
|
|
import { SelectableValue } from '@grafana/data';
|
|
import { selectors } from '@grafana/e2e-selectors';
|
|
import { config } from '@grafana/runtime';
|
|
|
|
import { configureStore } from '../../../../store/configureStore';
|
|
|
|
import { countError, getValueFromEventItem, PromSettings } from './PromSettings';
|
|
import { createDefaultConfigOptions } from './mocks';
|
|
|
|
beforeEach(() => {
|
|
jest.replaceProperty(config, 'featureToggles', {
|
|
prometheusCodeModeMetricNamesSearch: true,
|
|
});
|
|
});
|
|
|
|
describe('PromSettings', () => {
|
|
describe('getValueFromEventItem', () => {
|
|
describe('when called with undefined', () => {
|
|
it('then it should return empty string', () => {
|
|
const result = getValueFromEventItem(
|
|
undefined as unknown as SyntheticEvent<HTMLInputElement> | SelectableValue<string>
|
|
);
|
|
expect(result).toEqual('');
|
|
});
|
|
});
|
|
|
|
describe('when called with an input event', () => {
|
|
it('then it should return value from currentTarget', () => {
|
|
const value = 'An input value';
|
|
const result = getValueFromEventItem({ currentTarget: { value } });
|
|
expect(result).toEqual(value);
|
|
});
|
|
});
|
|
|
|
describe('when called with a select event', () => {
|
|
it('then it should return value', () => {
|
|
const value = 'A select value';
|
|
const result = getValueFromEventItem({ value });
|
|
expect(result).toEqual(value);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('PromSettings component', () => {
|
|
const defaultProps = createDefaultConfigOptions();
|
|
|
|
it('should show POST httpMethod if no httpMethod', () => {
|
|
const options = defaultProps;
|
|
options.url = '';
|
|
options.jsonData.httpMethod = '';
|
|
const store = configureStore();
|
|
|
|
render(
|
|
<Provider store={store}>
|
|
<PromSettings onOptionsChange={() => {}} options={options} />
|
|
</Provider>
|
|
);
|
|
expect(screen.getByText('POST')).toBeInTheDocument();
|
|
});
|
|
it('should show POST httpMethod if POST httpMethod is configured', () => {
|
|
const options = defaultProps;
|
|
options.url = 'test_url';
|
|
options.jsonData.httpMethod = 'POST';
|
|
const store = configureStore();
|
|
|
|
render(
|
|
<Provider store={store}>
|
|
<PromSettings onOptionsChange={() => {}} options={options} />
|
|
</Provider>
|
|
);
|
|
expect(screen.getByText('POST')).toBeInTheDocument();
|
|
});
|
|
it('should show GET httpMethod if GET httpMethod is configured', () => {
|
|
const options = defaultProps;
|
|
options.url = 'test_url';
|
|
options.jsonData.httpMethod = 'GET';
|
|
const store = configureStore();
|
|
|
|
render(
|
|
<Provider store={store}>
|
|
<PromSettings onOptionsChange={() => {}} options={options} />
|
|
</Provider>
|
|
);
|
|
expect(screen.getByText('GET')).toBeInTheDocument();
|
|
});
|
|
it('should show a valid metric name count if codeModeMetricNamesSuggestionLimit is configured correctly', () => {
|
|
const options = defaultProps;
|
|
const store = configureStore();
|
|
|
|
const { getByTestId, queryByText } = render(
|
|
<Provider store={store}>
|
|
<PromSettings onOptionsChange={() => {}} options={options} />
|
|
</Provider>
|
|
);
|
|
const input = getByTestId(
|
|
selectors.components.DataSource.Prometheus.configPage.codeModeMetricNamesSuggestionLimit
|
|
);
|
|
|
|
// Non-negative integer
|
|
fireEvent.change(input, { target: { value: '3000' } });
|
|
fireEvent.blur(input);
|
|
expect(queryByText(countError)).not.toBeInTheDocument();
|
|
|
|
// Non-negative integer with scientific notation
|
|
fireEvent.change(input, { target: { value: '1e5' } });
|
|
fireEvent.blur(input);
|
|
expect(queryByText(countError)).not.toBeInTheDocument();
|
|
|
|
// Non-negative integer with decimal scientific notation
|
|
fireEvent.change(input, { target: { value: '1.4e4' } });
|
|
fireEvent.blur(input);
|
|
expect(queryByText(countError)).not.toBeInTheDocument();
|
|
});
|
|
it('should show the expected error when an invalid value is provided for codeModeMetricNamesSuggestionLimit', () => {
|
|
const options = defaultProps;
|
|
const store = configureStore();
|
|
|
|
const { getByTestId, queryByText } = render(
|
|
<Provider store={store}>
|
|
<PromSettings onOptionsChange={() => {}} options={options} />
|
|
</Provider>
|
|
);
|
|
const input = getByTestId(
|
|
selectors.components.DataSource.Prometheus.configPage.codeModeMetricNamesSuggestionLimit
|
|
);
|
|
|
|
// No negative values
|
|
fireEvent.change(input, { target: { value: '-50' } });
|
|
fireEvent.blur(input);
|
|
expect(queryByText(countError)).toBeInTheDocument();
|
|
|
|
// No negative values with scientific notation
|
|
fireEvent.change(input, { target: { value: '-5e5' } });
|
|
fireEvent.blur(input);
|
|
expect(queryByText(countError)).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|