TIF_E41211115_Genso_quiz_ba.../test/service/test_auth_service.py

200 lines
6.4 KiB
Python

import pytest
from unittest.mock import MagicMock, patch
from app.services.auth_service import AuthService
from app.schemas import LoginSchema
from app.exception import AuthException
from werkzeug.security import generate_password_hash
from app.models.entities import UserEntity
from app.schemas.response import LoginResponseSchema
from app.mapper import UserMapper
@pytest.fixture
def mock_user_repository():
return MagicMock()
@pytest.fixture
def auth_service(mock_user_repository):
return AuthService(userRepository=mock_user_repository)
@pytest.fixture
def dummy_user_entity():
# Create a UserEntity instance with natural-looking data
return UserEntity(
id="6507a32a1f3b5e2dc8a45bf9",
email="budi@mail.com",
password=generate_password_hash("rahasia123"),
name="Budi Santoso",
locale="id-ID",
)
@pytest.fixture
def dummy_user_response():
# Create a mock response with natural-looking data
return MagicMock(
id="6507a32a1f3b5e2dc8a45bf9", email="budi@mail.com", name="Budi Santoso"
)
# --- verify_google_id_token tests ---
@patch("app.services.auth_service.id_token.verify_oauth2_token")
def test_verify_google_existing_user(
mock_verify,
auth_service,
mock_user_repository,
dummy_user_entity,
dummy_user_response,
):
# Simulate valid token
mock_verify.return_value = {
"sub": "108762374589123456789",
"email": "budi@mail.com",
}
mock_user_repository.get_by_google_id.return_value = dummy_user_entity
# Setup the mapper to return our expected response
with patch(
"app.services.auth_service.UserMapper.user_entity_to_response"
) as mock_mapper:
mock_mapper.return_value = dummy_user_response
user = auth_service.verify_google_id_token("valid_token_string")
assert user == dummy_user_response
mock_user_repository.get_by_google_id.assert_called_once_with(
"108762374589123456789"
)
mock_mapper.assert_called_once_with(dummy_user_entity)
@patch("app.services.auth_service.id_token.verify_oauth2_token")
def test_verify_google_new_user(
mock_verify,
auth_service,
mock_user_repository,
dummy_user_entity,
dummy_user_response,
):
# Setup the Google payload with natural data
google_payload = {
"sub": "117239875612345678901",
"email": "dewi@mail.com",
"name": "Dewi Sartika",
}
mock_verify.return_value = google_payload
# Setup repository responses
mock_user_repository.get_by_google_id.return_value = None
mock_user_repository.insert_user.return_value = "65081fe3ab234cdef9876543"
mock_user_repository.get_user_by_id.return_value = dummy_user_entity
# Setup mappers
with patch(
"app.services.auth_service.UserMapper.from_google_payload"
) as mock_from_google:
with patch(
"app.services.auth_service.UserMapper.user_entity_to_response"
) as mock_to_response:
# Configure the mocks
mock_from_google.return_value = dummy_user_entity
mock_to_response.return_value = dummy_user_response
# Call the method
user = auth_service.verify_google_id_token("google_token_string")
# Assertions
assert user == dummy_user_response
mock_user_repository.get_by_google_id.assert_called_once_with(
"117239875612345678901"
)
mock_from_google.assert_called_once_with(
"117239875612345678901", "dewi@mail.com", google_payload
)
mock_user_repository.insert_user.assert_called_once_with(
user_data=dummy_user_entity
)
mock_user_repository.get_user_by_id.assert_called_once_with(
user_id="65081fe3ab234cdef9876543"
)
mock_to_response.assert_called_once_with(dummy_user_entity)
@patch("app.services.auth_service.id_token.verify_oauth2_token")
def test_verify_google_email_mismatch(
mock_verify, auth_service, mock_user_repository, dummy_user_entity
):
# Setup mismatched email scenario with natural data
mock_verify.return_value = {
"sub": "108762374589123456789",
"email": "dewi@mail.com",
}
dummy_user_entity.email = "budi@mail.com"
mock_user_repository.get_by_google_id.return_value = dummy_user_entity
# Test should raise exception
with pytest.raises(AuthException, match="Email not match"):
auth_service.verify_google_id_token("token_string")
@patch("app.services.auth_service.id_token.verify_oauth2_token")
def test_verify_google_invalid_token(mock_verify, auth_service):
# Setup token verification failure
mock_verify.side_effect = ValueError("Token tidak valid")
# Test should raise exception
with pytest.raises(Exception):
auth_service.verify_google_id_token("invalid_token_string")
# --- login tests ---
def test_login_success(
auth_service, mock_user_repository, dummy_user_entity, dummy_user_response
):
# Setup repository
mock_user_repository.get_user_by_email.return_value = dummy_user_entity
# Setup mapper
with patch(
"app.services.auth_service.UserMapper.user_entity_to_response"
) as mock_mapper:
mock_mapper.return_value = dummy_user_response
# Call login with natural data
schema = LoginSchema(email="budi@mail.com", password="rahasia123")
user = auth_service.login(schema)
# Assertions
assert user == dummy_user_response
mock_user_repository.get_user_by_email.assert_called_once_with("budi@mail.com")
# Verify that password is set to None
assert dummy_user_entity.password is None
mock_mapper.assert_called_once_with(dummy_user_entity)
def test_login_wrong_password(auth_service, mock_user_repository, dummy_user_entity):
# Setup repository with correct user
mock_user_repository.get_user_by_email.return_value = dummy_user_entity
# Login with wrong password
schema = LoginSchema(email="budi@mail.com", password="password_salah")
user = auth_service.login(schema)
# Assertions
assert user is None
mock_user_repository.get_user_by_email.assert_called_once_with("budi@mail.com")
def test_login_user_not_found(auth_service, mock_user_repository):
# Setup repository to return no user
mock_user_repository.get_user_by_email.return_value = None
# Login with unknown email
schema = LoginSchema(email="tidak_ada@mail.com", password="rahasia123")
user = auth_service.login(schema)
# Assertions
assert user is None
mock_user_repository.get_user_by_email.assert_called_once_with("tidak_ada@mail.com")