feat: add comments feature with nested replies and recursive rendering
All checks were successful
ci/woodpecker/pr/pipeline Pipeline was successful
All checks were successful
ci/woodpecker/pr/pipeline Pipeline was successful
Implement full comments system: domain entities (Comment, CommentLike), value objects (CommentContent), use cases (CRUD, like toggle), SQLAlchemy repository, API v1 endpoints, web UI with comment form and nested replies, i18n translations (EN/RU/FR/DE), and E2E tests. Fix nested reply (reply-to-reply) not displaying — the flat reply_comments dict was only queried for top-level comment IDs, so deeply nested replies were saved to DB (incrementing comment count) but never rendered. Switch to a recursive Jinja2 macro that renders any nesting depth.
This commit is contained in:
98
tests/unit/domain/test_comment_entity.py
Normal file
98
tests/unit/domain/test_comment_entity.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""Tests for Comment domain entity.
|
||||
|
||||
This module tests the Comment entity creation, parent_id support,
|
||||
and BaseEntity integration.
|
||||
"""
|
||||
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from app.domain.entities.comment import Comment
|
||||
from app.domain.value_objects.comment_content import CommentContent
|
||||
|
||||
|
||||
class TestCommentEntity:
|
||||
"""Tests for the Comment domain entity.
|
||||
|
||||
Covers TC-UNIT-829 and TC-UNIT-830.
|
||||
"""
|
||||
|
||||
def test_comment_creation(self) -> None:
|
||||
"""Test creating a top-level Comment with valid attributes.
|
||||
|
||||
TC-UNIT-829: Positive — create Comment instance.
|
||||
|
||||
Expected:
|
||||
- post_id matches input
|
||||
- author_id matches input
|
||||
- content is CommentContent with correct value
|
||||
- id is a valid UUID
|
||||
- parent_id is None
|
||||
- like_count is 0
|
||||
- created_at is set
|
||||
"""
|
||||
post_id = UUID("00000000-0000-0000-0000-000000000001")
|
||||
author_id = "user-123"
|
||||
content_text = "This is a comment with **Markdown** support."
|
||||
|
||||
comment = Comment.create(
|
||||
post_id=post_id,
|
||||
author_id=author_id,
|
||||
content_str=content_text,
|
||||
)
|
||||
|
||||
assert comment.post_id == post_id
|
||||
assert comment.author_id == author_id
|
||||
assert isinstance(comment.content, CommentContent)
|
||||
assert comment.content.value == content_text
|
||||
assert isinstance(comment.id, UUID)
|
||||
assert comment.parent_id is None
|
||||
assert comment.like_count == 0
|
||||
assert comment.created_at is not None
|
||||
|
||||
def test_comment_with_parent(self) -> None:
|
||||
"""Test creating a reply Comment with parent_id.
|
||||
|
||||
TC-UNIT-830: Positive — create Comment with parent_id.
|
||||
|
||||
Expected:
|
||||
- parent_id matches the provided parent comment ID.
|
||||
- All other attributes set correctly.
|
||||
"""
|
||||
post_id = UUID("00000000-0000-0000-0000-000000000001")
|
||||
parent_id = uuid4()
|
||||
author_id = "user-456"
|
||||
content_text = "This is a reply to another comment."
|
||||
|
||||
comment = Comment.create(
|
||||
post_id=post_id,
|
||||
author_id=author_id,
|
||||
content_str=content_text,
|
||||
parent_id=parent_id,
|
||||
)
|
||||
|
||||
assert comment.parent_id == parent_id
|
||||
assert comment.post_id == post_id
|
||||
assert comment.author_id == author_id
|
||||
assert comment.content.value == content_text
|
||||
assert comment.like_count == 0
|
||||
|
||||
def test_comment_to_dict(self) -> None:
|
||||
"""Test Comment to_dict serialization."""
|
||||
post_id = UUID("00000000-0000-0000-0000-000000000001")
|
||||
author_id = "user-123"
|
||||
content_text = "Comment with serialization test."
|
||||
|
||||
comment = Comment.create(
|
||||
post_id=post_id,
|
||||
author_id=author_id,
|
||||
content_str=content_text,
|
||||
)
|
||||
data = comment.to_dict()
|
||||
|
||||
assert data["post_id"] == str(post_id)
|
||||
assert data["author_id"] == author_id
|
||||
assert data["content"] == content_text
|
||||
assert "id" in data
|
||||
assert "created_at" in data
|
||||
assert data["parent_id"] is None
|
||||
assert data["like_count"] == 0
|
||||
Reference in New Issue
Block a user