Loki: Fix issue where step parameter using a template variable was marked as invalid (#106541)

* Loki: Step with template variable should be valid

* Fix lint
This commit is contained in:
Ivana Huckova
2025-06-11 16:36:14 +02:00
committed by GitHub
parent fe5e69f731
commit c0e7701ad4
2 changed files with 54 additions and 2 deletions
@@ -273,6 +273,48 @@ describe('LokiQueryBuilderOptions', () => {
});
});
});
describe('Step validation', () => {
it('considers empty step as valid', async () => {
setup({ expr: 'rate({foo="bar"}[5m]' });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.queryByText(/Invalid step/)).not.toBeInTheDocument();
});
it('considers variable step that exists in the datasource as valid', async () => {
const datasource = createLokiDatasource();
datasource.getVariables = jest.fn().mockReturnValue(['$interval']);
setup({ expr: 'rate({foo="bar"}[5m]', step: '$interval' }, undefined, { datasource });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.queryByText(/Invalid step/)).not.toBeInTheDocument();
});
it('considers variable step that does not exist in the datasource as invalid', async () => {
const datasource = createLokiDatasource();
datasource.getVariables = jest.fn().mockReturnValue(['$interval']);
setup({ expr: 'rate({foo="bar"}[5m]', step: '$custom' }, undefined, { datasource });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.getByText(/Invalid step/)).toBeInTheDocument();
});
it('considers valid duration step as valid', async () => {
setup({ expr: 'rate({foo="bar"}[5m]', step: '1m' });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.queryByText(/Invalid step/)).not.toBeInTheDocument();
});
it('considers invalid step as invalid', async () => {
setup({ expr: 'rate({foo="bar"}[5m]', step: 'invalid' });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.getByText(/Invalid step/)).toBeInTheDocument();
});
it('considers non-duration number as invalid', async () => {
setup({ expr: 'rate({foo="bar"}[5m]', step: '123' });
await userEvent.click(screen.getByRole('button', { name: /Options/ }));
expect(screen.getByText(/Invalid step/)).toBeInTheDocument();
});
});
});
function setup(queryOverrides: Partial<LokiQuery> = {}, onChange = jest.fn(), propOverrides: Partial<Props> = {}) {
@@ -138,8 +138,18 @@ export const LokiQueryBuilderOptions = React.memo<Props>(
if (!query.step) {
return true;
}
return typeof query.step === 'string' && isValidGrafanaDuration(query.step) && !isNaN(parseInt(query.step, 10));
}, [query.step]);
if (typeof query.step === 'string') {
// If we use a variable as step, we consider it valid
if (datasource.getVariables().includes(query.step)) {
return true;
}
// Check if the step is a valid Grafana duration
return isValidGrafanaDuration(query.step) && !isNaN(parseInt(query.step, 10));
}
return false;
}, [query.step, datasource]);
return (
<EditorRow>