feat: adding unit test for repository

This commit is contained in:
akhdanre 2025-05-08 02:45:48 +07:00
parent 7a07543971
commit 1db14658e1
10 changed files with 690 additions and 0 deletions

View File

@ -0,0 +1,109 @@
import pytest
from unittest.mock import MagicMock
from bson import ObjectId
from datetime import datetime
from app.repositories import UserAnswerRepository
from app.models import UserAnswerEntity
from app.models.entities import AnswerItemEntity
@pytest.fixture
def mock_db():
return MagicMock()
@pytest.fixture
def repository(mock_db):
return UserAnswerRepository(db=mock_db)
def generate_dummy_answer_entity() -> UserAnswerEntity:
return UserAnswerEntity(
session_id="session123",
quiz_id=str(ObjectId()),
user_id="user123",
answered_at=datetime.utcnow(),
answers=[
AnswerItemEntity(
question_index=0, answer="B", is_correct=True, time_spent=10
)
],
total_score=80,
total_correct=4,
)
def test_create(repository):
dummy_entity = generate_dummy_answer_entity()
insert_result = MagicMock(inserted_id=ObjectId())
repository.collection.insert_one.return_value = insert_result
result = repository.create(dummy_entity)
repository.collection.insert_one.assert_called_once()
assert isinstance(result, str)
def test_get_by_id_found(repository):
dummy_entity = generate_dummy_answer_entity()
data = dummy_entity.model_dump(by_alias=True)
data["_id"] = ObjectId()
repository.collection.find_one.return_value = data
result = repository.get_by_id(str(data["_id"]))
assert isinstance(result, UserAnswerEntity)
assert result.user_id == dummy_entity.user_id
assert result.quiz_id == dummy_entity.quiz_id
def test_get_by_id_not_found(repository):
repository.collection.find_one.return_value = None
result = repository.get_by_id(str(ObjectId()))
assert result is None
def test_get_by_user_and_quiz(repository):
quiz_id = ObjectId()
repository.collection.find.return_value = [
{"_id": ObjectId(), "user_id": "u1", "quiz_id": quiz_id}
]
result = repository.get_by_user_and_quiz("u1", str(quiz_id))
repository.collection.find.assert_called_once_with(
{"user_id": "u1", "quiz_id": quiz_id}
)
assert isinstance(result, list)
def test_get_by_user(repository):
dummy_data = [generate_dummy_answer_entity().model_dump(by_alias=True)]
repository.collection.find.return_value = dummy_data
result = repository.get_by_user("user123")
assert isinstance(result, list)
assert all(isinstance(item, UserAnswerEntity) for item in result)
def test_get_by_session(repository):
session_id = ObjectId()
repository.collection.find.return_value = [{"session_id": str(session_id)}]
result = repository.get_by_session(str(session_id))
repository.collection.find.assert_called_once_with({"session_id": session_id})
assert isinstance(result, list)
assert result[0]["session_id"] == str(session_id)
def test_delete_by_id(repository):
repository.collection.delete_one.return_value = MagicMock(deleted_count=1)
result = repository.delete_by_id(str(ObjectId()))
assert result is True

View File

