"""Tests for ToggleCommentLikeUseCase. This module tests the comment like/unlike toggle use case covering first-time like, unlike, and comment-not-found scenarios. """ from unittest.mock import AsyncMock from uuid import uuid4 import pytest from app.application.use_cases.toggle_comment_like import ToggleCommentLikeUseCase from app.domain.entities.comment import Comment from app.domain.entities.comment_like import CommentLike from app.domain.exceptions import NotFoundException class TestToggleCommentLikeUseCase: """Tests for ToggleCommentLikeUseCase. Covers TC-UNIT-838 through TC-UNIT-840. """ @pytest.mark.asyncio async def test_like_comment_first_time( self, mock_transaction_manager: AsyncMock, ) -> None: """Test liking a comment for the first time. TC-UNIT-838: Positive — like first time. """ post_id = uuid4() comment = Comment.create( post_id=post_id, author_id="user-123", content_str="Nice post!", ) mock_comment_repository = AsyncMock() mock_comment_repository.get_by_id = AsyncMock(return_value=comment) mock_comment_repository.get_like = AsyncMock(return_value=None) mock_comment_repository.add_like = AsyncMock() mock_comment_repository.remove_like = AsyncMock() mock_comment_repository.update = AsyncMock() use_case = ToggleCommentLikeUseCase( comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) result = await use_case.execute(comment.id, "user-456") assert result.like_count == 1 mock_comment_repository.add_like.assert_called_once() mock_comment_repository.remove_like.assert_not_called() mock_comment_repository.update.assert_called_once() mock_transaction_manager.commit.assert_called_once() @pytest.mark.asyncio async def test_unlike_comment_already_liked( self, mock_transaction_manager: AsyncMock, ) -> None: """Test unliking a comment that is already liked. TC-UNIT-839: Positive — unlike (already liked). """ post_id = uuid4() comment = Comment.create( post_id=post_id, author_id="user-123", content_str="Nice post!", ) existing_like = CommentLike(comment_id=comment.id, liked_by="user-456") mock_comment_repository = AsyncMock() mock_comment_repository.get_by_id = AsyncMock(return_value=comment) mock_comment_repository.get_like = AsyncMock(return_value=existing_like) mock_comment_repository.add_like = AsyncMock() mock_comment_repository.remove_like = AsyncMock() mock_comment_repository.update = AsyncMock() use_case = ToggleCommentLikeUseCase( comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) result = await use_case.execute(comment.id, "user-456") assert result.like_count == 0 mock_comment_repository.remove_like.assert_called_once() mock_comment_repository.add_like.assert_not_called() mock_comment_repository.update.assert_called_once() mock_transaction_manager.commit.assert_called_once() @pytest.mark.asyncio async def test_like_comment_not_found( self, mock_transaction_manager: AsyncMock, ) -> None: """Test liking a non-existent comment. TC-UNIT-840: Negative — comment not found. """ mock_comment_repository = AsyncMock() mock_comment_repository.get_by_id = AsyncMock(return_value=None) use_case = ToggleCommentLikeUseCase( comment_repo=mock_comment_repository, tx_manager=mock_transaction_manager, ) with pytest.raises(NotFoundException): await use_case.execute(uuid4(), "user-456") mock_comment_repository.add_like.assert_not_called() mock_comment_repository.remove_like.assert_not_called() mock_transaction_manager.commit.assert_not_called()