diff --git a/.betterer.results b/.betterer.results index 567cc847348..b1d89314506 100644 --- a/.betterer.results +++ b/.betterer.results @@ -7562,10 +7562,6 @@ exports[`better eslint`] = { "public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx index 2079db28001..08cfd3bd16d 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx @@ -2,10 +2,13 @@ import { render, screen, getAllByRole, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; +import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data'; + import { LokiDatasource } from '../../datasource'; import { LokiOperationId, LokiVisualQuery } from '../types'; import { LokiQueryBuilder } from './LokiQueryBuilder'; +import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained'; const defaultQuery: LokiVisualQuery = { labels: [{ op: '=', label: 'baz', value: 'bar' }], @@ -17,8 +20,8 @@ const createDefaultProps = () => { { url: '', jsonData: {}, - meta: {} as any, - } as any, + meta: {} as DataSourcePluginMeta, + } as DataSourceInstanceSettings, undefined, undefined ); @@ -66,4 +69,30 @@ describe('LokiQueryBuilder', () => { ).not.toBeInTheDocument(); }); }); + it('shows explain section when showExplain is true', async () => { + const query = { + labels: [{ label: 'foo', op: '=', value: 'bar' }], + operations: [{ id: LokiOperationId.LineContains, params: ['error'] }], + }; + const props = createDefaultProps(); + props.showExplain = true; + props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); + + render(); + expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument(); + }); + + it('does not shows explain section when showExplain is false', async () => { + const query = { + labels: [{ label: 'foo', op: '=', value: 'bar' }], + operations: [{ id: LokiOperationId.LineContains, params: ['error'] }], + }; + const props = createDefaultProps(); + props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); + + render(); + await waitFor(() => { + expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument(); + }); + }); }); diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx index 634cd538c6e..5b04f7476e7 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx @@ -21,6 +21,7 @@ import { lokiQueryModeller } from '../LokiQueryModeller'; import { buildVisualQueryFromString } from '../parsing'; import { LokiOperationId, LokiVisualQuery } from '../types'; +import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained'; import { NestedQueryList } from './NestedQueryList'; export interface Props { @@ -119,7 +120,7 @@ export const LokiQueryBuilder = React.memo(({ datasource, query, onChange stepNumber={1} title={} > - Fetch all log lines matching label filters. + {EXPLAIN_LABEL_FILTER_CONTENT} )} diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx index d78caf86006..ab5ee6552be 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx @@ -10,6 +10,8 @@ import { lokiQueryModeller } from '../LokiQueryModeller'; import { buildVisualQueryFromString } from '../parsing'; import { LokiVisualQuery } from '../types'; +export const EXPLAIN_LABEL_FILTER_CONTENT = 'Fetch all log lines matching label filters.'; + export interface Props { query: string; } @@ -24,7 +26,7 @@ export const LokiQueryBuilderExplained = React.memo(({ query }) => { stepNumber={1} title={} > - Fetch all log lines matching label filters. + {EXPLAIN_LABEL_FILTER_CONTENT} stepNumber={2} diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx new file mode 100644 index 00000000000..1df52e41bf4 --- /dev/null +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx @@ -0,0 +1,53 @@ +import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data'; + +import { LokiDatasource } from '../../datasource'; +import { LokiQuery } from '../../types'; + +import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained'; +import { LokiQueryCodeEditor } from './LokiQueryCodeEditor'; + +const defaultQuery: LokiQuery = { + expr: '{job="bar}', + refId: 'A', +}; + +const createDefaultProps = () => { + const datasource = new LokiDatasource( + { + url: '', + jsonData: {}, + meta: {} as DataSourcePluginMeta, + } as DataSourceInstanceSettings, + undefined, + undefined + ); + + const props = { + datasource, + onRunQuery: () => {}, + onChange: () => {}, + showExplain: false, + }; + + return props; +}; + +describe('LokiQueryCodeEditor', () => { + it('shows explain section when showExplain is true', () => { + const props = createDefaultProps(); + props.showExplain = true; + props.datasource.metadataRequest = jest.fn().mockResolvedValue([]); + render(); + expect(screen.getByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument(); + }); + + it('does not shows explain section when showExplain is true', () => { + const props = createDefaultProps(); + props.datasource.metadataRequest = jest.fn().mockResolvedValue([]); + render(); + expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx index 21d28feaad7..b449576353d 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx @@ -8,6 +8,7 @@ import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/ import { LokiDatasource } from '../../datasource'; import { LokiQuery, LokiQueryType } from '../../types'; +import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained'; import { LokiQueryEditorSelector } from './LokiQueryEditorSelector'; jest.mock('@grafana/runtime', () => { @@ -117,6 +118,13 @@ describe('LokiQueryEditorSelector', () => { expect(selector.textContent).toBe('{job="grafana"}'); }); + it('Can enable explain', async () => { + renderWithMode(QueryEditorMode.Builder); + expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument(); + screen.getByLabelText('Explain').click(); + expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument(); + }); + it('changes to code mode', async () => { const { onChange } = renderWithMode(QueryEditorMode.Builder); await switchToMode(QueryEditorMode.Code);