@ -0,0 +1,171 @@
import pytest
from unittest.mock import MagicMock
from bson import ObjectId
from datetime import datetime
from app.repositories import QuizRepository
from app.models.entities import QuizEntity
@pytest.fixture
def mock_db():
return MagicMock()
@pytest.fixture
def repository(mock_db):
return QuizRepository(db=mock_db)
def generate_quiz_entity(**kwargs) -> QuizEntity:
return QuizEntity(
subject_id=kwargs.get("subject_id", "subject1"),
title=kwargs.get("title", "Kuis Sejarah Indonesia"),
description=kwargs.get(
"description", "Soal mengenai peristiwa penting Indonesia"
),
is_public=kwargs.get("is_public", True),
date=kwargs.get("date", datetime.now()),
total_quiz=kwargs.get("total_quiz", 10),
limit_duration=kwargs.get("limit_duration", 30),
total_user_playing=kwargs.get("total_user_playing", 100),
question_listings=[],
author_id=kwargs.get("author_id", "guru123"),
)
def test_create_quiz(repository):
quiz = generate_quiz_entity()
insert_result = MagicMock(inserted_id=ObjectId())
repository.collection.insert_one.return_value = insert_result
result = repository.create(quiz)
repository.collection.insert_one.assert_called_once()
assert isinstance(result, str)
def test_get_by_id_found(repository):
quiz_id = ObjectId()
quiz_data = generate_quiz_entity().model_dump(by_alias=True)
quiz_data["_id"] = quiz_id
repository.collection.find_one.return_value = quiz_data
result = repository.get_by_id(str(quiz_id))
assert isinstance(result, QuizEntity)
assert result.id == quiz_id
def test_get_by_id_not_found(repository):
repository.collection.find_one.return_value = None
result = repository.get_by_id(str(ObjectId()))
assert result is None
def test_search_by_title_or_category(repository):
mock_cursor = MagicMock()
mock_cursor.skip.return_value = mock_cursor
mock_cursor.limit.return_value = [generate_quiz_entity().model_dump(by_alias=True)]
repository.collection.find.return_value = mock_cursor
result = repository.search_by_title_or_category(
keyword="Indonesia",
subject_id=None,
page=1,
page_size=10,
)
assert len(result) == 1
assert isinstance(result[0], QuizEntity)
def test_count_by_search(repository):
repository.collection.count_documents.return_value = 3
result = repository.count_by_search("sejarah")
assert result == 3
def test_get_by_ids(repository):
qid1, qid2 = ObjectId(), ObjectId()
data = [generate_quiz_entity().model_dump(by_alias=True) for _ in range(2)]
data[0]["_id"] = qid1
data[1]["_id"] = qid2
repository.collection.find.return_value = data
result = repository.get_by_ids([str(qid1), str(qid2)])
assert result is not None
assert all(isinstance(q, QuizEntity) for q in result)
def test_get_by_user_id(repository):
mock_cursor = MagicMock()
mock_cursor.skip.return_value = mock_cursor
mock_cursor.limit.return_value = [generate_quiz_entity().model_dump(by_alias=True)]
repository.collection.find.return_value = mock_cursor
result = repository.get_by_user_id("guru123")
assert isinstance(result, list)
assert isinstance(result[0], QuizEntity)
def test_get_all(repository):
mock_cursor = MagicMock()
mock_cursor.skip.return_value = mock_cursor
mock_cursor.limit.return_value = [generate_quiz_entity().model_dump(by_alias=True)]
repository.collection.find.return_value = mock_cursor
result = repository.get_all()
assert len(result) == 1
assert isinstance(result[0], QuizEntity)
def test_update(repository):
repository.collection.update_one.return_value = MagicMock(modified_count=1)
result = repository.update(str(ObjectId()), {"title": "Update Title"})
assert result is True
def test_update_user_playing(repository):
repository.collection.update_one.return_value = MagicMock(modified_count=1)
result = repository.update_user_playing(str(ObjectId()), 123)
assert result is True
def test_delete(repository):
repository.collection.delete_one.return_value = MagicMock(deleted_count=1)
result = repository.delete(str(ObjectId()))
assert result is True
def test_count_by_user_id(repository):
repository.collection.count_documents.return_value = 7
result = repository.count_by_user_id("guru123")
assert result == 7
def test_get_top_played_quizzes(repository):
mock_cursor = MagicMock()
mock_cursor.sort.return_value = mock_cursor
mock_cursor.skip.return_value = mock_cursor
mock_cursor.limit.return_value = [generate_quiz_entity().model_dump(by_alias=True)]
repository.collection.find.return_value = mock_cursor
result = repository.get_top_played_quizzes()
assert isinstance(result, list)
assert isinstance(result[0], QuizEntity)

View File

