import { DataSourceInstanceSettings } from '@grafana/data'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { getRootReducer, RootReducerType } from '../state/helpers'; import { toVariableIdentifier, toVariablePayload } from '../state/types'; import { variableAdapters } from '../adapters'; import { createDataSourceVariableAdapter } from './adapter'; import { DataSourceVariableActionDependencies, initDataSourceVariableEditor, updateDataSourceVariableOptions, } from './actions'; import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; import { createDataSourceOptions } from './reducer'; import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; import { changeVariableEditorExtended } from '../editor/reducer'; import { datasourceBuilder } from '../shared/testing/builders'; import { getDataSourceInstanceSetting } from '../shared/testing/helpers'; interface Args { sources?: DataSourceInstanceSettings[]; query?: string; regex?: string; } function getTestContext({ sources = [], query, regex }: Args = {}) { const getListMock = jest.fn().mockReturnValue(sources); const getDatasourceSrvMock = jest.fn().mockReturnValue({ getList: getListMock }); const dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrvMock }; const datasource = datasourceBuilder().withId('0').withQuery(query).withRegEx(regex).build(); return { getListMock, getDatasourceSrvMock, dependencies, datasource }; } describe('data source actions', () => { variableAdapters.setInit(() => [createDataSourceVariableAdapter()]); describe('when updateDataSourceVariableOptions is dispatched', () => { describe('and there is no regex', () => { it('then the correct actions are dispatched', async () => { const meta = getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }); const sources: DataSourceInstanceSettings[] = [ getDataSourceInstanceSetting('first-name', meta), getDataSourceInstanceSetting('second-name', meta), ]; const { datasource, dependencies, getListMock, getDatasourceSrvMock } = getTestContext({ sources, query: 'mock-data-id', }); const tester = await reduxTester() .givenRootReducer(getRootReducer()) .whenActionIsDispatched( addVariable(toVariablePayload(datasource, { global: false, index: 0, model: datasource })) ) .whenAsyncActionIsDispatched( updateDataSourceVariableOptions(toVariableIdentifier(datasource), dependencies), true ); await tester.thenDispatchedActionsShouldEqual( createDataSourceOptions( toVariablePayload( { type: 'datasource', id: '0' }, { sources, regex: (undefined as unknown) as RegExp, } ) ), setCurrentVariableValue( toVariablePayload( { type: 'datasource', id: '0' }, { option: { text: 'first-name', value: 'first-name', selected: false } } ) ) ); expect(getListMock).toHaveBeenCalledTimes(1); expect(getListMock).toHaveBeenCalledWith({ metrics: true, variables: false }); expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); }); }); describe('and there is a regex', () => { it('then the correct actions are dispatched', async () => { const meta = getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }); const sources: DataSourceInstanceSettings[] = [ getDataSourceInstanceSetting('first-name', meta), getDataSourceInstanceSetting('second-name', meta), ]; const { datasource, dependencies, getListMock, getDatasourceSrvMock } = getTestContext({ sources, query: 'mock-data-id', regex: '/.*(second-name).*/', }); const tester = await reduxTester() .givenRootReducer(getRootReducer()) .whenActionIsDispatched( addVariable(toVariablePayload(datasource, { global: false, index: 0, model: datasource })) ) .whenAsyncActionIsDispatched( updateDataSourceVariableOptions(toVariableIdentifier(datasource), dependencies), true ); await tester.thenDispatchedActionsShouldEqual( createDataSourceOptions( toVariablePayload( { type: 'datasource', id: '0' }, { sources, regex: /.*(second-name).*/, } ) ), setCurrentVariableValue( toVariablePayload( { type: 'datasource', id: '0' }, { option: { text: 'second-name', value: 'second-name', selected: false } } ) ) ); expect(getListMock).toHaveBeenCalledTimes(1); expect(getListMock).toHaveBeenCalledWith({ metrics: true, variables: false }); expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); }); }); }); describe('when initDataSourceVariableEditor is dispatched', () => { it('then the correct actions are dispatched', async () => { const meta = getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }); const sources: DataSourceInstanceSettings[] = [ getDataSourceInstanceSetting('first-name', meta), getDataSourceInstanceSetting('second-name', meta), ]; const { dependencies, getListMock, getDatasourceSrvMock } = getTestContext({ sources }); await reduxTester() .givenRootReducer(getRootReducer()) .whenActionIsDispatched(initDataSourceVariableEditor(dependencies)) .thenDispatchedActionsShouldEqual( changeVariableEditorExtended({ propName: 'dataSourceTypes', propValue: [ { text: '', value: '' }, { text: 'mock-data-name', value: 'mock-data-id' }, ], }) ); expect(getListMock).toHaveBeenCalledTimes(1); expect(getListMock).toHaveBeenCalledWith({ metrics: true, variables: true }); expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); }); }); });