Variables: Fix for constant variables in self referencing links (#44631)

* Variables: Fix for constant variables in self referencing links

* Chore: adds bettercomment
This commit is contained in:
Hugo Häggmark 2022-01-31 13:34:26 +01:00 committed by GitHub
parent 9035859871
commit 5a5f5cacc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 15 deletions

View File

@ -52,6 +52,7 @@ import {
hasOptions, hasOptions,
hasStandardVariableSupport, hasStandardVariableSupport,
isAdHoc, isAdHoc,
isConstant,
isMulti, isMulti,
isQuery, isQuery,
} from '../guard'; } from '../guard';
@ -628,6 +629,10 @@ export const templateVarsChangedInUrl = (
if (variableInModel && hasCurrent(variableInModel)) { if (variableInModel && hasCurrent(variableInModel)) {
value = variableInModel.current.value; // revert value to the value stored in dashboard json value = variableInModel.current.value; // revert value to the value stored in dashboard json
} }
if (variableInModel && isConstant(variableInModel)) {
value = variableInModel.query; // revert value to the value stored in dashboard json, constants don't store current values in dashboard json
}
} }
const promise = variableAdapters.get(variable.type).setValueFromUrl(variable, value); const promise = variableAdapters.get(variable.type).setValueFromUrl(variable, value);

View File

