import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
import { PrometheusDatasource } from '../datasource';
import { PromVariableQuery, PromVariableQueryType, StandardPromVariableQuery } from '../types';
import { PromVariableQueryEditor, Props, variableMigration } from './VariableQueryEditor';
const refId = 'PrometheusVariableQueryEditor-VariableQuery';
describe('PromVariableQueryEditor', () => {
let props: Props;
test('Migrates from standard variable support to custom variable query', () => {
const query: StandardPromVariableQuery = {
query: 'label_names()',
refId: 'StandardVariableQuery',
};
const migration: PromVariableQuery = variableMigration(query);
const expected: PromVariableQuery = {
qryType: PromVariableQueryType.LabelNames,
refId: 'PrometheusDatasource-VariableQuery',
};
expect(migration).toEqual(expected);
});
test('Migrates from jsonnet grafana as code variable to custom variable query', () => {
const query = 'label_names()';
const migration: PromVariableQuery = variableMigration(query);
const expected: PromVariableQuery = {
qryType: PromVariableQueryType.LabelNames,
refId: 'PrometheusDatasource-VariableQuery',
};
expect(migration).toEqual(expected);
});
beforeEach(() => {
props = {
datasource: {
hasLabelsMatchAPISupport: () => 1,
languageProvider: {
start: () => Promise.resolve([]),
syntax: () => {},
getLabelKeys: () => [],
metrics: [],
},
getInitHints: () => [],
} as unknown as PrometheusDatasource,
query: {
refId: 'test',
query: 'label_names()',
},
onRunQuery: () => {},
onChange: () => {},
history: [],
};
});
test('Displays a group of function options', async () => {
render();
const select = screen.getByLabelText('Query type').parentElement!;
await userEvent.click(select);
await waitFor(() => expect(screen.getAllByText('Label names')).toHaveLength(2));
await waitFor(() => expect(screen.getByText('Label values')).toBeInTheDocument());
await waitFor(() => expect(screen.getByText('Metrics')).toBeInTheDocument());
await waitFor(() => expect(screen.getByText('Query result')).toBeInTheDocument());
await waitFor(() => expect(screen.getByText('Series query')).toBeInTheDocument());
});
test('Calls onChange for label_names() query', async () => {
const onChange = jest.fn();
props.query = {
refId: 'test',
query: '',
};
render();
await selectOptionInTest(screen.getByLabelText('Query type'), 'Label names');
expect(onChange).toHaveBeenCalledWith({
query: 'label_names()',
refId,
});
});
test('Does not call onChange for other queries', async () => {
const onChange = jest.fn();
render();
await selectOptionInTest(screen.getByLabelText('Query type'), 'Metrics');
await selectOptionInTest(screen.getByLabelText('Query type'), 'Query result');
await selectOptionInTest(screen.getByLabelText('Query type'), 'Series query');
expect(onChange).not.toHaveBeenCalled();
});
test('Calls onChange for metrics() with argument onBlur', async () => {
const onChange = jest.fn();
props.query = {
refId: 'test',
query: 'metrics(a)',
};
render();
const labelSelect = screen.getByLabelText('Metric selector');
await userEvent.click(labelSelect);
const functionSelect = screen.getByLabelText('Query type').parentElement!;
await userEvent.click(functionSelect);
expect(onChange).toHaveBeenCalledWith({
query: 'metrics(a)',
refId,
});
});
test('Calls onChange for query_result() with argument onBlur', async () => {
const onChange = jest.fn();
props.query = {
refId: 'test',
query: 'query_result(a)',
};
render();
const labelSelect = screen.getByLabelText('Prometheus Query');
await userEvent.click(labelSelect);
const functionSelect = screen.getByLabelText('Query type').parentElement!;
await userEvent.click(functionSelect);
expect(onChange).toHaveBeenCalledWith({
query: 'query_result(a)',
refId,
});
});
test('Calls onChange for Match[] series with argument onBlur', async () => {
const onChange = jest.fn();
props.query = {
refId: 'test',
query: '{a: "example"}',
};
render();
const labelSelect = screen.getByLabelText('Series Query');
await userEvent.click(labelSelect);
const functionSelect = screen.getByLabelText('Query type').parentElement!;
await userEvent.click(functionSelect);
expect(onChange).toHaveBeenCalledWith({
query: '{a: "example"}',
refId,
});
});
});