Dashboard: Fix Variables query hides fields with non-supported datasources (#88516)

* Show queryVariable editor even if the variable does not support variables

* Fix VariableQueryRunner unit test, now takes into account the new function
This commit is contained in:
Alexa V 2024-06-03 13:58:30 +02:00 committed by GitHub
parent 44c62dd536
commit e147c58a7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 22 additions and 8 deletions

View File

@ -131,7 +131,7 @@ export class QueryVariableEditorUnConnected extends PureComponent<Props, State>
render() {
const { extended, variable } = this.props;
if (!extended || !extended.dataSource || !extended.VariableQueryEditor) {
if (!extended || !extended.dataSource) {
return null;
}

View File

@ -70,6 +70,7 @@ function getTestContext(variable?: QueryVariableModel) {
runRequest: jest.fn().mockReturnValue(of({ series: [], state: LoadingState.Done })),
};
const queryRunners = {
isQueryRunnerAvailableForDatasource: jest.fn().mockReturnValue(true),
getRunnerForDatasource: jest.fn().mockReturnValue(queryRunner),
} as unknown as QueryRunners;
const getVariable = jest.fn().mockReturnValue(variable);
@ -147,15 +148,12 @@ describe('VariableQueryRunner', () => {
});
describe('error cases', () => {
describe('queryRunners.getRunnerForDatasource throws', () => {
describe('queryRunners.isQueryRunnerAvailableForDatasource throws', () => {
it('then it should work as expected', (done) => {
const { identifier, runner, datasource, getState, getVariable, queryRunners, queryRunner, dispatch } =
getTestContext();
queryRunners.getRunnerForDatasource = jest.fn().mockImplementation(() => {
throw new Error('getRunnerForDatasource error');
});
queryRunners.isQueryRunnerAvailableForDatasource = jest.fn().mockReturnValue(false);
expectOnResults({
identifier,
runner,
@ -163,13 +161,17 @@ describe('VariableQueryRunner', () => {
// verify that the observable works as expected
expect(results).toEqual([
{ state: LoadingState.Loading, identifier },
{ state: LoadingState.Error, identifier, error: new Error('getRunnerForDatasource error') },
{
state: LoadingState.Error,
identifier,
error: new Error('Query Runner is not available for datasource.'),
},
]);
// verify that mocks have been called as expected
expect(getState).toHaveBeenCalledTimes(2);
expect(getVariable).toHaveBeenCalledTimes(1);
expect(queryRunners.getRunnerForDatasource).toHaveBeenCalledTimes(1);
expect(queryRunners.isQueryRunnerAvailableForDatasource).toHaveBeenCalledTimes(1);
expect(queryRunner.getTarget).not.toHaveBeenCalled();
expect(queryRunner.runRequest).not.toHaveBeenCalled();
expect(datasource.metricFindQuery).not.toHaveBeenCalled();

View File

@ -111,6 +111,13 @@ export class VariableQueryRunner {
const timeSrv = getTimeSrv();
const runnerArgs = { variable, datasource, searchFilter, timeSrv, runRequest };
//if query runner is not available for the datasource, we should return early
if (!queryRunners.isQueryRunnerAvailableForDatasource(datasource)) {
const error = new Error('Query Runner is not available for datasource.');
this.updateOptionsResults.next({ identifier, state: LoadingState.Error, error });
return;
}
const runner = queryRunners.getRunnerForDatasource(datasource);
const target = runner.getTarget({ datasource, variable });
const request = this.getRequest(variable, args, target);

View File

@ -61,6 +61,11 @@ export class QueryRunners {
throw new Error("Couldn't find a query runner that matches supplied arguments.");
}
//Check if datasource has a query runner associated with it
isQueryRunnerAvailableForDatasource(datasource: DataSourceApi) {
return this.runners.some((runner) => runner.canRun(datasource));
}
}
class LegacyQueryRunner implements QueryRunner {