/usr/share/grafana/public/app/features/variables/state
import { DataSourceRef, LoadingState } from '@grafana/data'; import { setDataSourceSrv } from '@grafana/runtime'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { toAsyncOfResult } from '../../query/state/DashboardQueryRunner/testHelpers'; import { variableAdapters } from '../adapters'; import { createAdHocVariableAdapter } from '../adhoc/adapter'; import { createConstantVariableAdapter } from '../constant/adapter'; import { createDataSourceVariableAdapter } from '../datasource/adapter'; import { createDataSourceOptions } from '../datasource/reducer'; import { cleanEditorState } from '../editor/reducer'; import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; import { setVariableQueryRunner, VariableQueryRunner } from '../query/VariableQueryRunner'; import { createQueryVariableAdapter } from '../query/adapter'; import { adHocBuilder, constantBuilder, datasourceBuilder, queryBuilder } from '../shared/testing/builders'; import { TransactionStatus, VariableModel } from '../types'; import { toVariablePayload } from '../utils'; import { initVariablesTransaction } from './actions'; import { getPreloadedState, getRootReducer, RootReducerType } from './helpers'; import { toKeyedAction } from './keyedVariablesReducer'; import { addVariable, changeVariableProp, setCurrentVariableValue, variableStateCompleted, variableStateFetching, variableStateNotStarted, } from './sharedReducer'; import { initialTransactionState, variablesClearTransaction, variablesCompleteTransaction, variablesInitTransaction, } from './transactionReducer'; import { cleanVariables } from './variablesReducer'; variableAdapters.setInit(() => [ createQueryVariableAdapter(), createConstantVariableAdapter(), createAdHocVariableAdapter(), createDataSourceVariableAdapter(), ]); function getTestContext(variables?: VariableModel[]) { const key = 'key'; const constant = constantBuilder().withId('constant').withName('constant').build(); const templating = { list: variables ?? [constant] }; const getInstanceSettingsMock = jest.fn().mockReturnValue(undefined); setDataSourceSrv({ registerRuntimeDataSource: jest.fn(), get: jest.fn().mockResolvedValue({}), getList: jest.fn().mockReturnValue([]), getInstanceSettings: getInstanceSettingsMock, reload: jest.fn(), }); const variableQueryRunner = { cancelRequest: jest.fn(), queueRequest: jest.fn(), getResponse: () => toAsyncOfResult({ state: LoadingState.Done, identifier: { type: 'query', id: 'query' } }), destroy: jest.fn(), } as unknown as VariableQueryRunner; setVariableQueryRunner(variableQueryRunner); const dashboard = { title: 'Some dash', uid: key, templating } as DashboardModel; return { constant, getInstanceSettingsMock, templating, key, dashboard }; } describe('initVariablesTransaction', () => { describe('when called and the previous dashboard has completed', () => { it('then correct actions are dispatched', async () => { const { constant, key, dashboard } = getTestContext(); const tester = await reduxTester<RootReducerType>() .givenRootReducer(getRootReducer()) .whenAsyncActionIsDispatched(initVariablesTransaction(key, dashboard)); tester.thenDispatchedActionsPredicateShouldEqual((dispatchedActions) => { expect(dispatchedActions[0]).toEqual(toKeyedAction(key, variablesInitTransaction({ uid: key }))); expect(dispatchedActions[1].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[1].payload.action.payload.id).toEqual('__dashboard'); expect(dispatchedActions[2].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[2].payload.action.payload.id).toEqual('__org'); expect(dispatchedActions[3].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[3].payload.action.payload.id).toEqual('__user'); expect(dispatchedActions[4]).toEqual( toKeyedAction(key, addVariable(toVariablePayload(constant, { global: false, index: 0, model: constant }))) ); expect(dispatchedActions[5]).toEqual(toKeyedAction(key, variableStateNotStarted(toVariablePayload(constant)))); expect(dispatchedActions[6]).toEqual(toKeyedAction(key, variableStateCompleted(toVariablePayload(constant)))); expect(dispatchedActions[7]).toEqual(toKeyedAction(key, variablesCompleteTransaction({ uid: key }))); return dispatchedActions.length === 8; }); }); describe('and there are variables that have data source that need to be migrated', () => { it('then correct actions are dispatched', async () => { const legacyDs = '${ds}' as unknown as DataSourceRef; const ds = datasourceBuilder().withId('ds').withRootStateKey('key').withName('ds').withQuery('prom').build(); const query = queryBuilder() .withId('query') .withRootStateKey('key') .withName('query') .withDatasource(legacyDs) .build(); const adhoc = adHocBuilder() .withId('adhoc') .withRootStateKey('key') .withName('adhoc') .withDatasource(legacyDs) .build(); const { key, dashboard } = getTestContext([ds, query, adhoc]); const tester = await reduxTester<RootReducerType>() .givenRootReducer(getRootReducer()) .whenAsyncActionIsDispatched(initVariablesTransaction(key, dashboard)); tester.thenDispatchedActionsPredicateShouldEqual((dispatchedActions) => { expect(dispatchedActions[0]).toEqual(toKeyedAction(key, variablesInitTransaction({ uid: key }))); expect(dispatchedActions[1].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[1].payload.action.payload.id).toEqual('__dashboard'); expect(dispatchedActions[2].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[2].payload.action.payload.id).toEqual('__org'); expect(dispatchedActions[3].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[3].payload.action.payload.id).toEqual('__user'); expect(dispatchedActions[4]).toEqual( toKeyedAction(key, addVariable(toVariablePayload(ds, { global: false, index: 0, model: ds }))) ); expect(dispatchedActions[5]).toEqual( toKeyedAction(key, addVariable(toVariablePayload(query, { global: false, index: 1, model: query }))) ); expect(dispatchedActions[6]).toEqual( toKeyedAction(key, addVariable(toVariablePayload(adhoc, { global: false, index: 2, model: adhoc }))) ); expect(dispatchedActions[7]).toEqual(toKeyedAction(key, variableStateNotStarted(toVariablePayload(ds)))); expect(dispatchedActions[8]).toEqual(toKeyedAction(key, variableStateNotStarted(toVariablePayload(query)))); expect(dispatchedActions[9]).toEqual(toKeyedAction(key, variableStateNotStarted(toVariablePayload(adhoc)))); expect(dispatchedActions[10]).toEqual( toKeyedAction( key, changeVariableProp(toVariablePayload(query, { propName: 'datasource', propValue: { uid: '${ds}' } })) ) ); expect(dispatchedActions[11]).toEqual( toKeyedAction( key, changeVariableProp(toVariablePayload(adhoc, { propName: 'datasource', propValue: { uid: '${ds}' } })) ) ); expect(dispatchedActions[12]).toEqual(toKeyedAction(key, variableStateFetching(toVariablePayload(ds)))); expect(dispatchedActions[13]).toEqual(toKeyedAction(key, variableStateCompleted(toVariablePayload(adhoc)))); expect(dispatchedActions[14]).toEqual( toKeyedAction(key, createDataSourceOptions(toVariablePayload(ds, { sources: [], regex: undefined }))) ); expect(dispatchedActions[15]).toEqual( toKeyedAction( key, setCurrentVariableValue( toVariablePayload(ds, { option: { selected: false, text: 'No data sources found', value: '' } }) ) ) ); expect(dispatchedActions[16]).toEqual(toKeyedAction(key, variableStateCompleted(toVariablePayload(ds)))); expect(dispatchedActions[17]).toEqual(toKeyedAction(key, variableStateFetching(toVariablePayload(query)))); expect(dispatchedActions[18]).toEqual(toKeyedAction(key, variableStateCompleted(toVariablePayload(query)))); expect(dispatchedActions[19]).toEqual(toKeyedAction(key, variablesCompleteTransaction({ uid: key }))); return dispatchedActions.length === 20; }); }); }); }); describe('when called and the previous dashboard is still processing variables', () => { it('then correct actions are dispatched', async () => { const { constant, key, dashboard } = getTestContext(); const transactionState = { ...initialTransactionState, uid: 'previous-uid', status: TransactionStatus.Fetching }; const preloadedState = getPreloadedState(key, { transaction: transactionState }); const tester = await reduxTester<RootReducerType>({ preloadedState }) .givenRootReducer(getRootReducer()) .whenAsyncActionIsDispatched(initVariablesTransaction(key, dashboard)); tester.thenDispatchedActionsPredicateShouldEqual((dispatchedActions) => { expect(dispatchedActions[0]).toEqual(toKeyedAction(key, cleanVariables())); expect(dispatchedActions[1]).toEqual(toKeyedAction(key, cleanEditorState())); expect(dispatchedActions[2]).toEqual(toKeyedAction(key, cleanPickerState())); expect(dispatchedActions[3]).toEqual(toKeyedAction(key, variablesClearTransaction())); expect(dispatchedActions[4]).toEqual(toKeyedAction(key, variablesInitTransaction({ uid: key }))); expect(dispatchedActions[5].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[5].payload.action.payload.id).toEqual('__dashboard'); expect(dispatchedActions[6].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[6].payload.action.payload.id).toEqual('__org'); expect(dispatchedActions[7].payload.action.type).toEqual(addVariable.type); expect(dispatchedActions[7].payload.action.payload.id).toEqual('__user'); expect(dispatchedActions[8]).toEqual( toKeyedAction(key, addVariable(toVariablePayload(constant, { global: false, index: 0, model: constant }))) ); expect(dispatchedActions[9]).toEqual(toKeyedAction(key, variableStateNotStarted(toVariablePayload(constant)))); expect(dispatchedActions[10]).toEqual(toKeyedAction(key, variableStateCompleted(toVariablePayload(constant)))); expect(dispatchedActions[11]).toEqual(toKeyedAction(key, variablesCompleteTransaction({ uid: key }))); return dispatchedActions.length === 12; }); }); }); });
.
Edit
..
Edit
__tests__
Edit
actions.test.ts
Edit
actions.ts
Edit
helpers.ts
Edit
initVariableTransaction.test.ts
Edit
keyedVariablesReducer.test.ts
Edit
keyedVariablesReducer.ts
Edit
migrateVariablesDatasourceNameToRef.test.ts
Edit
onTimeRangeUpdated.test.ts
Edit
processVariable.test.ts
Edit
reducers.test.ts
Edit
reducers.ts
Edit
selectors.ts
Edit
setOptionFromUrl.test.ts
Edit
sharedReducer.test.ts
Edit
sharedReducer.ts
Edit
templateVarsChangedInUrl.test.ts
Edit
transactionReducer.test.ts
Edit
transactionReducer.ts
Edit
types.ts
Edit
upgradeLegacyQueries.test.ts
Edit
variablesReducer.ts
Edit