import { getByTestId, render, screen } 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'; // 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: any) => { return ; }; 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', () => { const queryField = render(); expect(queryField.getAllByRole('button')).toHaveLength(1); }); it('renders a disabled metrics chooser if lookups are disabled in datasource settings', () => { const props = defaultProps; props.datasource.lookupsDisabled = true; const queryField = render(); const bcButton = queryField.getByRole('button'); expect(bcButton).toBeDisabled(); }); it('renders an initial hint if no data and initial hint provided', () => { const props = defaultProps; props.datasource.lookupsDisabled = true; props.datasource.getInitHints = () => [{ label: 'Initial hint', type: 'INFO' }]; render(); expect(screen.getByText('Initial hint')).toBeInTheDocument(); }); it('renders query hint if data, query hint and initial hint provided', () => { const props = defaultProps; props.datasource.lookupsDisabled = true; props.datasource.getInitHints = () => [{ label: 'Initial hint', type: 'INFO' }]; props.datasource.getQueryHints = () => [{ label: 'Query hint', type: 'INFO' }]; render( ); 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( [], } as unknown as PrometheusDatasource } {...defaultProps} /> ); const changedMetrics = ['baz', 'moo']; queryField.rerender( ); // If we check the label browser right away it should be in loading state let labelBrowser = screen.getByRole('button'); expect(labelBrowser.textContent).toContain('Loading'); }); it('should not run query onBlur in explore', async () => { const onRunQuery = jest.fn(); const { container } = render(); const input = getByTestId(container, 'dummy-code-input'); expect(input).toBeInTheDocument(); await userEvent.type(input, 'metric'); input.blur(); expect(onRunQuery).not.toHaveBeenCalled(); }); it('should run query onBlur in dashboard', async () => { const onRunQuery = jest.fn(); const { container } = render(); const input = getByTestId(container, 'dummy-code-input'); expect(input).toBeInTheDocument(); await userEvent.type(input, 'metric'); input.blur(); expect(onRunQuery).toHaveBeenCalled(); }); }); function makeLanguageProvider(options: { metrics: string[][] }) { const metricsStack = [...options.metrics]; return { histogramMetrics: [] as any, metrics: [], metricsMetadata: {}, lookupsDisabled: false, getLabelKeys: () => [], start() { this.metrics = metricsStack.shift(); return Promise.resolve([]); }, } as any as PromQlLanguageProvider; }