/usr/share/grafana/public/app/features/variables/state
import { cloneDeep } from 'lodash'; import { BaseVariableModel, ConstantVariableModel, LoadingState, QueryVariableModel, VariableOption, VariableType, } from '@grafana/data'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { variableAdapters } from '../adapters'; import { createConstantVariableAdapter } from '../constant/adapter'; import { initialConstantVariableModelState } from '../constant/reducer'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { changeVariableNameSucceeded } from '../editor/reducer'; import { createQueryVariableAdapter } from '../query/adapter'; import { initialQueryVariableModelState } from '../query/reducer'; import { toVariablePayload } from '../utils'; import { createConstantVariable } from './__tests__/fixtures'; import { getVariableState, getVariableTestContext } from './helpers'; import { addVariable, changeVariableOrder, changeVariableProp, changeVariableType, duplicateVariable, removeVariable, setCurrentVariableValue, sharedReducer, variableStateCompleted, variableStateFailed, variableStateFetching, variableStateNotStarted, } from './sharedReducer'; import { initialVariablesState, KeyedVariableIdentifier, VariablesState } from './types'; variableAdapters.setInit(() => [createQueryVariableAdapter(), createConstantVariableAdapter()]); describe('sharedReducer', () => { describe('when addVariable is dispatched', () => { it('then state should be correct', () => { const model = { name: 'name from model', type: 'query', current: undefined, } as unknown as BaseVariableModel; const expected: QueryVariableModel = { ...initialQueryVariableModelState, id: 'name from model', global: true, index: 0, name: 'name from model', type: 'query', current: {} as unknown as VariableOption, }; const payload = toVariablePayload({ id: 'name from model', type: 'query' }, { global: true, index: 0, model }); reducerTester<VariablesState>() .givenReducer(sharedReducer, { ...initialVariablesState }) .whenActionIsDispatched(addVariable(payload)) .thenStateShouldEqual({ ['name from model']: expected, }); }); }); describe('when addVariable is dispatched for a constant model', () => { it('then state should be correct', () => { const model = { name: 'constant', type: 'constant', query: 'a constant', current: { selected: true, text: 'A', value: 'A' }, options: [{ selected: true, text: 'A', value: 'A' }], } as unknown as BaseVariableModel; const expected: ConstantVariableModel = { ...initialConstantVariableModelState, id: 'constant', global: true, index: 0, name: 'constant', type: 'constant', query: 'a constant', current: { selected: true, text: 'a constant', value: 'a constant' }, options: [{ selected: true, text: 'a constant', value: 'a constant' }], }; const payload = toVariablePayload({ id: 'constant', type: 'constant' }, { global: true, index: 0, model }); reducerTester<VariablesState>() .givenReducer(sharedReducer, { ...initialVariablesState }) .whenActionIsDispatched(addVariable(payload)) .thenStateShouldEqual({ ['constant']: expected, }); }); }); describe('when removeVariable is dispatched and reIndex is true', () => { it('then state should be correct', () => { const initialState = getVariableState(3); const payload = toVariablePayload({ id: '1', type: 'query' }, { reIndex: true }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(removeVariable(payload)) .thenStateShouldEqual({ '0': { ...initialState['0'], index: 0, }, '2': { ...initialState['2'], index: 1, }, }); }); }); describe('when removeVariable is dispatched and reIndex is false', () => { it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3); const payload = toVariablePayload({ id: '1', type: 'query' }, { reIndex: false }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(removeVariable(payload)) .thenStateShouldEqual({ '0': initialState['0'], '2': initialState['2'], }); }); }); describe('when duplicateVariable is dispatched', () => { it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3, -1, false, true); const payload = toVariablePayload({ id: '1', type: 'query' }, { newId: '11' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(duplicateVariable(payload)) .thenStateShouldEqual({ ...initialState, '11': { ...initialQueryVariableModelState, ...initialState['1'], id: '11', name: 'copy_of_Name-1', index: 3, }, }); }); it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3, -1, false, true); initialState['1'].name = 'copy_of_Name-1_2'; const payload = toVariablePayload({ id: '1', type: 'query' }, { newId: '11' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(duplicateVariable(payload)) .thenStateShouldEqual({ ...initialState, '11': { ...initialQueryVariableModelState, ...initialState['1'], id: '11', name: 'copy_of_copy_of_Name-1_2', index: 3, }, }); }); it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3, -1, false, true); initialState['0'].name = 'Name-0'; initialState['1'].name = 'copy_of_Name-0_2'; const payload = toVariablePayload({ id: '0', type: 'query' }, { newId: '01' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(duplicateVariable(payload)) .thenStateShouldEqual({ ...initialState, '01': { ...initialQueryVariableModelState, ...initialState['0'], id: '01', name: 'copy_of_Name-0_3', index: 3, }, }); }); it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3, -1, false, true); initialState['1'].name = 'copy_of_Name-1_2'; const duplicateOne = toVariablePayload({ id: '1', type: 'query' }, { newId: '11' }); const duplicateTwo = toVariablePayload({ id: '1', type: 'query' }, { newId: '12' }); const duplicateThree = toVariablePayload({ id: '1', type: 'query' }, { newId: '13' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(duplicateVariable(duplicateOne)) .whenActionIsDispatched(duplicateVariable(duplicateTwo)) .whenActionIsDispatched(duplicateVariable(duplicateThree)) .thenStateShouldEqual({ ...initialState, '11': { ...initialQueryVariableModelState, ...initialState['1'], id: '11', name: 'copy_of_copy_of_Name-1_2', index: 3, }, '12': { ...initialQueryVariableModelState, ...initialState['1'], id: '12', name: 'copy_of_copy_of_Name-1_2_1', index: 4, }, '13': { ...initialQueryVariableModelState, ...initialState['1'], id: '13', name: 'copy_of_copy_of_Name-1_2_2', index: 5, }, }); }); }); describe('when changeVariableOrder is dispatched', () => { it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3); const payload = toVariablePayload({ id: '2', type: 'query' }, { fromIndex: 2, toIndex: 0 }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(changeVariableOrder(payload)) .thenStateShouldEqual({ '0': { ...initialState['0'], index: 1, }, '1': { ...initialState['1'], index: 2, }, '2': { ...initialState['2'], index: 0, }, }); }); it('then state should be correct', () => { const initialState: VariablesState = getVariableState(3); const payload = toVariablePayload({ id: '0', type: 'query' }, { fromIndex: 0, toIndex: 2 }); reducerTester<VariablesState>() .givenReducer(sharedReducer, initialState) .whenActionIsDispatched(changeVariableOrder(payload)) .thenStateShouldEqual({ '0': { ...initialState['0'], index: 2, }, '1': { ...initialState['1'], index: 0, }, '2': { ...initialState['2'], index: 1, }, }); }); }); describe('when setCurrentVariableValue is dispatched and current.text is an Array with values', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { options: [ { text: 'All', value: '$__all', selected: false }, { text: 'A', value: 'A', selected: false }, { text: 'B', value: 'B', selected: false }, ], }); const current = { text: ['A', 'B'], selected: true, value: ['A', 'B'] }; const payload = toVariablePayload({ id: '0', type: 'query' }, { option: current }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(setCurrentVariableValue(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], options: [ { selected: false, text: 'All', value: '$__all' }, { selected: true, text: 'A', value: 'A' }, { selected: true, text: 'B', value: 'B' }, ], current: { selected: true, text: ['A', 'B'], value: ['A', 'B'] }, } as unknown as QueryVariableModel, }); }); }); describe('when setCurrentVariableValue is dispatched and current.value is an Array with values except All value', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { options: [ { text: 'All', value: '$__all', selected: false }, { text: 'A', value: 'A', selected: false }, { text: 'B', value: 'B', selected: false }, ], }); const current = { text: 'A + B', selected: true, value: ['A', 'B'] }; const payload = toVariablePayload({ id: '0', type: 'query' }, { option: current }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(setCurrentVariableValue(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], options: [ { selected: false, text: 'All', value: '$__all' }, { selected: true, text: 'A', value: 'A' }, { selected: true, text: 'B', value: 'B' }, ], current: { selected: true, text: 'A + B', value: ['A', 'B'] }, } as unknown as QueryVariableModel, }); }); }); describe('when setCurrentVariableValue is dispatched and current.value is an Array with values containing All value', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { options: [ { text: 'All', value: '$__all', selected: false }, { text: 'A', value: 'A', selected: false }, { text: 'B', value: 'B', selected: false }, ], }); const current = { text: ALL_VARIABLE_TEXT, selected: true, value: [ALL_VARIABLE_VALUE] }; const payload = toVariablePayload({ id: '0', type: 'query' }, { option: current }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(setCurrentVariableValue(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], options: [ { selected: true, text: 'All', value: '$__all' }, { selected: false, text: 'A', value: 'A' }, { selected: false, text: 'B', value: 'B' }, ], current: { selected: true, text: 'All', value: ['$__all'] }, } as unknown as QueryVariableModel, }); }); }); describe('when variableStateNotStarted is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { state: LoadingState.Done, error: 'Some error', }); const payload = toVariablePayload({ id: '0', type: 'query' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(variableStateNotStarted(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], state: LoadingState.NotStarted, error: null, } as unknown as QueryVariableModel, }); }); }); describe('when variableStateFetching is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { state: LoadingState.Done, error: 'Some error', }); const payload = toVariablePayload({ id: '0', type: 'query' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(variableStateFetching(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], state: LoadingState.Loading, error: null, } as unknown as QueryVariableModel, }); }); }); describe('when variableStateCompleted is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { state: LoadingState.Loading, error: 'Some error', }); const payload = toVariablePayload({ id: '0', type: 'query' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(variableStateCompleted(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], state: LoadingState.Done, error: null, } as unknown as QueryVariableModel, }); }); }); describe('when variableStateFailed is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter, { state: LoadingState.Loading }); const payload = toVariablePayload({ id: '0', type: 'query' }, { error: 'Some error' }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(variableStateFailed(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], state: LoadingState.Error, error: 'Some error', } as unknown as QueryVariableModel, }); }); }); describe('when changeVariableProp is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter); const propName = 'label'; const propValue = 'Updated label'; const payload = toVariablePayload({ id: '0', type: 'query' }, { propName, propValue }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(changeVariableProp(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], label: 'Updated label', }, }); }); }); describe('when changeVariableNameSucceeded is dispatched', () => { it('then state should be correct', () => { const adapter = createQueryVariableAdapter(); const { initialState } = getVariableTestContext(adapter); const newName = 'A new name'; const payload = toVariablePayload({ id: '0', type: 'query' }, { newName }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(initialState)) .whenActionIsDispatched(changeVariableNameSucceeded(payload)) .thenStateShouldEqual({ ...initialState, '0': { ...initialState[0], name: 'A new name', }, }); }); }); describe('when changeVariableType is dispatched', () => { it('then state should be correct', () => { const queryAdapter = createQueryVariableAdapter(); const { initialState: queryAdapterState } = getVariableTestContext(queryAdapter); const constantAdapter = createConstantVariableAdapter(); const { initialState: constantAdapterState } = getVariableTestContext(constantAdapter); const newType = 'constant' as VariableType; const identifier: KeyedVariableIdentifier = { id: '0', type: 'query', rootStateKey: 'key' }; const payload = toVariablePayload(identifier, { newType }); reducerTester<VariablesState>() .givenReducer(sharedReducer, cloneDeep(queryAdapterState)) .whenActionIsDispatched(changeVariableNameSucceeded(toVariablePayload(identifier, { newName: 'test' }))) .whenActionIsDispatched( changeVariableProp(toVariablePayload(identifier, { propName: 'description', propValue: 'new description' })) ) .whenActionIsDispatched( changeVariableProp(toVariablePayload(identifier, { propName: 'label', propValue: 'new label' })) ) .whenActionIsDispatched(changeVariableType(payload)) .thenStateShouldEqual({ ...constantAdapterState, '0': { ...constantAdapterState[0], ...createConstantVariable({ type: 'constant', rootStateKey: 'key', name: 'test', description: 'new description', label: 'new label', current: {} as VariableOption, }), }, }); }); }); });
.
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