grafana/packages/grafana-prometheus/src/components/PromQueryField.test.tsx

184 lines
5.5 KiB
TypeScript
Raw Normal View History

Prometheus: Create Prometheus library (#81641) * Move to the library * copy from library * move them in src * have additional files * add unmigrated/dulicated code and files * migrate from brendan's pr module.ts, query_hints.ts, tracking.ts, and remove plugin.json * migrate from brendan's pr metric_find_query.test.ts * migrate from brendan's pr language_utils.test.ts * migrate from brendan's pr index.ts in root and in configuration * migrate from brendan's pr datasource.test.ts * migrate from brendan's pr typings folder * migrate from brendan's pr querycache folder * migrate from brendan's pr monaco-query-field folder * migrate from brendan's pr components folder without monaco-query-field folder * migrate from brendan's pr configuration/overhaul folder * migrate from brendan's pr AlertingSettingsOverhaul.tsx * Remove azure related code * migrate from brendan's pr ConfigEditor.tsx, DataSourceHttpSettingsOverhaul.tsx, ExemplarSetting.tsx, configuration/mocks.ts, PromSettings.test.tsx, PromSettings.tsx * migrate from brendan's pr useFlag.ts * migrate from brendan's pr metrics-modal folder * migrate from brendan's pr files inside components folder * migrate from brendan's pr LabelFilters* files because they are now under components folder * migrate from brendan's pr files under querybuilder/shared folder * migrate from brendan's pr aggregations.ts, QueryPattern.tsx, QueryPatternsModal.tsx, state.ts, testUtils.ts under querybuilder folder * Apply Ivana's PR https://github.com/grafana/grafana/pull/81656 * Apply jack's suggestions in this PR https://github.com/grafana/grafana/pull/77762 * Apply Ivana's PR https://github.com/grafana/grafana/pull/81656 * Fix type import * add monaco-promql to transformIgnorePatterns to run prometheus frontend library tests * remove Loki specific tests because we removed Loki code to decouple Loki * add prometheus specific references * We are moving these betterer issues from core Prometheus to the Library and we promise to remove all issues in the future, thank you * include prometheus library in package.json * add yarn lock with prometheus frontend library * decouple final core import from metric_find_query.test.ts * run prettier * fix core imports in promqail * fix lint errors * run prettier * add grafana-ui to devdeps to fix lint errors * update yarn.lock * grafana-ui fix * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * try to pass typecheck --------- Co-authored-by: Brendan O'Handley <brendan.ohandley@grafana.com>
2024-02-02 22:30:14 +08:00
import { getByTestId, render, screen, waitFor } from '@testing-library/react';
// @ts-ignore
import userEvent from '@testing-library/user-event';
import React from 'react';
import { CoreApp, DataFrame, LoadingState, PanelData } from '@grafana/data';
import { PrometheusDatasource } from '../datasource';
import PromQlLanguageProvider from '../language_provider';
Prometheus: Library fixes for using in external vendor DS (#82115) * fix stateSlice type errors for build, do not export stateSlice in the future * fix exports for consistency * fix package.json for rollup, update licence, keep private * rollup as devdependencies * try a different version of @testing-library/dom to try to fix the aria-query issue in drone * remove testUtils export * change @testing-library/dom version back * remove icon bundling, grafana-ui handles this * remove unused dependencies * components folder: avoid nested barrel files and use named exports * configuration folder: avoid nested barrel files and use named exports * querybuilder folder: avoid nested barrel files and use named exports * general files: use named exports * fix loader issue with promql for external ds * default to support labels match api * export things necessary for custom config auth * remove changes to core datasource.test.ts * Update packages/grafana-prometheus/package.json Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com> * remove icons script, not needed * update readme, remove references to grafana/ui * remove private property * check tests * remove private property in package.json * update changelog * update npm drone script for file checks * debug why updating test in script broke another library that had never been tested before * fix npm test for checking licenses * fix npm test for checking licenses * fix npm test for checking licenses * fix npm test for checking licenses * update license file for npm drone test * fix bash script --------- Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
2024-02-17 02:55:39 +08:00
import { PromQueryField } from './PromQueryField';
Prometheus: Create Prometheus library (#81641) * Move to the library * copy from library * move them in src * have additional files * add unmigrated/dulicated code and files * migrate from brendan's pr module.ts, query_hints.ts, tracking.ts, and remove plugin.json * migrate from brendan's pr metric_find_query.test.ts * migrate from brendan's pr language_utils.test.ts * migrate from brendan's pr index.ts in root and in configuration * migrate from brendan's pr datasource.test.ts * migrate from brendan's pr typings folder * migrate from brendan's pr querycache folder * migrate from brendan's pr monaco-query-field folder * migrate from brendan's pr components folder without monaco-query-field folder * migrate from brendan's pr configuration/overhaul folder * migrate from brendan's pr AlertingSettingsOverhaul.tsx * Remove azure related code * migrate from brendan's pr ConfigEditor.tsx, DataSourceHttpSettingsOverhaul.tsx, ExemplarSetting.tsx, configuration/mocks.ts, PromSettings.test.tsx, PromSettings.tsx * migrate from brendan's pr useFlag.ts * migrate from brendan's pr metrics-modal folder * migrate from brendan's pr files inside components folder * migrate from brendan's pr LabelFilters* files because they are now under components folder * migrate from brendan's pr files under querybuilder/shared folder * migrate from brendan's pr aggregations.ts, QueryPattern.tsx, QueryPatternsModal.tsx, state.ts, testUtils.ts under querybuilder folder * Apply Ivana's PR https://github.com/grafana/grafana/pull/81656 * Apply jack's suggestions in this PR https://github.com/grafana/grafana/pull/77762 * Apply Ivana's PR https://github.com/grafana/grafana/pull/81656 * Fix type import * add monaco-promql to transformIgnorePatterns to run prometheus frontend library tests * remove Loki specific tests because we removed Loki code to decouple Loki * add prometheus specific references * We are moving these betterer issues from core Prometheus to the Library and we promise to remove all issues in the future, thank you * include prometheus library in package.json * add yarn lock with prometheus frontend library * decouple final core import from metric_find_query.test.ts * run prettier * fix core imports in promqail * fix lint errors * run prettier * add grafana-ui to devdeps to fix lint errors * update yarn.lock * grafana-ui fix * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * trying to fix grafana-ui type errors with lerna drone check * try to pass typecheck --------- Co-authored-by: Brendan O'Handley <brendan.ohandley@grafana.com>
2024-02-02 22:30:14 +08:00
import { Props } from './monaco-query-field/MonacoQueryFieldProps';
// the monaco-based editor uses lazy-loading and that does not work
// well with this test, and we do not need the monaco-related
// functionality in this test anyway, so we mock it out.
jest.mock('./monaco-query-field/MonacoQueryFieldLazy', () => {
const fakeQueryField = (props: Props) => {
return <input onBlur={(e) => props.onBlur(e.currentTarget.value)} data-testid={'dummy-code-input'} type={'text'} />;
};
return {
MonacoQueryFieldLazy: fakeQueryField,
};
});
const defaultProps = {
datasource: {
languageProvider: {
start: () => Promise.resolve([]),
syntax: () => {},
getLabelKeys: () => [],
metrics: [],
},
getInitHints: () => [],
} as unknown as PrometheusDatasource,
query: {
expr: '',
refId: '',
},
onRunQuery: () => {},
onChange: () => {},
history: [],
};
describe('PromQueryField', () => {
beforeAll(() => {
// @ts-ignore
window.getSelection = () => {};
});
it('renders metrics chooser regularly if lookups are not disabled in the datasource settings', async () => {
const queryField = render(<PromQueryField {...defaultProps} />);
// wait for component to render
await screen.findByRole('button');
expect(queryField.getAllByRole('button')).toHaveLength(1);
});
it('renders a disabled metrics chooser if lookups are disabled in datasource settings', async () => {
const props = defaultProps;
props.datasource.lookupsDisabled = true;
const queryField = render(<PromQueryField {...props} />);
// wait for component to render
await screen.findByRole('button');
const bcButton = queryField.getByRole('button');
expect(bcButton).toBeDisabled();
});
it('renders an initial hint if no data and initial hint provided', async () => {
const props = defaultProps;
props.datasource.lookupsDisabled = true;
props.datasource.getInitHints = () => [{ label: 'Initial hint', type: 'INFO' }];
render(<PromQueryField {...props} />);
// wait for component to render
await screen.findByRole('button');
expect(screen.getByText('Initial hint')).toBeInTheDocument();
});
it('renders query hint if data, query hint and initial hint provided', async () => {
const props = defaultProps;
props.datasource.lookupsDisabled = true;
props.datasource.getInitHints = () => [{ label: 'Initial hint', type: 'INFO' }];
props.datasource.getQueryHints = () => [{ label: 'Query hint', type: 'INFO' }];
render(
<PromQueryField
{...props}
data={
{
series: [{ name: 'test name' }] as DataFrame[],
state: LoadingState.Done,
} as PanelData
}
/>
);
// wait for component to render
await screen.findByRole('button');
expect(screen.getByText('Query hint')).toBeInTheDocument();
expect(screen.queryByText('Initial hint')).not.toBeInTheDocument();
});
it('refreshes metrics when the data source changes', async () => {
const defaultProps = {
query: { expr: '', refId: '' },
onRunQuery: () => {},
onChange: () => {},
history: [],
};
const metrics = ['foo', 'bar'];
const queryField = render(
<PromQueryField
datasource={
{
languageProvider: makeLanguageProvider({ metrics: [metrics] }),
getInitHints: () => [],
} as unknown as PrometheusDatasource
}
{...defaultProps}
/>
);
// wait for component to render
await screen.findByRole('button');
const changedMetrics = ['baz', 'moo'];
queryField.rerender(
<PromQueryField
// @ts-ignore
datasource={{
languageProvider: makeLanguageProvider({ metrics: [changedMetrics] }),
}}
{...defaultProps}
/>
);
// If we check the label browser right away it should be in loading state
let labelBrowser = screen.getByRole('button');
expect(labelBrowser).toHaveTextContent('Loading');
// wait for component to rerender
labelBrowser = await screen.findByRole('button');
await waitFor(() => {
expect(labelBrowser).toHaveTextContent('Metrics browser');
});
});
it('should not run query onBlur', async () => {
const onRunQuery = jest.fn();
const { container } = render(<PromQueryField {...defaultProps} app={CoreApp.Explore} onRunQuery={onRunQuery} />);
// wait for component to rerender
await screen.findByRole('button');
const input = getByTestId(container, 'dummy-code-input');
expect(input).toBeInTheDocument();
await userEvent.type(input, 'metric');
// blur element
await userEvent.click(document.body);
expect(onRunQuery).not.toHaveBeenCalled();
});
});
function makeLanguageProvider(options: { metrics: string[][] }) {
const metricsStack = [...options.metrics];
return {
histogramMetrics: [],
metrics: [],
metricsMetadata: {},
lookupsDisabled: false,
getLabelKeys: () => [],
start() {
this.metrics = metricsStack.shift();
return Promise.resolve([]);
},
} as any as PromQlLanguageProvider;
}