mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* 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
318 lines
9.0 KiB
TypeScript
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 };
|
|
}
|