import pytest from unittest.mock import MagicMock from datetime import datetime from app.services.answer_service import AnswerService from app.schemas.requests import UserAnswerSchema, AnswerItemSchema from app.models.entities import QuestionItemEntity from app.models import UserAnswerEntity from app.exception import ValidationException @pytest.fixture def mock_answer_repository(): return MagicMock() @pytest.fixture def mock_quiz_repository(): return MagicMock() @pytest.fixture def mock_user_repository(): return MagicMock() @pytest.fixture def answer_service(mock_answer_repository, mock_quiz_repository, mock_user_repository): return AnswerService( answer_repository=mock_answer_repository, quiz_repository=mock_quiz_repository, user_repositroy=mock_user_repository, ) def test_create_answer_success( answer_service, mock_quiz_repository, mock_user_repository, mock_answer_repository ): # Setup dummy quiz mock_quiz = MagicMock() mock_quiz.id = "quiz1" mock_quiz.total_user_playing = 5 mock_quiz.question_listings = [ QuestionItemEntity( index=0, question="Soal 1", type="fill_the_blank", target_answer="Jakarta", duration=10, options=[], ), QuestionItemEntity( index=1, question="Soal 2", type="true_false", target_answer="True", duration=10, options=[], ), QuestionItemEntity( index=2, question="Soal 3", type="option", target_answer="1", duration=10, options=["A", "B", "C"], ), ] mock_quiz_repository.get_by_id.return_value = mock_quiz # Setup dummy user mock_user_repository.get_user_by_id.return_value = MagicMock() # Setup user answer input answer_data = UserAnswerSchema( session_id="session1", quiz_id="quiz1", user_id="user1", answered_at=datetime.now(), answers=[ AnswerItemSchema( question_index=0, answer="Jakarta", time_spent=10, is_correct=True, ), AnswerItemSchema( question_index=1, answer="True", time_spent=5, is_correct=True, ), AnswerItemSchema( question_index=2, answer="1", time_spent=7, is_correct=True, ), ], ) mock_answer_repository.create.return_value = "answer_id_123" result = answer_service.create_answer(answer_data) assert result == "answer_id_123" mock_quiz_repository.update_user_playing.assert_called_once_with( quiz_id="quiz1", total_user=6 ) mock_answer_repository.create.assert_called_once() assert all([a.is_correct is not None for a in answer_data.answers]) def test_create_answer_quiz_not_found(answer_service, mock_quiz_repository): mock_quiz_repository.get_by_id.return_value = None answer_data = UserAnswerSchema( session_id="s1", quiz_id="nonexistent", user_id="u1", answered_at=datetime.now(), answers=[], ) with pytest.raises(ValidationException, match="Quiz not found"): answer_service.create_answer(answer_data) def test_create_answer_user_not_found( answer_service, mock_quiz_repository, mock_user_repository ): mock_quiz_repository.get_by_id.return_value = MagicMock() mock_user_repository.get_user_by_id.return_value = None answer_data = UserAnswerSchema( session_id="s1", quiz_id="q1", user_id="unknown_user", answered_at=datetime.now(), answers=[], ) with pytest.raises(ValidationException, match="user is not registered"): answer_service.create_answer(answer_data) def test_create_answer_invalid_option_index( answer_service, mock_quiz_repository, mock_user_repository ): quiz = MagicMock() quiz.id = "quiz1" quiz.total_user_playing = 0 quiz.question_listings = [ QuestionItemEntity( index=0, question="Soal 1", type="option", target_answer="1", duration=10, options=["A", "B", "C"], ), ] mock_quiz_repository.get_by_id.return_value = quiz mock_user_repository.get_user_by_id.return_value = MagicMock() answer_data = UserAnswerSchema( session_id="s1", quiz_id="quiz1", user_id="user1", answered_at=datetime.now(), answers=[ AnswerItemSchema( question_index=0, answer="5", time_spent=3, is_correct=False ) ], ) with pytest.raises(ValueError, match="Index jawaban tidak valid"): answer_service.create_answer(answer_data)