Files
grafana/public/app/features/explore/utils/links.test.ts
Ashley Harrison f8d89eff56 Chore: fix type errors in tests (#63270)
* fix any's in tests

* fix more any's in tests

* more test type fixes

* fixing any's in tests part 3

* more test type fixes

* fixing test any's p5

* some tidy up

* fix template_srv
2023-02-14 16:46:42 +01:00

318 lines
9.0 KiB
TypeScript

import {
ArrayVector,
DataFrame,
DataLink,
dateTime,
Field,
FieldType,
InterpolateFunction,
TimeRange,
toDataFrame,
} from '@grafana/data';
import { setTemplateSrv } from '@grafana/runtime';
import { initTemplateSrv } from '../../../../test/helpers/initTemplateSrv';
import { ContextSrv, setContextSrv } from '../../../core/services/context_srv';
import { setLinkSrv } from '../../panel/panellinks/link_srv';
import { getFieldLinksForExplore } from './links';
describe('getFieldLinksForExplore', () => {
beforeEach(() => {
setTemplateSrv(
initTemplateSrv('key', [
{ type: 'custom', name: 'emptyVar', current: { value: null } },
{ type: 'custom', name: 'num', current: { value: 1 } },
{ type: 'custom', name: 'test', current: { value: 'foo' } },
])
);
});
it('returns correct link model for external link', () => {
const { field, range } = setup({
title: 'external',
url: 'http://regionalhost',
});
const links = getFieldLinksForExplore({
field,
rowIndex: ROW_WITH_TEXT_VALUE.index,
splitOpenFn: jest.fn(),
range,
});
expect(links[0].href).toBe('http://regionalhost');
expect(links[0].title).toBe('external');
});
it('returns generates title for external link', () => {
const { field, range } = setup({
title: '',
url: 'http://regionalhost',
});
const links = getFieldLinksForExplore({
field,
rowIndex: ROW_WITH_TEXT_VALUE.index,
splitOpenFn: jest.fn(),
range,
});
expect(links[0].href).toBe('http://regionalhost');
expect(links[0].title).toBe('regionalhost');
});
it('returns correct link model for internal link', () => {
const { field, range } = setup({
title: '',
url: '',
internal: {
query: { query: 'query_1' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
panelsState: {
trace: {
spanId: 'abcdef',
},
},
},
});
const splitfn = jest.fn();
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, splitOpenFn: splitfn, range });
expect(links[0].href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1"}],"panelsState":{"trace":{"spanId":"abcdef"}}}'
)}`
);
expect(links[0].title).toBe('test_ds');
if (links[0].onClick) {
links[0].onClick({});
}
expect(splitfn).toBeCalledWith({
datasourceUid: 'uid_1',
query: { query: 'query_1' },
range,
panelsState: {
trace: {
spanId: 'abcdef',
},
},
});
});
it('returns correct link model for external link when user does not have access to explore', () => {
const { field, range } = setup(
{
title: 'external',
url: 'http://regionalhost',
},
false
);
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range });
expect(links[0].href).toBe('http://regionalhost');
expect(links[0].title).toBe('external');
});
it('returns no internal links if when user does not have access to explore', () => {
const { field, range } = setup(
{
title: '',
url: '',
internal: {
query: { query: 'query_1' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
},
false
);
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range });
expect(links).toHaveLength(0);
});
it('returns internal links when target contains __data template variables', () => {
const { field, range, dataFrame } = setup({
title: '',
url: '',
internal: {
query: { query: 'query_1-${__data.fields.flux-dimensions}' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
});
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range, dataFrame });
expect(links).toHaveLength(1);
expect(links[0].href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1-foo"}]}'
)}`
);
});
it('returns internal links when target contains targetField template variable', () => {
const { field, range, dataFrame } = setup({
title: '',
url: '',
internal: {
query: { query: 'query_1-${__targetField}' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
});
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range, dataFrame });
expect(links).toHaveLength(1);
expect(links[0].href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1-foo"}]}'
)}`
);
});
it('returns internal links when target contains field name template variable', () => {
// field cannot be hyphenated, change field name to non-hyphenated
const noHyphenLink = {
title: '',
url: '',
internal: {
query: { query: 'query_1-${fluxDimensions}' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
};
const { field, range, dataFrame } = setup(noHyphenLink, true, {
name: 'fluxDimensions',
type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]),
config: {
links: [noHyphenLink],
},
});
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range, dataFrame });
expect(links).toHaveLength(1);
expect(links[0].href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1-foo"}]}'
)}`
);
});
it('returns internal links when target contains other field name template variables', () => {
// field cannot be hyphenated, change field name to non-hyphenated
const noHyphenLink = {
title: '',
url: '',
internal: {
query: { query: 'query_1-${fluxDimensions}-${fluxDimension2}' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
};
const { field, range, dataFrame } = setup(
noHyphenLink,
true,
{
name: 'fluxDimensions',
type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]),
config: {
links: [noHyphenLink],
},
},
[
{
name: 'fluxDimension2',
type: FieldType.string,
values: new ArrayVector(['foo2', ROW_WITH_NULL_VALUE.value]),
config: {
links: [noHyphenLink],
},
},
]
);
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_TEXT_VALUE.index, range, dataFrame });
expect(links).toHaveLength(1);
expect(links[0].href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1-foo-foo2"}]}'
)}`
);
});
it('returns no internal links when target contains empty template variables', () => {
const { field, range, dataFrame } = setup({
title: '',
url: '',
internal: {
query: { query: 'query_1-${__data.fields.flux-dimensions}' },
datasourceUid: 'uid_1',
datasourceName: 'test_ds',
},
});
const links = getFieldLinksForExplore({ field, rowIndex: ROW_WITH_NULL_VALUE.index, range, dataFrame });
expect(links).toHaveLength(0);
});
});
const ROW_WITH_TEXT_VALUE = { value: 'foo', index: 0 };
const ROW_WITH_NULL_VALUE = { value: null, index: 1 };
function setup(
link: DataLink,
hasAccess = true,
fieldOverride?: Field<string | null>,
dataFrameOtherFieldOverride?: Field[]
) {
setLinkSrv({
getDataLinkUIModel(link: DataLink, replaceVariables: InterpolateFunction | undefined, origin) {
return {
href: link.url,
title: link.title,
target: '_blank',
origin: origin,
};
},
getAnchorInfo(link) {
return { ...link };
},
getLinkUrl(link) {
return link.url;
},
});
setContextSrv({
hasAccessToExplore: () => hasAccess,
} as ContextSrv);
const field: Field<string | null> = {
name: 'flux-dimensions',
type: FieldType.string,
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]),
config: {
links: [link],
},
};
let fieldsArr = [fieldOverride || field];
if (dataFrameOtherFieldOverride) {
fieldsArr = [...fieldsArr, ...dataFrameOtherFieldOverride];
}
const dataFrame: DataFrame = toDataFrame({
fields: fieldsArr,
});
const range: TimeRange = {
from: dateTime('2020-10-14T00:00:00'),
to: dateTime('2020-10-14T01:00:00'),
raw: {
from: 'now-1h',
to: 'now',
},
};
return { range, field: fieldOverride || field, dataFrame };
}