|
|
|
@ -16,578 +16,470 @@ import { initTemplateSrv } from '../../../../test/helpers/initTemplateSrv'; |
|
|
|
|
import { ContextSrv, setContextSrv } from '../../../core/services/context_srv'; |
|
|
|
|
import { setLinkSrv } from '../../panel/panellinks/link_srv'; |
|
|
|
|
|
|
|
|
|
import { getFieldLinksForExplore, getVariableUsageInfo } from './links'; |
|
|
|
|
|
|
|
|
|
describe('explore links utils', () => { |
|
|
|
|
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' } }, |
|
|
|
|
]) |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
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 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, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
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'); |
|
|
|
|
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, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
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', |
|
|
|
|
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' }, |
|
|
|
|
range, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
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', |
|
|
|
|
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', |
|
|
|
|
}, |
|
|
|
|
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 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 internal links when target contains __data template variables', () => { |
|
|
|
|
const { field, range, dataFrame } = setup({ |
|
|
|
|
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-${__data.fields.flux-dimensions}' }, |
|
|
|
|
query: { query: 'query_1' }, |
|
|
|
|
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"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}, |
|
|
|
|
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 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, { |
|
|
|
|
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], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
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', |
|
|
|
|
name: 'fluxDimension2', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector([ROW_WITH_TEXT_VALUE.value, ROW_WITH_NULL_VALUE.value]), |
|
|
|
|
values: new ArrayVector(['foo2', 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"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
] |
|
|
|
|
); |
|
|
|
|
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 internal links with logfmt and regex transformation', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} env=${environment}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ type: SupportedTransformationTypes.Logfmt }, |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'host=(dev|prod)', mapValue: 'environment' }, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=foo host=dev-001', 'application=bar host=prod-003']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with logfmt and regex transformation', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} env=${environment}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ type: SupportedTransformationTypes.Logfmt }, |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'host=(dev|prod)', mapValue: 'environment' }, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=foo env=dev}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=bar env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=foo host=dev-001', 'application=bar host=prod-003']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=foo env=dev}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=bar env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
it('returns internal links with 2 unnamed regex transformations and use the last transformation', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{env=${msg}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'fieldA=(asparagus|broccoli)' }, |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'fieldB=(apple|banana)' }, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['fieldA=asparagus fieldB=banana', 'fieldA=broccoli fieldB=apple']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with 2 unnamed regex transformations and use the last transformation', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{env=${msg}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'fieldA=(asparagus|broccoli)' }, |
|
|
|
|
{ type: SupportedTransformationTypes.Regex, expression: 'fieldB=(apple|banana)' }, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{env=banana}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{env=apple}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['fieldA=asparagus fieldB=banana', 'fieldA=broccoli fieldB=apple']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{env=banana}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{env=apple}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
it('returns internal links with logfmt with stringified booleans', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} isOnline=${online}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [{ type: SupportedTransformationTypes.Logfmt }], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=foo online=true', 'application=bar online=false']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with logfmt with stringified booleans', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} isOnline=${online}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [{ type: SupportedTransformationTypes.Logfmt }], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=foo isOnline=true}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=bar isOnline=false}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
it('returns internal links with logfmt with correct data on transformation-defined field', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [{ type: SupportedTransformationTypes.Logfmt, field: 'fieldNamedInTransformation' }], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// fieldWithLink has the transformation, but the transformation has defined fieldNamedInTransformation as its field to transform
|
|
|
|
|
const { field, range, dataFrame } = setup( |
|
|
|
|
transformationLink, |
|
|
|
|
true, |
|
|
|
|
{ |
|
|
|
|
name: 'fieldWithLink', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=foo online=true', 'application=bar online=false']), |
|
|
|
|
values: new ArrayVector(['application=link', 'application=link2']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=foo isOnline=true}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=bar isOnline=false}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with logfmt with correct data on transformation-defined field', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [{ type: SupportedTransformationTypes.Logfmt, field: 'fieldNamedInTransformation' }], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// fieldWithLink has the transformation, but the transformation has defined fieldNamedInTransformation as its field to transform
|
|
|
|
|
const { field, range, dataFrame } = setup( |
|
|
|
|
transformationLink, |
|
|
|
|
true, |
|
|
|
|
}, |
|
|
|
|
[ |
|
|
|
|
{ |
|
|
|
|
name: 'fieldWithLink', |
|
|
|
|
name: 'fieldNamedInTransformation', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=link', 'application=link2']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
values: new ArrayVector(['application=transform', 'application=transform2']), |
|
|
|
|
config: {}, |
|
|
|
|
}, |
|
|
|
|
[ |
|
|
|
|
] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=transform}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=transform2}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with regex named capture groups', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} env=${environment}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ |
|
|
|
|
name: 'fieldNamedInTransformation', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=transform', 'application=transform2']), |
|
|
|
|
config: {}, |
|
|
|
|
type: SupportedTransformationTypes.Regex, |
|
|
|
|
expression: '(?=.*(?<application>(grafana|loki)))(?=.*(?<environment>(dev|prod)))', |
|
|
|
|
}, |
|
|
|
|
] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=transform}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=transform2}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns internal links with regex named capture groups', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} env=${environment}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [ |
|
|
|
|
{ |
|
|
|
|
type: SupportedTransformationTypes.Regex, |
|
|
|
|
expression: '(?=.*(?<application>(grafana|loki)))(?=.*(?<environment>(dev|prod)))', |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['foo loki prod', 'dev bar grafana', 'prod grafana foo']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 2, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=loki env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=grafana env=dev}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
expect(links[2]).toHaveLength(1); |
|
|
|
|
expect(links[2][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=grafana env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
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 { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['foo loki prod', 'dev bar grafana', 'prod grafana foo']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('does not return internal links when not all query variables are matched', () => { |
|
|
|
|
const transformationLink: DataLink = { |
|
|
|
|
title: '', |
|
|
|
|
url: '', |
|
|
|
|
internal: { |
|
|
|
|
query: { query: 'http_requests{app=${application} env=${diffVar}}' }, |
|
|
|
|
datasourceUid: 'uid_1', |
|
|
|
|
datasourceName: 'test_ds', |
|
|
|
|
transformations: [{ type: SupportedTransformationTypes.Logfmt }], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { field, range, dataFrame } = setup(transformationLink, true, { |
|
|
|
|
name: 'msg', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: new ArrayVector(['application=foo host=dev-001']), |
|
|
|
|
config: { |
|
|
|
|
links: [transformationLink], |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const links = [getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame })]; |
|
|
|
|
expect(links[0]).toHaveLength(0); |
|
|
|
|
}); |
|
|
|
|
const links = [ |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 0, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 1, range, dataFrame }), |
|
|
|
|
getFieldLinksForExplore({ field, rowIndex: 2, range, dataFrame }), |
|
|
|
|
]; |
|
|
|
|
expect(links[0]).toHaveLength(1); |
|
|
|
|
expect(links[0][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=loki env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
expect(links[1]).toHaveLength(1); |
|
|
|
|
expect(links[1][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=grafana env=dev}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
expect(links[2]).toHaveLength(1); |
|
|
|
|
expect(links[2][0].href).toBe( |
|
|
|
|
`/explore?left=${encodeURIComponent( |
|
|
|
|
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"http_requests{app=grafana env=prod}"}]}' |
|
|
|
|
)}` |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
describe('getVariableUsageInfo', () => { |
|
|
|
|
it('returns true when query contains variables and all variables are used', () => { |
|
|
|
|
const dataLink = { |
|
|
|
|
url: '', |
|
|
|
|
title: '', |
|
|
|
|
internal: { |
|
|
|
|
datasourceUid: 'uid', |
|
|
|
|
datasourceName: 'dsName', |
|
|
|
|
query: { query: 'test ${testVal}' }, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const scopedVars = { |
|
|
|
|
testVal: { text: '', value: 'val1' }, |
|
|
|
|
}; |
|
|
|
|
const varMapMock = jest.fn().mockReturnValue({ testVal: scopedVars.testVal.value }); |
|
|
|
|
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars, varMapMock).allVariablesDefined; |
|
|
|
|
|
|
|
|
|
expect(dataLinkRtnVal).toBe(true); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns false when query contains variables and no variables are used', () => { |
|
|
|
|
const dataLink = { |
|
|
|
|
url: '', |
|
|
|
|
title: '', |
|
|
|
|
internal: { |
|
|
|
|
datasourceUid: 'uid', |
|
|
|
|
datasourceName: 'dsName', |
|
|
|
|
query: { query: 'test ${diffVar}' }, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const scopedVars = { |
|
|
|
|
testVal: { text: '', value: 'val1' }, |
|
|
|
|
}; |
|
|
|
|
const varMapMock = jest.fn().mockReturnValue({ diffVar: null }); |
|
|
|
|
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars, varMapMock).allVariablesDefined; |
|
|
|
|
|
|
|
|
|
expect(dataLinkRtnVal).toBe(false); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns false when query contains variables and some variables are used', () => { |
|
|
|
|
const dataLink = { |
|
|
|
|
url: '', |
|
|
|
|
title: '', |
|
|
|
|
internal: { |
|
|
|
|
datasourceUid: 'uid', |
|
|
|
|
datasourceName: 'dsName', |
|
|
|
|
query: { query: 'test ${testVal} ${diffVar}' }, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const scopedVars = { |
|
|
|
|
testVal: { text: '', value: 'val1' }, |
|
|
|
|
}; |
|
|
|
|
const varMapMock = jest.fn().mockReturnValue({ testVal: 'val1', diffVar: null }); |
|
|
|
|
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars, varMapMock).allVariablesDefined; |
|
|
|
|
expect(dataLinkRtnVal).toBe(false); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('returns true when query contains no variables', () => { |
|
|
|
|
const dataLink = { |
|
|
|
|
url: '', |
|
|
|
|
title: '', |
|
|
|
|
internal: { |
|
|
|
|
datasourceUid: 'uid', |
|
|
|
|
datasourceName: 'dsName', |
|
|
|
|
query: { query: 'test' }, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
const scopedVars = { |
|
|
|
|
testVal: { text: '', value: 'val1' }, |
|
|
|
|
}; |
|
|
|
|
const varMapMock = jest.fn().mockReturnValue({}); |
|
|
|
|
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars, varMapMock).allVariablesDefined; |
|
|
|
|
expect(dataLinkRtnVal).toBe(true); |
|
|
|
|
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); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|