diff --git a/public/app/features/dimensions/resource.test.ts b/public/app/features/dimensions/resource.test.ts index 646bf297ff5..ad644b61b4f 100644 --- a/public/app/features/dimensions/resource.test.ts +++ b/public/app/features/dimensions/resource.test.ts @@ -1,7 +1,7 @@ import { createDataFrame } from '@grafana/data'; import { ResourceDimensionMode } from '@grafana/schema'; -import { getResourceDimension } from './resource'; +import { getPublicOrAbsoluteUrl, getResourceDimension } from './resource'; describe('getResourceDimension', () => { const publicPath = 'https://grafana.fake/public/'; @@ -63,5 +63,66 @@ describe('getResourceDimension', () => { expect(getResourceDimension(frame, config).value()).toEqual('https://3rdparty.fake/field.png'); }); + it('should return empty string for boolean field values', () => { + const frame = createDataFrame({ + fields: [ + { + name: 'image_field', + values: [true], + display: (v) => ({ + text: String(v), + numeric: NaN, + icon: undefined, + }), + }, + ], + }); + const config = { mode: ResourceDimensionMode.Field, field: 'image_field', fixed: '' }; + + expect(getResourceDimension(frame, config).get(0)).toEqual(''); + expect(getResourceDimension(frame, config).value()).toEqual(''); + }); + + it('should return empty string for numeric field values', () => { + const frame = createDataFrame({ + fields: [ + { + name: 'image_field', + values: [123], + display: (v) => ({ + text: String(v), + numeric: Number(v), + icon: undefined, + }), + }, + ], + }); + const config = { mode: ResourceDimensionMode.Field, field: 'image_field', fixed: '' }; + + expect(getResourceDimension(frame, config).get(0)).toEqual(''); + expect(getResourceDimension(frame, config).value()).toEqual(''); + }); + // TODO: write tests for mapping modes }); + +describe('getPublicOrAbsoluteUrl', () => { + const publicPath = 'https://grafana.fake/public/'; + beforeAll(() => { + window.__grafana_public_path__ = publicPath; + }); + + it('should handle string paths correctly', () => { + expect(getPublicOrAbsoluteUrl('icon.png')).toEqual(`${publicPath}build/icon.png`); + expect(getPublicOrAbsoluteUrl('https://example.com/icon.png')).toEqual('https://example.com/icon.png'); + }); + + it('should return empty string for non-string values', () => { + expect(getPublicOrAbsoluteUrl(true)).toEqual(''); + expect(getPublicOrAbsoluteUrl(123)).toEqual(''); + expect(getPublicOrAbsoluteUrl(null)).toEqual(''); + expect(getPublicOrAbsoluteUrl(undefined)).toEqual(''); + expect(getPublicOrAbsoluteUrl({ path: 'icon.png' })).toEqual(''); + expect(getPublicOrAbsoluteUrl(['icon.png'])).toEqual(''); + }); +}); diff --git a/public/app/features/dimensions/resource.ts b/public/app/features/dimensions/resource.ts index 278469b6a45..4eb28242550 100644 --- a/public/app/features/dimensions/resource.ts +++ b/public/app/features/dimensions/resource.ts @@ -7,8 +7,8 @@ import { findField, getLastNotNullFieldValue } from './utils'; //--------------------------------------------------------- // Resource dimension //--------------------------------------------------------- -export function getPublicOrAbsoluteUrl(path: string): string { - if (!path) { +export function getPublicOrAbsoluteUrl(path: unknown): string { + if (!path || typeof path !== 'string') { return ''; } @@ -55,7 +55,11 @@ export function getResourceDimension( } // mode === ResourceDimensionMode.Field case - const getImageOrIcon = (value: string): string => { + const getImageOrIcon = (value: unknown): string => { + if (typeof value !== 'string') { + return ''; + } + let url = value; if (field && field.display) { const displayValue = field.display(value);