diff --git a/frontend/src/lib/shared/discussion/CommentThread.svelte.test.ts b/frontend/src/lib/shared/discussion/CommentThread.svelte.test.ts index 6fbb6293..76862419 100644 --- a/frontend/src/lib/shared/discussion/CommentThread.svelte.test.ts +++ b/frontend/src/lib/shared/discussion/CommentThread.svelte.test.ts @@ -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'); + }); });