import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import MarkdownContent from './MarkdownContent'; import rehypeExternalLinks from '../__mocks__/rehype-external-links'; const BOLD_TEXT = '**Bold text**'; const ITALIC_TEXT = '*Italic text*'; const INLINE_CODE = 'Here is inline code: `const x = 5`'; const CODE_BLOCK = `\`\`\`javascript function hello() { console.log('Hello, world!'); } \`\`\``; const HEADING = '# Heading 1'; const LINK = '[PatternFly](https://www.patternfly.org/)'; const UNORDERED_LIST = ` * Item 1 * Item 2 * Item 3 `; const ORDERED_LIST = ` 1. First item 2. Second item 3. Third item `; const TABLE = ` | Column 1 | Column 2 | |----------|----------| | Cell 1 | Cell 2 | | Cell 3 | Cell 4 | `; const BLOCKQUOTE = '> This is a blockquote'; const IMAGE = '![Alt text](https://example.com/image.png)'; describe('MarkdownContent', () => { beforeEach(() => { jest.clearAllMocks(); }); it('should render bold text correctly', () => { const { container } = render(); expect(container.querySelector('strong')).toBeTruthy(); expect(screen.getByText('Bold text')).toBeTruthy(); }); it('should render italic text correctly', () => { const { container } = render(); expect(container.querySelector('em')).toBeTruthy(); expect(screen.getByText('Italic text')).toBeTruthy(); }); it('should render inline code correctly', () => { render(); expect(screen.getByText(/const x = 5/)).toBeTruthy(); }); it('should render code blocks correctly', () => { render(); expect(screen.getByText(/function hello/)).toBeVisible(); expect(screen.getByText(/console.log/)).toBeVisible(); expect(screen.getByRole('button', { name: 'Copy code' })).toBeVisible(); }); it('should render headings correctly', () => { render(); expect(screen.getByRole('heading', { name: /Heading 1/i })).toBeTruthy(); }); it('should render links correctly', () => { render(); expect(screen.getByRole('link', { name: /PatternFly/i })).toBeTruthy(); }); it('should render unordered lists correctly', () => { render(); expect(screen.getByText('Item 1')).toBeTruthy(); expect(screen.getByText('Item 2')).toBeTruthy(); expect(screen.getByText('Item 3')).toBeTruthy(); expect(screen.getAllByRole('listitem')).toHaveLength(3); }); it('should render ordered lists correctly', () => { render(); expect(screen.getByText('First item')).toBeTruthy(); expect(screen.getByText('Second item')).toBeTruthy(); expect(screen.getByText('Third item')).toBeTruthy(); expect(screen.getAllByRole('listitem')).toHaveLength(3); }); it('should render tables correctly', () => { render(); expect(screen.getByRole('grid', { name: /Test table/i })).toBeTruthy(); expect(screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy(); expect(screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy(); expect(screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy(); expect(screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy(); }); it('should render blockquotes correctly', () => { render(); const quote = screen.getByText(/This is a blockquote/); expect(quote).toBeVisible(); expect(quote.closest('.pf-v6-c-content--blockquote')?.tagName).toBe('BLOCKQUOTE'); }); it('should render images when hasNoImages is false', () => { render(); expect(screen.getByRole('img', { name: /Alt text/i })).toBeTruthy(); }); it('should not render images when hasNoImages is true', () => { render(); expect(screen.queryByRole('img', { name: /Alt text/i })).toBeFalsy(); }); it('should disable markdown rendering when isMarkdownDisabled is true', () => { render(); expect(screen.getByText('**Bold text**')).toBeTruthy(); }); it('should render text component when isMarkdownDisabled is true and textComponent is provided', () => { const textComponent =
Custom text component
; render(); expect(screen.getByTestId('custom-text')).toBeTruthy(); expect(screen.getByText('Custom text component')).toBeTruthy(); }); it('should apply isPrimary prop to elements', () => { const { container } = render(); expect(container.querySelector('.pf-m-primary')).toBeTruthy(); }); it('should apply shouldRetainStyles prop to elements', () => { const { container } = render(); expect(container.querySelector('.pf-m-markdown')).toBeTruthy(); }); it('should pass codeBlockProps to code blocks', () => { render(); expect(screen.getByRole('button', { name: /Custom code block/i })).toBeTruthy(); }); it('should pass tableProps to tables', () => { render(); expect(screen.getByRole('grid', { name: /Custom table label/i })).toBeTruthy(); }); it('should open links in new tab when openLinkInNewTab is true', () => { render(); expect(rehypeExternalLinks).toHaveBeenCalledTimes(1); }); it('should not open links in new tab when openLinkInNewTab is false', () => { render(); expect(rehypeExternalLinks).not.toHaveBeenCalled(); }); it('should pass linkProps to links', async () => { const onClick = jest.fn(); render(); const link = screen.getByRole('link', { name: /PatternFly/i }); link.click(); expect(onClick).toHaveBeenCalledTimes(1); }); it('should handle reactMarkdownProps.disallowedElements', () => { render(); // Code block should not render when disallowed expect(screen.queryByRole('button', { name: /Copy code/i })).toBeFalsy(); }); it('should render plain text when no markdown is present', () => { render(); expect(screen.getByText('Plain text without markdown')).toBeTruthy(); }); it('should handle empty content', () => { const { container } = render(); expect(container.textContent).toBe(''); }); it('should handle undefined content', () => { const { container } = render(); expect(container.textContent).toBe(''); }); it('should render multiple markdown elements together', () => { const content = `# Heading **Bold text** and *italic text* \`\`\`javascript const x = 5; \`\`\` [Link](https://example.com)`; render(); expect(screen.getByRole('heading', { name: /Heading/i })).toBeTruthy(); expect(screen.getByText('Bold text')).toBeTruthy(); expect(screen.getByText('italic text')).toBeTruthy(); expect(screen.getByText(/const x = 5/)).toBeTruthy(); expect(screen.getByRole('link', { name: /Link/i })).toBeTruthy(); }); });