200 lines
6.4 KiB
Python
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")
|