test(coverage): drive browser tests to 80% on all metrics (#496) #505

Merged
marcel merged 189 commits from feat/issue-496-browser-coverage-tests into main 2026-05-11 21:50:39 +02:00
Showing only changes of commit 14993db1f0 - Show all commits

View File

@@ -232,4 +232,81 @@ describe('CommentThread', () => {
const calls = fetchSpy.mock.calls.map((c) => c[0].toString());
expect(calls.some((c) => c.endsWith('/api/documents/doc-X/comments'))).toBe(true);
});
it('does not call onCountChange when loadOnMount=true (initial render path)', async () => {
const onCountChange = vi.fn();
// Mock the reload fetch to return one comment so onCountChange fires from reload, not from mount-effect
fetchSpy.mockResolvedValueOnce(
new Response(
JSON.stringify([
{
id: 'c-1',
documentId: 'doc-1',
content: 'Loaded',
authorId: 'u-1',
authorName: 'Anna',
createdAt: '2026-01-01T00:00:00Z',
updatedAt: null,
replies: []
}
]),
{ status: 200, headers: { 'Content-Type': 'application/json' } }
)
);
render(CommentThread, {
props: {
documentId: 'doc-1',
canComment: false,
currentUserId: null,
initialComments: [],
loadOnMount: true,
onCountChange
}
});
await new Promise((r) => setTimeout(r, 50));
expect(onCountChange).toHaveBeenCalledWith(1);
});
it('treats currentUserId=null as never owning a comment', async () => {
render(CommentThread, {
props: {
documentId: 'doc-1',
canComment: true,
currentUserId: null,
initialComments: [baseComment({ id: 'c-1', authorId: 'u-1' })]
}
});
await new Promise((r) => setTimeout(r, 30));
// No edit/delete buttons because none is "own"
const editBtns = Array.from(document.querySelectorAll('button')).filter((b) =>
/bearbeiten/i.test(b.textContent ?? '')
);
expect(editBtns.length).toBe(0);
});
it('flat-messages flattens replies', async () => {
render(CommentThread, {
props: {
documentId: 'doc-1',
canComment: false,
currentUserId: null,
initialComments: [
{
...baseComment({ id: 'c-1', content: 'Top' }),
replies: [
baseComment({ id: 'r-1', content: 'Reply 1' }),
baseComment({ id: 'r-2', content: 'Reply 2' })
]
} as Comment
]
}
});
expect(document.body.textContent).toContain('Top');
expect(document.body.textContent).toContain('Reply 1');
expect(document.body.textContent).toContain('Reply 2');
});
});