Dashboard: Alerts user to incorrect tag format for JSON import (#54657)
* Dashboard: Alerts user to incorrect tag format for JSON import Fixes #54285: Malformed tags cause hidden title and settings page crash * Update public/app/features/manage-dashboards/utils/validation.ts Co-authored-by: Polina Boneva <13227501+polibb@users.noreply.github.com> * Included Suggestions - Removed Comments - Updated Code Block accordingly - Updated Tests to camelCase over snake_case * Updates per comments - Re-wrapped function in try{}, catch{} as I appear to have overlooked including it in the initial refactor - Re-worded errors to align with initial error - Added a test case for invalid json * Update validation.ts Updated errors to read correctly to the root cause. Updated dashboard variable as const. * Update actions.test.ts Fix tests according to error output rewording * Update validation.ts - Included test for an empty string of non-array * Update actions.test.ts -- Commented incorrect commit for validation.ts, update: - Refactored code to better align and separate from generic JSON package tests followed by our manual checks of (1) Is array, and (2) if array, is of strings - Test cases now include a check for non-array empty string in the tag property Co-authored-by: Polina Boneva <13227501+polibb@users.noreply.github.com>
This commit is contained in:
co-authored by
Polina Boneva
parent
e52c98ba99
commit
5285d34cc0
@@ -2,6 +2,8 @@ import { thunkTester } from 'test/core/thunk/thunkTester';
|
|||||||
|
|
||||||
import { setBackendSrv } from '@grafana/runtime';
|
import { setBackendSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
|
import { validateDashboardJson } from '../utils/validation';
|
||||||
|
|
||||||
import { importDashboard } from './actions';
|
import { importDashboard } from './actions';
|
||||||
import { DataSourceInput, ImportDashboardDTO, initialImportDashboardState, InputType } from './reducers';
|
import { DataSourceInput, ImportDashboardDTO, initialImportDashboardState, InputType } from './reducers';
|
||||||
|
|
||||||
@@ -75,3 +77,32 @@ describe('importDashboard', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('validateDashboardJson', () => {
|
||||||
|
it('Should return true if correct json', async () => {
|
||||||
|
const jsonImportCorrectFormat = '{"title": "Correct Format", "tags": ["tag1", "tag2"], "schemaVersion": 36}';
|
||||||
|
const validateDashboardJsonCorrectFormat = await validateDashboardJson(jsonImportCorrectFormat);
|
||||||
|
expect(validateDashboardJsonCorrectFormat).toBe(true);
|
||||||
|
});
|
||||||
|
it('Should not return true if nested tags', async () => {
|
||||||
|
const jsonImportNestedTags =
|
||||||
|
'{"title": "Nested tags","tags": ["tag1", "tag2", ["nestedTag1", "nestedTag2"]],"schemaVersion": 36}';
|
||||||
|
const validateDashboardJsonNestedTags = await validateDashboardJson(jsonImportNestedTags);
|
||||||
|
expect(validateDashboardJsonNestedTags).toBe('tags expected array of strings');
|
||||||
|
});
|
||||||
|
it('Should not return true if not an array', async () => {
|
||||||
|
const jsonImportNotArray = '{"title": "Not Array","tags": "tag1","schemaVersion":36}';
|
||||||
|
const validateDashboardJsonNotArray = await validateDashboardJson(jsonImportNotArray);
|
||||||
|
expect(validateDashboardJsonNotArray).toBe('tags expected array');
|
||||||
|
});
|
||||||
|
it('Should not return true if not an array and is blank string', async () => {
|
||||||
|
const jsonImportEmptyTags = '{"schemaVersion": 36,"tags": "", "title": "Empty Tags"}';
|
||||||
|
const validateDashboardJsonEmptyTags = await validateDashboardJson(jsonImportEmptyTags);
|
||||||
|
expect(validateDashboardJsonEmptyTags).toBe('tags expected array');
|
||||||
|
});
|
||||||
|
it('Should not return true if not valid JSON', async () => {
|
||||||
|
const jsonImportInvalidJson = '{"schemaVersion": 36,"tags": {"tag", "nested tag"}, "title": "Nested lists"}';
|
||||||
|
const validateDashboardJsonNotValid = await validateDashboardJson(jsonImportInvalidJson);
|
||||||
|
expect(validateDashboardJsonNotValid).toBe('Not valid JSON');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -3,12 +3,23 @@ import { getBackendSrv } from '@grafana/runtime';
|
|||||||
import { validationSrv } from '../services/ValidationSrv';
|
import { validationSrv } from '../services/ValidationSrv';
|
||||||
|
|
||||||
export const validateDashboardJson = (json: string) => {
|
export const validateDashboardJson = (json: string) => {
|
||||||
|
let dashboard;
|
||||||
try {
|
try {
|
||||||
JSON.parse(json);
|
dashboard = JSON.parse(json);
|
||||||
return true;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return 'Not valid JSON';
|
return 'Not valid JSON';
|
||||||
}
|
}
|
||||||
|
if (dashboard && dashboard.hasOwnProperty('tags')) {
|
||||||
|
if (Array.isArray(dashboard.tags)) {
|
||||||
|
const hasInvalidTag = dashboard.tags.some((tag: string) => typeof tag !== 'string');
|
||||||
|
if (hasInvalidTag) {
|
||||||
|
return 'tags expected array of strings';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 'tags expected array';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateGcomDashboard = (gcomDashboard: string) => {
|
export const validateGcomDashboard = (gcomDashboard: string) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user