diff --git a/public/app/plugins/panel/text/TextPanel.test.tsx b/public/app/plugins/panel/text/TextPanel.test.tsx index 4e2967f7b9d..ccebf02f1bc 100644 --- a/public/app/plugins/panel/text/TextPanel.test.tsx +++ b/public/app/plugins/panel/text/TextPanel.test.tsx @@ -104,6 +104,43 @@ describe('TextPanel', () => { expect(waited.innerHTML).toEqual('
We begin by a simple sentence.\ncode block
hello
\n'); + }); + + // Tests https://github.com/grafana/grafana/issues/49759 explicitly + it('interpolates variables correctly so they can be used in markdown urls', async () => { + const contentTest = '[Example: ${__url_time_range}](https://example.com/?${__url_time_range})'; + replaceVariablesMock.mockImplementationOnce((str) => { + return str.replace(/\${__url_time_range}/g, 'from=now-6h&to=now'); + }); + + const props = Object.assign({}, defaultProps, { + options: { content: contentTest, mode: TextMode.Markdown }, + }); + + setup(props); + + const waited = await screen.getByTestId('TextPanel-converted-content'); + // Yes, ampersands in query string in href attribute should be encoded + // https://stackoverflow.com/questions/3705591/do-i-encode-ampersands-in-a-href + expect(waited.innerHTML).toEqual( + '\n' + ); + }); + it('converts content to html when in html mode', () => { const contentTest = 'We begin by a simple sentence.\n```This is a code block\n```'; replaceVariablesMock.mockReturnValueOnce(contentTest); diff --git a/public/app/plugins/panel/text/TextPanel.tsx b/public/app/plugins/panel/text/TextPanel.tsx index 6f34aed6190..3252c3fb718 100644 --- a/public/app/plugins/panel/text/TextPanel.tsx +++ b/public/app/plugins/panel/text/TextPanel.tsx @@ -67,6 +67,8 @@ function processContent(options: Options, interpolate: InterpolateFunction, disa return ''; } + // Variables must be interpolated before content is converted to markdown so using variables + // in URLs work properly content = interpolate(content, {}, options.code?.language === 'json' ? 'json' : 'html'); switch (mode) {