From 3b487c2661175f7cecab5dd10255978d76a82166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 3 Mar 2022 14:30:17 +0100 Subject: [PATCH] Loki: Initial loki builder tests (#46076) --- .../LokiQueryEditorSelector.test.tsx | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx new file mode 100644 index 00000000000..2c34d60768c --- /dev/null +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx @@ -0,0 +1,188 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { LokiDatasource } from '../../datasource'; +import { cloneDeep, defaultsDeep } from 'lodash'; +import { LokiQuery } from '../../types'; +import { LokiQueryEditorSelector } from './LokiQueryEditorSelector'; +import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; + +const defaultQuery = { + refId: 'A', + expr: '{label1="foo", label2="bar"}', +}; + +const datasource = new LokiDatasource( + { + id: 1, + uid: '', + type: 'loki', + name: 'loki-test', + access: 'proxy', + url: '', + jsonData: {}, + meta: {} as any, + }, + undefined, + undefined +); + +datasource.languageProvider.fetchLabels = jest.fn().mockResolvedValue([]); + +const defaultProps = { + datasource, + query: defaultQuery, + onRunQuery: () => {}, + onChange: () => {}, +}; + +describe('LokiQueryEditorSelector', () => { + it('shows code editor if expr and nothing else', async () => { + // We opt for showing code editor for queries created before this feature was added + render(); + expectCodeEditor(); + }); + + it('shows builder if new query', async () => { + render( + + ); + expectBuilder(); + }); + + it('shows code editor when code mode is set', async () => { + renderWithMode(QueryEditorMode.Code); + expectCodeEditor(); + }); + + it('shows builder when builder mode is set', async () => { + renderWithMode(QueryEditorMode.Builder); + expectBuilder(); + }); + + it('shows explain when explain mode is set', async () => { + renderWithMode(QueryEditorMode.Explain); + expectExplain(); + }); + + it('changes to builder mode', async () => { + const { onChange } = renderWithMode(QueryEditorMode.Code); + switchToMode(QueryEditorMode.Builder); + expect(onChange).toBeCalledWith({ + refId: 'A', + expr: defaultQuery.expr, + editorMode: QueryEditorMode.Builder, + }); + }); + + // it('Can enable preview', async () => { + // const { onChange } = renderWithMode(QueryEditorMode.Builder); + // expect(screen.queryByLabelText('selector')).not.toBeInTheDocument(); + + // screen.getByLabelText('Preview').click(); + + // expect(onChange).toBeCalledWith({ + // refId: 'A', + // expr: defaultQuery.expr, + // range: true, + // editorMode: QueryEditorMode.Builder, + // editorPreview: true, + // }); + // }); + + // it('Should show preview', async () => { + // renderWithProps({ + // editorPreview: true, + // editorMode: QueryEditorMode.Builder, + // expr: 'my_metric', + // }); + // expect(screen.getByLabelText('selector').textContent).toBe('my_metric'); + // }); + + it('changes to code mode', async () => { + const { onChange } = renderWithMode(QueryEditorMode.Builder); + switchToMode(QueryEditorMode.Code); + expect(onChange).toBeCalledWith({ + refId: 'A', + expr: defaultQuery.expr, + editorMode: QueryEditorMode.Code, + }); + }); + + it('changes to explain mode', async () => { + const { onChange } = renderWithMode(QueryEditorMode.Code); + switchToMode(QueryEditorMode.Explain); + expect(onChange).toBeCalledWith({ + refId: 'A', + expr: defaultQuery.expr, + editorMode: QueryEditorMode.Explain, + }); + }); + + // it('parses query when changing to builder mode', async () => { + // const { rerender } = renderWithProps({ + // refId: 'A', + // expr: 'rate(test_metric{instance="host.docker.internal:3000"}[$__interval])', + // editorMode: QueryEditorMode.Code, + // }); + // switchToMode(QueryEditorMode.Builder); + // rerender( + // + // ); + + // await screen.findByText('test_metric'); + // expect(screen.getByText('host.docker.internal:3000')).toBeInTheDocument(); + // expect(screen.getByText('Rate')).toBeInTheDocument(); + // expect(screen.getByText('$__interval')).toBeInTheDocument(); + // }); +}); + +function renderWithMode(mode: QueryEditorMode) { + return renderWithProps({ editorMode: mode } as any); +} + +function renderWithProps(overrides?: Partial) { + const query = defaultsDeep(overrides ?? {}, cloneDeep(defaultQuery)); + const onChange = jest.fn(); + + const stuff = render(); + return { onChange, ...stuff }; +} + +function expectCodeEditor() { + // Log browser shows this until log labels are loaded. + expect(screen.getByText('Loading labels...')).toBeInTheDocument(); +} + +function expectBuilder() { + expect(screen.getByText('Labels')).toBeInTheDocument(); +} + +function expectExplain() { + // Base message when there is no query + expect(screen.getByText(/Fetch all log/)).toBeInTheDocument(); +} + +function switchToMode(mode: QueryEditorMode) { + const label = { + [QueryEditorMode.Code]: 'Code', + [QueryEditorMode.Explain]: 'Explain', + [QueryEditorMode.Builder]: 'Builder', + }[mode]; + + const switchEl = screen.getByLabelText(label); + userEvent.click(switchEl); +}