"""Tests for CreateCommentUseCase. This module tests comment creation use case covering top-level comments, replies to existing comments, and post-not-found scenarios. """ from unittest.mock import AsyncMock, Mock from uuid import uuid4 import pytest from app.application.use_cases.create_comment import CreateCommentUseCase from app.domain.entities import Post from app.domain.exceptions import NotFoundException @pytest.fixture def test_post() -> Post: """Create a test post for comment tests.""" return Post.create( title_str="Commentable Post", content_str="This post will receive comments. Enough length here.", author_id="user-123", tags=["test"], ) class TestCreateCommentUseCase: """Tests for CreateCommentUseCase. Covers TC-UNIT-832 through TC-UNIT-834. """ @pytest.mark.asyncio async def test_create_comment_on_post( self, mock_post_repository: Mock, mock_transaction_manager: Mock, test_post: Post, ) -> None: """Test creating a top-level comment on a post. TC-UNIT-832: Positive — create top-level comment. """ mock_comment_repository = AsyncMock() mock_post_repository.get_by_id = AsyncMock(return_value=test_post) use_case = CreateCommentUseCase( post_repo=mock_post_repository, comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) result = await use_case.execute( post_id=test_post.id, author_id="user-456", content="Great post! Thanks for sharing.", ) assert result.post_id == test_post.id assert result.author_id == "user-456" assert result.content == "Great post! Thanks for sharing." assert result.parent_id is None assert result.like_count == 0 mock_comment_repository.add.assert_called_once() mock_transaction_manager.commit.assert_called_once() @pytest.mark.asyncio async def test_create_comment_reply( self, mock_post_repository: Mock, mock_transaction_manager: Mock, test_post: Post, ) -> None: """Test creating a reply to an existing comment. TC-UNIT-833: Positive — reply to comment with parent_id. """ mock_comment_repository = AsyncMock() mock_post_repository.get_by_id = AsyncMock(return_value=test_post) parent_id = uuid4() use_case = CreateCommentUseCase( post_repo=mock_post_repository, comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) result = await use_case.execute( post_id=test_post.id, author_id="user-456", content="This is a reply.", parent_id=parent_id, ) assert result.parent_id == parent_id assert result.post_id == test_post.id mock_comment_repository.add.assert_called_once() mock_transaction_manager.commit.assert_called_once() @pytest.mark.asyncio async def test_create_comment_post_not_found( self, mock_post_repository: Mock, mock_transaction_manager: Mock, ) -> None: """Test creating a comment on a non-existent post. TC-UNIT-834: Negative — post not found. """ mock_comment_repository = AsyncMock() mock_post_repository.get_by_id = AsyncMock(return_value=None) use_case = CreateCommentUseCase( post_repo=mock_post_repository, comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) with pytest.raises(NotFoundException): await use_case.execute( post_id=uuid4(), author_id="user-456", content="Comment on missing post.", ) mock_comment_repository.add.assert_not_called() mock_transaction_manager.commit.assert_not_called()