test(discussion): cover CommentMessage branches
Author + initials, comment body, edited label gated on updatedAt vs createdAt, edit-mode textarea, delete button gated on isOwn, onDelete callback wiring. 8 tests covering ~16 of CommentMessage's branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
import { page } from 'vitest/browser';
|
||||
import CommentMessage from './CommentMessage.svelte';
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
const baseMessage = (overrides: Record<string, unknown> = {}) => ({
|
||||
id: 'm1',
|
||||
authorId: 'u1',
|
||||
authorName: 'Anna Schmidt',
|
||||
content: 'Tolle Geschichte!',
|
||||
createdAt: '2026-04-15T10:00:00Z',
|
||||
updatedAt: '2026-04-15T10:00:00Z',
|
||||
mentionDTOs: [] as unknown[],
|
||||
...overrides
|
||||
});
|
||||
|
||||
const baseProps = (overrides: Record<string, unknown> = {}) => ({
|
||||
message: baseMessage(),
|
||||
isOwn: false,
|
||||
isEditing: false,
|
||||
editText: '',
|
||||
onEdit: () => {},
|
||||
onDelete: () => {},
|
||||
onEditTextChange: () => {},
|
||||
onEditKeydown: () => {},
|
||||
...overrides
|
||||
});
|
||||
|
||||
describe('CommentMessage', () => {
|
||||
it('renders the author name and avatar initials', async () => {
|
||||
render(CommentMessage, { props: baseProps() });
|
||||
|
||||
await expect.element(page.getByText('Anna Schmidt')).toBeVisible();
|
||||
await expect.element(page.getByText('AS')).toBeVisible();
|
||||
});
|
||||
|
||||
it('renders the comment body', async () => {
|
||||
render(CommentMessage, { props: baseProps() });
|
||||
|
||||
await expect.element(page.getByText('Tolle Geschichte!')).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows the edited label when updatedAt > createdAt', async () => {
|
||||
render(CommentMessage, {
|
||||
props: baseProps({
|
||||
message: baseMessage({
|
||||
createdAt: '2026-04-15T10:00:00Z',
|
||||
updatedAt: '2026-04-15T11:00:00Z'
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
await expect.element(page.getByText('(Bearbeitet)')).toBeVisible();
|
||||
});
|
||||
|
||||
it('hides the edited label when updatedAt equals createdAt', async () => {
|
||||
render(CommentMessage, { props: baseProps() });
|
||||
|
||||
await expect.element(page.getByText('(Bearbeitet)')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows the textarea when in edit mode', async () => {
|
||||
render(CommentMessage, {
|
||||
props: baseProps({ isOwn: true, isEditing: true, editText: 'Editing content' })
|
||||
});
|
||||
|
||||
const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
|
||||
expect(textarea.value).toBe('Editing content');
|
||||
});
|
||||
|
||||
it('shows the delete button only when isOwn is true', async () => {
|
||||
render(CommentMessage, { props: baseProps({ isOwn: true }) });
|
||||
|
||||
await expect.element(page.getByRole('button', { name: /löschen anna schmidt/i })).toBeVisible();
|
||||
});
|
||||
|
||||
it('hides the delete button when isOwn is false', async () => {
|
||||
render(CommentMessage, { props: baseProps() });
|
||||
|
||||
await expect.element(page.getByRole('button', { name: /löschen/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onDelete when the delete button is clicked', async () => {
|
||||
const onDelete = vi.fn();
|
||||
render(CommentMessage, { props: baseProps({ isOwn: true, onDelete }) });
|
||||
|
||||
await page.getByRole('button', { name: /löschen anna schmidt/i }).click();
|
||||
|
||||
expect(onDelete).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user