D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
usr
/
share
/
grafana
/
public
/
app
/
plugins
/
datasource
/
prometheus
/
components
/
Filename :
PromQueryField.test.tsx
back
Copy
import { getByTestId, render, screen, waitFor } from '@testing-library/react'; // @ts-ignore import userEvent from '@testing-library/user-event'; import React from 'react'; import { PanelData, LoadingState, DataFrame, CoreApp } from '@grafana/data'; import { PrometheusDatasource } from '../datasource'; import PromQlLanguageProvider from '../language_provider'; import PromQueryField from './PromQueryField'; 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; }