@ -0,0 +1,116 @@
import pytest
from unittest.mock import MagicMock
from bson import ObjectId
from datetime import datetime
from app.repositories import SessionRepository
from app.models.entities import SessionEntity
@pytest.fixture
def mock_db():
return MagicMock()
@pytest.fixture
def repository(mock_db):
return SessionRepository(db=mock_db)
def generate_session_entity() -> SessionEntity:
return SessionEntity(
session_code="ABC123",
quiz_id="quiz1",
host_id="user1",
created_at=datetime.now(),
started_at=None,
ended_at=None,
is_active=True,
participan_limit=5,
participants=["user1"],
current_question_index=0,
)
def test_insert_session(repository):
session = generate_session_entity()
insert_result = MagicMock(inserted_id=ObjectId())
repository.collection.insert_one.return_value = insert_result
result = repository.insert(session)
repository.collection.insert_one.assert_called_once()
assert isinstance(result, str)
def test_find_by_session_id_found(repository):
session = generate_session_entity()
doc = session.model_dump(by_alias=True)
repository.collection.find_one.return_value = doc
result = repository.find_by_session_id(session_id=doc["_id"])
assert isinstance(result, SessionEntity)
assert result.session_code == "ABC123"
def test_find_by_session_id_not_found(repository):
repository.collection.find_one.return_value = None
result = repository.find_by_session_id("nonexistent_id")
assert result is None
def test_find_by_session_code_found(repository):
session = generate_session_entity()
doc = session.model_dump(by_alias=True)
repository.collection.find_one.return_value = doc
result = repository.find_by_session_code("ABC123")
assert isinstance(result, SessionEntity)
assert result.quiz_id == "quiz1"
def test_update_session(repository):
repository.collection.update_one.return_value = MagicMock(modified_count=1)
update_data = {"is_active": False}
result = repository.update("session123", update_data)
repository.collection.update_one.assert_called_once_with(
{"_id": "session123"}, {"$set": update_data}
)
assert result is True
def test_add_participant(repository):
repository.collection.update_one.return_value = MagicMock(modified_count=1)
result = repository.add_participant("session123", "user999")
repository.collection.update_one.assert_called_once_with(
{"_id": "session123"}, {"$addToSet": {"participants": "user999"}}
)
assert result is True
def test_delete_session(repository):
repository.collection.delete_one.return_value = MagicMock(deleted_count=1)
result = repository.delete("session123")
repository.collection.delete_one.assert_called_once_with({"_id": "session123"})
assert result is True
def test_list_active_sessions(repository):
doc = generate_session_entity().model_dump(by_alias=True)
repository.collection.find.return_value = [doc]
result = repository.list_active_sessions()
repository.collection.find.assert_called_once_with({"is_active": True})
assert len(result) == 1
assert isinstance(result[0], SessionEntity)
assert result[0].is_active is True

View File

@ -0,0 +1,139 @@
import pytest
from unittest.mock import MagicMock
from bson import ObjectId
from app.repositories.subject_repository import SubjectRepository
from app.models.entities import SubjectEntity
@pytest.fixture
def mock_db():
return MagicMock()
@pytest.fixture
def repository(mock_db):
return SubjectRepository(db=mock_db)
def generate_subject(name, short_name, desc, icon="") -> SubjectEntity:
return SubjectEntity(name=name, short_name=short_name, description=desc, icon=icon)
def test_create_subject(repository):
subject = generate_subject(
name="Sejarah Indonesia",
short_name="SEJARAH",
desc="Mempelajari peristiwa dan tokoh penting dalam sejarah nasional.",
)
insert_result = MagicMock(inserted_id=ObjectId())
repository.collection.insert_one.return_value = insert_result
result = repository.create(subject)
repository.collection.insert_one.assert_called_once()
assert isinstance(result, str)
def test_get_all_subjects(repository):
mock_data = [
generate_subject(
"Biologi",
"BIO",
"Ilmu yang mempelajari makhluk hidup dan lingkungannya.",
).model_dump(by_alias=True),
generate_subject(
"Fisika",
"FIS",
"Mempelajari fenomena alam seperti gaya, energi, dan gerak.",
).model_dump(by_alias=True),
]
repository.collection.find.return_value = mock_data
result = repository.get_all()
assert len(result) == 2
assert result[0].name == "Biologi"
assert result[1].short_name == "FIS"
def test_get_by_id_valid(repository):
oid = ObjectId()
doc = generate_subject(
"Geografi",
"GEO",
"Studi tentang lokasi, wilayah, dan interaksi manusia-lingkungan.",
).model_dump(by_alias=True)
doc["_id"] = oid
repository.collection.find_one.return_value = doc
result = repository.get_by_id(str(oid))
assert isinstance(result, SubjectEntity)
assert result.name == "Geografi"
assert result.id == oid
def test_get_by_id_invalid(repository):
result = repository.get_by_id("invalid_id")
assert result is None
def test_get_by_ids_mixed(repository):
oid1 = ObjectId()
oid2 = ObjectId()
ids = [str(oid1), "invalid_id", str(oid2)]
mock_docs = [
{
**generate_subject(
"Kimia",
"KIM",
"Ilmu tentang zat dan reaksinya",
).model_dump(by_alias=True),
"_id": oid1,
},
{
**generate_subject(
"Ekonomi",
"EKO",
"Analisis produksi, distribusi, dan konsumsi",
).model_dump(by_alias=True),
"_id": oid2,
},
]
repository.collection.find.return_value = mock_docs
result = repository.get_by_ids(ids)
assert len(result) == 2
assert result[0].short_name == "KIM"
assert result[1].name == "Ekonomi"
def test_update_valid(repository):
oid = ObjectId()
repository.collection.update_one.return_value = MagicMock(modified_count=1)
result = repository.update(str(oid), {"description": "Updated Description"})
assert result is True
def test_update_invalid(repository):
result = repository.update("invalid_object_id", {"name": "Something"})
assert result is False
def test_delete_valid(repository):
oid = ObjectId()
repository.collection.delete_one.return_value = MagicMock(deleted_count=1)
result = repository.delete(str(oid))
assert result is True
def test_delete_invalid(repository):
result = repository.delete("invalid_object_id")
assert result is False

