mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 17:15:40 -06:00
Chore: Test grafana/public/app/plugins/panel/text/TextPanel.tsx
(#52244)
* move sanitize test to its own test file * add a test for renderTextPanelMarkdown to always sanitize * setup TextPanel tests * add tests to always sanitize Text Panel contents and always convert correctly to html/markdown
This commit is contained in:
parent
13b23fd512
commit
bec500b69f
@ -1,5 +1,4 @@
|
|||||||
import { renderMarkdown } from './markdown';
|
import { renderMarkdown, renderTextPanelMarkdown } from './markdown';
|
||||||
import { sanitizeTextPanelContent } from './sanitize';
|
|
||||||
|
|
||||||
describe('Markdown wrapper', () => {
|
describe('Markdown wrapper', () => {
|
||||||
it('should be able to handle undefined value', () => {
|
it('should be able to handle undefined value', () => {
|
||||||
@ -12,12 +11,8 @@ describe('Markdown wrapper', () => {
|
|||||||
expect(str).toBe('<script>alert()</script>');
|
expect(str).toBe('<script>alert()</script>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow whitelisted styles in text panel', () => {
|
it('should sanitize content in text panel by default', () => {
|
||||||
const html =
|
const str = renderTextPanelMarkdown('<script>alert()</script>');
|
||||||
'<div style="display:flex; flex-direction: column; flex-wrap: wrap; justify-content: start; gap: 2px;"><div style="flex-basis: 50%"></div></div>';
|
expect(str).toBe('<script>alert()</script>');
|
||||||
const str = sanitizeTextPanelContent(html);
|
|
||||||
expect(str).toBe(
|
|
||||||
'<div style="display:flex; flex-direction:column; flex-wrap:wrap; justify-content:start; gap:2px;"><div style="flex-basis:50%;"></div></div>'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
12
packages/grafana-data/src/text/sanitize.test.ts
Normal file
12
packages/grafana-data/src/text/sanitize.test.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { sanitizeTextPanelContent } from './sanitize';
|
||||||
|
|
||||||
|
describe('Sanitize wrapper', () => {
|
||||||
|
it('should allow whitelisted styles in text panel', () => {
|
||||||
|
const html =
|
||||||
|
'<div style="display:flex; flex-direction: column; flex-wrap: wrap; justify-content: start; gap: 2px;"><div style="flex-basis: 50%"></div></div>';
|
||||||
|
const str = sanitizeTextPanelContent(html);
|
||||||
|
expect(str).toBe(
|
||||||
|
'<div style="display:flex; flex-direction:column; flex-wrap:wrap; justify-content:start; gap:2px;"><div style="flex-basis:50%;"></div></div>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
120
public/app/plugins/panel/text/TextPanel.test.tsx
Normal file
120
public/app/plugins/panel/text/TextPanel.test.tsx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { dateTime, LoadingState, EventBusSrv } from '@grafana/data';
|
||||||
|
|
||||||
|
import { Props, TextPanel } from './TextPanel';
|
||||||
|
import { TextMode } from './models.gen';
|
||||||
|
|
||||||
|
const replaceVariablesMock = jest.fn();
|
||||||
|
const defaultProps: Props = {
|
||||||
|
id: 1,
|
||||||
|
data: {
|
||||||
|
state: LoadingState.Done,
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
fields: [],
|
||||||
|
length: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timeRange: {
|
||||||
|
from: dateTime('2022-01-01T15:55:00Z'),
|
||||||
|
to: dateTime('2022-07-12T15:55:00Z'),
|
||||||
|
raw: {
|
||||||
|
from: 'now-15m',
|
||||||
|
to: 'now',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
timeRange: {
|
||||||
|
from: dateTime('2022-07-11T15:55:00Z'),
|
||||||
|
to: dateTime('2022-07-12T15:55:00Z'),
|
||||||
|
raw: {
|
||||||
|
from: 'now-15m',
|
||||||
|
to: 'now',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
timeZone: 'utc',
|
||||||
|
transparent: false,
|
||||||
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
fieldConfig: {
|
||||||
|
defaults: {},
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
|
renderCounter: 1,
|
||||||
|
title: 'Test Text Panel',
|
||||||
|
eventBus: new EventBusSrv(),
|
||||||
|
options: { content: '', mode: TextMode.Markdown },
|
||||||
|
onOptionsChange: jest.fn(),
|
||||||
|
onFieldConfigChange: jest.fn(),
|
||||||
|
replaceVariables: replaceVariablesMock,
|
||||||
|
onChangeTimeRange: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const setup = (props: Props = defaultProps) => {
|
||||||
|
render(<TextPanel {...props} />);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('TextPanel', () => {
|
||||||
|
it('should render panel without content', () => {
|
||||||
|
expect(() => setup()).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sanitizes content in html mode', () => {
|
||||||
|
const contentTest = '<form><p>Form tags are sanitized.</p></form>\n<script>Script tags are sanitized.</script>';
|
||||||
|
replaceVariablesMock.mockReturnValueOnce(contentTest);
|
||||||
|
const props = Object.assign({}, defaultProps, {
|
||||||
|
options: { content: contentTest, mode: TextMode.HTML },
|
||||||
|
});
|
||||||
|
|
||||||
|
setup(props);
|
||||||
|
|
||||||
|
expect(screen.getByTestId('TextPanel-converted-content').innerHTML).toEqual(
|
||||||
|
'<form><p>Form tags are sanitized.</p></form>\n<script>Script tags are sanitized.</script>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sanitizes content in markdown mode', () => {
|
||||||
|
const contentTest = '<form><p>Form tags are sanitized.</p></form>\n<script>Script tags are sanitized.</script>';
|
||||||
|
replaceVariablesMock.mockReturnValueOnce(contentTest);
|
||||||
|
|
||||||
|
const props = Object.assign({}, defaultProps, {
|
||||||
|
options: { content: contentTest, mode: TextMode.Markdown },
|
||||||
|
});
|
||||||
|
|
||||||
|
setup(props);
|
||||||
|
|
||||||
|
expect(screen.getByTestId('TextPanel-converted-content').innerHTML).toEqual(
|
||||||
|
'<form><p>Form tags are sanitized.</p></form>\n<script>Script tags are sanitized.</script>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts content to markdown when in markdown mode', async () => {
|
||||||
|
const contentTest = 'We begin by a simple sentence.\n```code block```';
|
||||||
|
replaceVariablesMock.mockReturnValueOnce(contentTest);
|
||||||
|
|
||||||
|
const props = Object.assign({}, defaultProps, {
|
||||||
|
options: { content: contentTest, mode: TextMode.Markdown },
|
||||||
|
});
|
||||||
|
|
||||||
|
setup(props);
|
||||||
|
|
||||||
|
const waited = await screen.getByTestId('TextPanel-converted-content');
|
||||||
|
expect(waited.innerHTML).toEqual('<p>We begin by a simple sentence.\n<code>code block</code></p>\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);
|
||||||
|
const props = Object.assign({}, defaultProps, {
|
||||||
|
options: { content: contentTest, mode: TextMode.HTML },
|
||||||
|
});
|
||||||
|
|
||||||
|
setup(props);
|
||||||
|
|
||||||
|
expect(screen.getByTestId('TextPanel-converted-content').innerHTML).toEqual(
|
||||||
|
'We begin by a simple sentence.\n```This is a code block\n```'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -12,7 +12,7 @@ import config from 'app/core/config';
|
|||||||
// Types
|
// Types
|
||||||
import { PanelOptions, TextMode } from './models.gen';
|
import { PanelOptions, TextMode } from './models.gen';
|
||||||
|
|
||||||
interface Props extends PanelProps<PanelOptions> {}
|
export interface Props extends PanelProps<PanelOptions> {}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
html: string;
|
html: string;
|
||||||
@ -90,7 +90,11 @@ export class TextPanel extends PureComponent<Props, State> {
|
|||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
return (
|
return (
|
||||||
<CustomScrollbar autoHeightMin="100%">
|
<CustomScrollbar autoHeightMin="100%">
|
||||||
<DangerouslySetHtmlContent html={html} className={cx('markdown-html', styles.content)} />
|
<DangerouslySetHtmlContent
|
||||||
|
html={html}
|
||||||
|
className={cx('markdown-html', styles.content)}
|
||||||
|
data-testid="TextPanel-converted-content"
|
||||||
|
/>
|
||||||
</CustomScrollbar>
|
</CustomScrollbar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user