diff --git a/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.test.tsx new file mode 100644 index 00000000000..d1b2f3fb4b7 --- /dev/null +++ b/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.test.tsx @@ -0,0 +1,89 @@ +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { LokiDatasource } from '../../datasource'; +import { createLokiDatasource } from '../../mocks'; +import { LokiVisualQuery, LokiVisualQueryBinary } from '../types'; + +import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained'; +import { NestedQueryList, Props as NestedQueryListProps } from './NestedQueryList'; + +const X_BUTTON_LABEL = 'Remove nested query'; +function createMockProps(nestedQueriesCount = 1, showExplain = false): NestedQueryListProps { + const operators: string[] = ['+', '-', '*', '/']; + const nestedQueries: LokiVisualQueryBinary[] = [...Array(nestedQueriesCount).keys()].map((i) => ({ + operator: operators[i % operators.length], + query: { + labels: [], + operations: [], + }, + })); + + const query: LokiVisualQuery = { + labels: [], + operations: [], + binaryQueries: nestedQueries, + }; + const datasource: LokiDatasource = createLokiDatasource(); + + const props: NestedQueryListProps = { + query: query, + datasource: datasource, + showExplain: showExplain, + onChange: jest.fn(), + onRunQuery: jest.fn(), + }; + + return props; +} + +describe('render nested queries', () => { + it.each([1, 3])('%i nested queries can be rendered', async (queriesCount) => { + const props = createMockProps(queriesCount, false); + render(); + + const nestedQueryCloseButtons = await screen.findAllByLabelText(X_BUTTON_LABEL); + expect(nestedQueryCloseButtons).toHaveLength(queriesCount); + }); + + it('shows explanations for all nested queries', async () => { + const props = createMockProps(3, true); + render(); + + const nestedQueryCloseButtons = await screen.findAllByText(EXPLAIN_LABEL_FILTER_CONTENT); + expect(nestedQueryCloseButtons).toHaveLength(3); + }); +}); + +describe('events from nested queries', () => { + it('onChange is called when user removes one', async () => { + const props: NestedQueryListProps = createMockProps(3, false); + render(); + + const xButton: HTMLElement[] = await screen.findAllByLabelText(X_BUTTON_LABEL); + await userEvent.click(xButton[0]); + + const removedQuery: LokiVisualQueryBinary[] = [props.query.binaryQueries![0]]; + await waitFor(() => { + expect(props.onChange).toHaveBeenCalledWith({ + ...props.query, + binaryQueries: expect.not.arrayContaining(removedQuery), + }); + }); + }); + + it('onChange is called from sub-query', async () => { + const props = createMockProps(4, false); + const subQuery = { ...props.query.binaryQueries![3] }; + props.query.binaryQueries![0].query.binaryQueries = [subQuery]; + render(); + + const xButton: HTMLElement[] = await screen.findAllByLabelText(X_BUTTON_LABEL); + await userEvent.click(xButton[1]); + + await waitFor(async () => { + expect(props.onChange).toHaveBeenCalledTimes(1); + }); + }); +});