tududi/frontend/components/Shared/__tests__/MarkdownRenderer.checkbox.test.tsx
Chris c753331874
Fix/note checkboxes (#486)
* Add checkboxes and make them clickable

* fixup! Add checkboxes and make them clickable
2025-11-05 16:09:51 +02:00

156 lines
5.2 KiB
TypeScript

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import MarkdownRenderer from '../MarkdownRenderer';
// Mock react-markdown and its plugins
jest.mock('react-markdown', () => {
return function ReactMarkdown({ children, components }: any) {
const content = children as string;
const lines = content.split('\n');
return (
<div className="markdown-content">
<ul>
{lines.map((line: string, idx: number) => {
const match = line.match(/^(\s*)-\s*\[([ xX])\](.*)$/);
if (match) {
const checked = match[2].toLowerCase() === 'x';
const text = match[3].trim();
const InputComponent = components?.input || 'input';
return (
<li key={idx}>
<InputComponent
type="checkbox"
checked={checked}
/>
{text}
</li>
);
}
return <li key={idx}>{line}</li>;
})}
</ul>
</div>
);
};
});
jest.mock('remark-gfm', () => ({}));
jest.mock('rehype-highlight', () => ({}));
jest.mock('highlight.js', () => ({
configure: jest.fn(),
highlightElement: jest.fn(),
}));
describe('MarkdownRenderer - Checkbox Functionality', () => {
it('renders checkboxes for task list items', () => {
const content = '- [ ] Task one\n- [x] Task two';
render(<MarkdownRenderer content={content} />);
const checkboxes = screen.getAllByRole('checkbox');
expect(checkboxes).toHaveLength(2);
expect(checkboxes[0]).not.toBeChecked();
expect(checkboxes[1]).toBeChecked();
});
it('renders nested checkboxes with proper indentation', () => {
const content =
'- [ ] Parent task\n - [ ] Nested task\n - [ ] Deep nested task';
render(<MarkdownRenderer content={content} />);
const checkboxes = screen.getAllByRole('checkbox');
expect(checkboxes).toHaveLength(3);
});
it('disables checkboxes when onContentChange is not provided', () => {
const content = '- [ ] Task one';
render(<MarkdownRenderer content={content} />);
const checkbox = screen.getByRole('checkbox');
expect(checkbox).toBeDisabled();
});
it('enables checkboxes when onContentChange callback is provided', () => {
const content = '- [ ] Task one';
const mockOnContentChange = jest.fn();
render(
<MarkdownRenderer
content={content}
onContentChange={mockOnContentChange}
/>
);
const checkbox = screen.getByRole('checkbox');
expect(checkbox).not.toBeDisabled();
});
it('toggles checkbox state when clicked', () => {
const content = '- [ ] Task one';
const mockOnContentChange = jest.fn();
render(
<MarkdownRenderer
content={content}
onContentChange={mockOnContentChange}
/>
);
const checkbox = screen.getByRole('checkbox');
fireEvent.click(checkbox);
expect(mockOnContentChange).toHaveBeenCalledTimes(1);
expect(mockOnContentChange).toHaveBeenCalledWith('- [x] Task one');
});
it('toggles checked checkbox to unchecked', () => {
const content = '- [x] Task one';
const mockOnContentChange = jest.fn();
render(
<MarkdownRenderer
content={content}
onContentChange={mockOnContentChange}
/>
);
const checkbox = screen.getByRole('checkbox');
fireEvent.click(checkbox);
expect(mockOnContentChange).toHaveBeenCalledWith('- [ ] Task one');
});
it('toggles the correct checkbox in a list', () => {
const content = '- [ ] Task one\n- [ ] Task two\n- [ ] Task three';
const mockOnContentChange = jest.fn();
render(
<MarkdownRenderer
content={content}
onContentChange={mockOnContentChange}
/>
);
const checkboxes = screen.getAllByRole('checkbox');
fireEvent.click(checkboxes[1]); // Click second checkbox
expect(mockOnContentChange).toHaveBeenCalledWith(
'- [ ] Task one\n- [x] Task two\n- [ ] Task three'
);
});
it('preserves indentation when toggling nested checkboxes', () => {
const content = '- [ ] Parent\n - [ ] Nested';
const mockOnContentChange = jest.fn();
render(
<MarkdownRenderer
content={content}
onContentChange={mockOnContentChange}
/>
);
const checkboxes = screen.getAllByRole('checkbox');
fireEvent.click(checkboxes[1]); // Click nested checkbox
expect(mockOnContentChange).toHaveBeenCalledWith(
'- [ ] Parent\n - [x] Nested'
);
});
});