@ -1,5 +1,5 @@
import { variableAdapters } from '../adapters'; import { variableAdapters } from '../adapters';
import { customBuilder } from '../shared/testing/builders'; import { constantBuilder, customBuilder } from '../shared/testing/builders';
import { DashboardState, StoreState } from '../../../types'; import { DashboardState, StoreState } from '../../../types';
import { initialState } from '../../dashboard/state/reducers'; import { initialState } from '../../dashboard/state/reducers';
import { TemplatingState } from './reducers'; import { TemplatingState } from './reducers';
@ -8,17 +8,27 @@ import { templateVarsChangedInUrl } from './actions';
import { createCustomVariableAdapter } from '../custom/adapter'; import { createCustomVariableAdapter } from '../custom/adapter';
import { VariablesState } from './types'; import { VariablesState } from './types';
import { DashboardModel } from '../../dashboard/state'; import { DashboardModel } from '../../dashboard/state';
import { createConstantVariableAdapter } from '../constant/adapter';
import { VariableModel } from '../types';
const dashboardModel = new DashboardModel({}); const dashboardModel = new DashboardModel({});
variableAdapters.setInit(() => [createCustomVariableAdapter()]); variableAdapters.setInit(() => [createCustomVariableAdapter(), createConstantVariableAdapter()]);
async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}) { async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}, variable: VariableModel | undefined = undefined) {
jest.clearAllMocks(); jest.clearAllMocks();
const custom = customBuilder().withId('custom').withCurrent(['A', 'C']).withOptions('A', 'B', 'C').build(); if (!variable) {
variable = customBuilder()
.withId('variable')
.withName('variable')
.withCurrent(['A', 'C'])
.withOptions('A', 'B', 'C')
.build();
}
const setValueFromUrlMock = jest.fn(); const setValueFromUrlMock = jest.fn();
variableAdapters.get('custom').setValueFromUrl = setValueFromUrlMock; variableAdapters.get(variable.type).setValueFromUrl = setValueFromUrlMock;
const templateVariableValueUpdatedMock = jest.fn(); const templateVariableValueUpdatedMock = jest.fn();
const startRefreshMock = jest.fn(); const startRefreshMock = jest.fn();
@ -27,12 +37,12 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}) {
getModel: () => { getModel: () => {
dashboardModel.templateVariableValueUpdated = templateVariableValueUpdatedMock; dashboardModel.templateVariableValueUpdated = templateVariableValueUpdatedMock;
dashboardModel.startRefresh = startRefreshMock; dashboardModel.startRefresh = startRefreshMock;
dashboardModel.templating = { list: [custom] }; dashboardModel.templating = { list: [variable] };
return dashboardModel; return dashboardModel;
}, },
}; };
const variables: VariablesState = { custom }; const variables: VariablesState = { variable };
const templating = ({ variables } as unknown) as TemplatingState; const templating = ({ variables } as unknown) as TemplatingState;
const state: Partial<StoreState> = { const state: Partial<StoreState> = {
dashboard, dashboard,
@ -45,7 +55,7 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}) {
await thunk(dispatch, getState, undefined); await thunk(dispatch, getState, undefined);
return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, custom }; return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, variable };
} }
describe('templateVarsChangedInUrl', () => { describe('templateVarsChangedInUrl', () => {
@ -75,7 +85,7 @@ describe('templateVarsChangedInUrl', () => {
describe('and the values in url query map are the same as current in state', () => { describe('and the values in url query map are the same as current in state', () => {
it('then no value should change and dashboard should not be refreshed', async () => { it('then no value should change and dashboard should not be refreshed', async () => {
const { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock } = await getTestContext({ const { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock } = await getTestContext({
'var-custom': { value: ['A', 'C'] }, 'var-variable': { value: ['A', 'C'] },
}); });
expect(setValueFromUrlMock).not.toHaveBeenCalled(); expect(setValueFromUrlMock).not.toHaveBeenCalled();
@ -90,13 +100,13 @@ describe('templateVarsChangedInUrl', () => {
setValueFromUrlMock, setValueFromUrlMock,
templateVariableValueUpdatedMock, templateVariableValueUpdatedMock,
startRefreshMock, startRefreshMock,
custom, variable,
} = await getTestContext({ } = await getTestContext({
'var-custom': { value: 'B' }, 'var-variable': { value: 'B' },
}); });
expect(setValueFromUrlMock).toHaveBeenCalledTimes(1); expect(setValueFromUrlMock).toHaveBeenCalledTimes(1);
expect(setValueFromUrlMock).toHaveBeenCalledWith(custom, 'B'); expect(setValueFromUrlMock).toHaveBeenCalledWith(variable, 'B');
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1); expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
expect(startRefreshMock).toHaveBeenCalledTimes(1); expect(startRefreshMock).toHaveBeenCalledTimes(1);
}); });
@ -107,13 +117,39 @@ describe('templateVarsChangedInUrl', () => {
setValueFromUrlMock, setValueFromUrlMock,
templateVariableValueUpdatedMock, templateVariableValueUpdatedMock,
startRefreshMock, startRefreshMock,
custom, variable,
} = await getTestContext({ } = await getTestContext({
'var-custom': { value: '', removed: true }, 'var-variable': { value: '', removed: true },
}); });
expect(setValueFromUrlMock).toHaveBeenCalledTimes(1); expect(setValueFromUrlMock).toHaveBeenCalledTimes(1);
expect(setValueFromUrlMock).toHaveBeenCalledWith(custom, ['A', 'C']); expect(setValueFromUrlMock).toHaveBeenCalledWith(variable, ['A', 'C']);
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
expect(startRefreshMock).toHaveBeenCalledTimes(1);
});
});
describe('and the variable is a constant', () => {
it('then the value should change to the value in dashboard json and dashboard should be refreshed', async () => {
const constant = constantBuilder()
.withId('variable')
.withName('variable')
.withQuery('default value in dash.json')
.build();
const {
setValueFromUrlMock,
templateVariableValueUpdatedMock,
startRefreshMock,
variable,
} = await getTestContext(
{
'var-variable': { value: '', removed: true },
},
constant
);
expect(setValueFromUrlMock).toHaveBeenCalledTimes(1);
expect(setValueFromUrlMock).toHaveBeenCalledWith(variable, 'default value in dash.json');
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1); expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
expect(startRefreshMock).toHaveBeenCalledTimes(1); expect(startRefreshMock).toHaveBeenCalledTimes(1);
}); });