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,
hasStandardVariableSupport,
isAdHoc,
isConstant,
isMulti,
isQuery,
} from '../guard';
@ -628,6 +629,10 @@ export const templateVarsChangedInUrl = (
if (variableInModel && hasCurrent(variableInModel)) {
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);

View File

@ -1,5 +1,5 @@
import { variableAdapters } from '../adapters';
import { customBuilder } from '../shared/testing/builders';
import { constantBuilder, customBuilder } from '../shared/testing/builders';
import { DashboardState, StoreState } from '../../../types';
import { initialState } from '../../dashboard/state/reducers';
import { TemplatingState } from './reducers';
@ -8,17 +8,27 @@ import { templateVarsChangedInUrl } from './actions';
import { createCustomVariableAdapter } from '../custom/adapter';
import { VariablesState } from './types';
import { DashboardModel } from '../../dashboard/state';
import { createConstantVariableAdapter } from '../constant/adapter';
import { VariableModel } from '../types';
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();
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();
variableAdapters.get('custom').setValueFromUrl = setValueFromUrlMock;
variableAdapters.get(variable.type).setValueFromUrl = setValueFromUrlMock;
const templateVariableValueUpdatedMock = jest.fn();
const startRefreshMock = jest.fn();
@ -27,12 +37,12 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}) {
getModel: () => {
dashboardModel.templateVariableValueUpdated = templateVariableValueUpdatedMock;
dashboardModel.startRefresh = startRefreshMock;
dashboardModel.templating = { list: [custom] };
dashboardModel.templating = { list: [variable] };
return dashboardModel;
},
};
const variables: VariablesState = { custom };
const variables: VariablesState = { variable };
const templating = ({ variables } as unknown) as TemplatingState;
const state: Partial<StoreState> = {
dashboard,
@ -45,7 +55,7 @@ async function getTestContext(urlQueryMap: ExtendedUrlQueryMap = {}) {
await thunk(dispatch, getState, undefined);
return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, custom };
return { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock, variable };
}
describe('templateVarsChangedInUrl', () => {
@ -75,7 +85,7 @@ describe('templateVarsChangedInUrl', () => {
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 () => {
const { setValueFromUrlMock, templateVariableValueUpdatedMock, startRefreshMock } = await getTestContext({
'var-custom': { value: ['A', 'C'] },
'var-variable': { value: ['A', 'C'] },
});
expect(setValueFromUrlMock).not.toHaveBeenCalled();
@ -90,13 +100,13 @@ describe('templateVarsChangedInUrl', () => {
setValueFromUrlMock,
templateVariableValueUpdatedMock,
startRefreshMock,
custom,
variable,
} = await getTestContext({
'var-custom': { value: 'B' },
'var-variable': { value: 'B' },
});
expect(setValueFromUrlMock).toHaveBeenCalledTimes(1);
expect(setValueFromUrlMock).toHaveBeenCalledWith(custom, 'B');
expect(setValueFromUrlMock).toHaveBeenCalledWith(variable, 'B');
expect(templateVariableValueUpdatedMock).toHaveBeenCalledTimes(1);
expect(startRefreshMock).toHaveBeenCalledTimes(1);
});
@ -107,13 +117,39 @@ describe('templateVarsChangedInUrl', () => {
setValueFromUrlMock,
templateVariableValueUpdatedMock,
startRefreshMock,
custom,
variable,
} = await getTestContext({
'var-custom': { value: '', removed: true },
'var-variable': { value: '', removed: true },
});
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(startRefreshMock).toHaveBeenCalledTimes(1);
});