View File

@ -0,0 +1,155 @@
import pytest
from unittest.mock import MagicMock
from bson import ObjectId
from datetime import datetime
from app.repositories.user_repository import UserRepository
from app.models.entities import UserEntity
@pytest.fixture
def mock_db():
return MagicMock()
@pytest.fixture
def user_repository(mock_db):
return UserRepository(db=mock_db)
def test_get_all_users(user_repository):
mock_users = [
{
"_id": ObjectId(),
"email": "a@example.com",
"name": "A",
"password": "pass1",
"locale": "id-ID",
},
{
"_id": ObjectId(),
"email": "b@example.com",
"name": "B",
"password": "pass2",
"locale": "id-ID",
},
]
user_repository.collection.find.return_value = mock_users
result = user_repository.get_all_users()
assert len(result) == 2
assert all(isinstance(user, UserEntity) for user in result)
assert result[0].email == "a@example.com"
assert result[1].name == "B"
def test_get_user_by_email_found(user_repository):
mock_user = {
"_id": ObjectId(),
"email": "john@example.com",
"name": "John Doe",
"password": "hashed",
"birth_date": datetime(2000, 1, 1),
"locale": "en-US",
"phone": "08123456789",
}
user_repository.collection.find_one.return_value = mock_user
result = user_repository.get_user_by_email("john@example.com")
assert isinstance(result, UserEntity)
assert result.email == "john@example.com"
assert result.name == "John Doe"
def test_get_user_by_email_not_found(user_repository):
user_repository.collection.find_one.return_value = None
result = user_repository.get_user_by_email("notfound@example.com")
assert result is None
def test_get_user_by_id_found(user_repository):
user_id = ObjectId()
mock_user = {
"_id": user_id,
"email": "jane@example.com",
"name": "Jane",
"password": "hashed",
"birth_date": datetime(1990, 1, 1),
"locale": "en-US",
"phone": "089999999",
}
user_repository.collection.find_one.return_value = mock_user
result = user_repository.get_user_by_id(str(user_id))
assert isinstance(result, UserEntity)
assert str(result.id) == str(user_id)
assert result.name == "Jane"
def test_get_by_google_id_found(user_repository):
mock_user = {
"_id": ObjectId(),
"google_id": "google-123",
"email": "google@example.com",
"name": "Google User",
"locale": "en-US",
}
user_repository.collection.find_one.return_value = mock_user
result = user_repository.get_by_google_id("google-123")
assert isinstance(result, UserEntity)
assert result.google_id == "google-123"
assert result.email == "google@example.com"
def test_insert_user(user_repository):
user_entity = UserEntity(
name="Test",
email="test@example.com",
password="123",
birth_date=datetime(2000, 1, 1),
phone="081111111",
locale="id-ID",
)
mock_insert_result = MagicMock(inserted_id=ObjectId())
user_repository.collection.insert_one.return_value = mock_insert_result
result = user_repository.insert_user(user_entity)
user_repository.collection.insert_one.assert_called_once()
assert isinstance(result, str)
def test_update_user(user_repository):
user_id = str(ObjectId())
mock_result = MagicMock(modified_count=1)
user_repository.collection.update_one.return_value = mock_result
result = user_repository.update_user(user_id, {"name": "Updated Name"})
assert result is True
def test_update_user_field(user_repository):
user_id = str(ObjectId())
mock_result = MagicMock(modified_count=1)
user_repository.collection.update_one.return_value = mock_result
result = user_repository.update_user_field(user_id, "phone", "0822334455")
assert result is True
def test_delete_user(user_repository):
user_id = str(ObjectId())
mock_result = MagicMock(deleted_count=1)
user_repository.collection.delete_one.return_value = mock_result
result = user_repository.delete_user(user_id)
assert result is True