TIF_E41211115_Genso_quiz_ba.../test/service/test_answer_service.py

179 lines
4.9 KiB
Python

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)