import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DataSourceApi } from '@grafana/data'; import { Props, QueryVariableEditorUnConnected } from './QueryVariableEditor'; import { initialQueryVariableModelState } from './reducer'; import { initialVariableEditorState } from '../editor/reducer'; import { describe, expect } from '../../../../test/lib/common'; import { NEW_VARIABLE_ID } from '../state/types'; import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor'; import { setDataSourceSrv } from '@grafana/runtime'; const setupTestContext = (options: Partial) => { const defaults: Props = { variable: { ...initialQueryVariableModelState }, initQueryVariableEditor: jest.fn(), changeQueryVariableDataSource: jest.fn(), changeQueryVariableQuery: jest.fn(), changeVariableMultiValue: jest.fn(), editor: { ...initialVariableEditorState, extended: { VariableQueryEditor: LegacyVariableQueryEditor, dataSource: ({} as unknown) as DataSourceApi, }, }, onPropChange: jest.fn(), }; const props: Props & Record = { ...defaults, ...options }; const { rerender } = render(); return { rerender, props }; }; setDataSourceSrv({ getInstanceSettings: () => null, getList: () => [], } as any); describe('QueryVariableEditor', () => { describe('when the component is mounted', () => { it('then it should call initQueryVariableEditor', () => { const { props } = setupTestContext({}); expect(props.initQueryVariableEditor).toHaveBeenCalledTimes(1); expect(props.initQueryVariableEditor).toHaveBeenCalledWith({ type: 'query', id: NEW_VARIABLE_ID }); }); }); describe('when the user changes', () => { it.each` fieldName | propName | expectedArgs ${'query'} | ${'changeQueryVariableQuery'} | ${[{ type: 'query', id: NEW_VARIABLE_ID }, 't', 't']} ${'regex'} | ${'onPropChange'} | ${{ propName: 'regex', propValue: 't', updateOptions: true }} `( '$fieldName field and tabs away then $propName should be called with correct args', ({ fieldName, propName, expectedArgs }) => { const { props } = setupTestContext({}); const propUnderTest = props[propName]; const fieldAccessor = fieldAccessors[fieldName]; userEvent.type(fieldAccessor(), 't'); userEvent.tab(); expect(propUnderTest).toHaveBeenCalledTimes(1); expect(propUnderTest).toHaveBeenCalledWith(...expectedArgs); } ); }); describe('when the user changes', () => { it.each` fieldName | propName ${'query'} | ${'changeQueryVariableQuery'} ${'regex'} | ${'onPropChange'} `( '$fieldName field but reverts the change and tabs away then $propName should not be called', ({ fieldName, propName }) => { const { props } = setupTestContext({}); const propUnderTest = props[propName]; const fieldAccessor = fieldAccessors[fieldName]; userEvent.type(fieldAccessor(), 't'); userEvent.type(fieldAccessor(), '{backspace}'); userEvent.tab(); expect(propUnderTest).not.toHaveBeenCalled(); } ); }); }); const getQueryField = () => screen.getByRole('textbox', { name: /variable editor form default variable query editor textarea/i }); const getRegExField = () => screen.getByRole('textbox', { name: /variable editor form query regex field/i }); const fieldAccessors: Record HTMLElement> = { query: getQueryField, regex: getRegExField, };