from unittest import mock import pytest from dmp.adapters.google import GoogleClientError from dmp.adapters.google.models import RefreshToken, User, UserAdAccount from dmp.audiences.models import Audience from dmp.config import Settings from dmp.google.models import ( GoogleAdAccount, GoogleUserAdAccount, GoogleUserConnection, GoogleUserConnectionAdAccount, ) from dmp.google.repositories import GoogleUserConnectionRepository from dmp.google.services import GoogleUserConnectionService from tests.unit.faker import FakerTyped from tests.unit.types import BuildModel, CreateModel class TestGoogleUserConnectionService: @pytest.mark.db def test_create_or_update_user_connection_new_connection( self, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, build_model: BuildModel, identity_id: str, settings: Settings, ) -> None: user = build_model(User) token = build_model( RefreshToken, scope=" ".join(settings.google_user_required_scopes), ) google_client_mock.get_user.return_value = user google_client_mock.get_refresh_token.return_value = token user_connection = build_model( GoogleUserConnection, identity_id=identity_id, token=token.refresh_token, user_id=user.id, user_name=user.name, is_valid=True, ) result_user_connection = service.create_or_update_user_connection( user_connection=user_connection ) assert result_user_connection assert result_user_connection.id == user_connection.id assert result_user_connection.is_valid assert result_user_connection.user_id == user.id assert result_user_connection.user_name == user.name assert result_user_connection.identity_id == identity_id @pytest.mark.db def test_create_or_update_user_connection_with_existing_connection( self, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, build_model: BuildModel, create_model: CreateModel, identity_id: str, settings: Settings, ) -> None: user = build_model(User) existing_user_connection = create_model( GoogleUserConnection, identity_id=identity_id, user_id=user.id, is_valid=False, connection_ad_accounts=[], ) token = build_model( RefreshToken, scope=" ".join(settings.google_user_required_scopes), ) google_client_mock.get_user.return_value = user google_client_mock.get_refresh_token.return_value = token new_user_connection = build_model( GoogleUserConnection, identity_id=identity_id, user_id=user.id, is_valid=True, token=token.refresh_token, user_name=user.name, ) user_connection = service.create_or_update_user_connection( user_connection=new_user_connection ) assert user_connection assert user_connection.id == existing_user_connection.id assert user_connection.is_valid assert user_connection.user_id == existing_user_connection.user_id assert user_connection.user_name == user.name assert user_connection.identity_id == existing_user_connection.identity_id assert str(user_connection.token) == str(token.refresh_token) @pytest.mark.db def test_get_active_audience_sharing_connection_disconnect_user( self, user_connection_repository: GoogleUserConnectionRepository, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, create_model: CreateModel, ) -> None: audience = create_model(Audience) ad_account = create_model(GoogleAdAccount) user_connection = create_model( GoogleUserConnection, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account), ], is_valid=True, ) create_model( GoogleUserAdAccount, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, ) google_client_mock.get_user.side_effect = GoogleClientError() ad_account_connection = service.get_active_audience_sharing_connection( audience_id=audience.id, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, ) assert not ad_account_connection result = user_connection_repository.get(user_connection.id) assert result assert not result.is_valid @pytest.mark.db def test_get_active_audience_sharing_connection_when_token_is_invalid( self, user_connection_repository: GoogleUserConnectionRepository, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, create_model: CreateModel, ) -> None: audience = create_model(Audience) ad_account = create_model(GoogleAdAccount) user_connection = create_model( GoogleUserConnection, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account), ], is_valid=True, ) create_model( GoogleUserAdAccount, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, ) google_client_mock.get_access_token.side_effect = GoogleClientError() ad_account_connection = service.get_active_audience_sharing_connection( audience_id=audience.id, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, ) assert not ad_account_connection result = user_connection_repository.get(user_connection.id) assert result assert not result.is_valid @pytest.mark.db def test_invalidate_user_connection_when_token_is_invalid( self, user_connection_repository: GoogleUserConnectionRepository, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, create_model: CreateModel, ) -> None: audience = create_model(Audience) ad_account = create_model(GoogleAdAccount) user_connection = create_model( GoogleUserConnection, is_valid=True, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account), ], ) create_model( GoogleUserAdAccount, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, ) google_client_mock.get_access_token.side_effect = GoogleClientError() with pytest.raises(GoogleClientError): (service.get_connection_access_token(connection=user_connection)) result = user_connection_repository.get(user_connection.id) assert result assert not result.is_valid @pytest.mark.db def test_get_active_audience_sharing_connection( self, service: GoogleUserConnectionService, google_client_mock: mock.MagicMock, build_model: BuildModel, create_model: CreateModel, ) -> None: audience = create_model(Audience) ad_account = create_model(GoogleAdAccount) user_connection = create_model( GoogleUserConnection, is_valid=True, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account), ], ) create_model( GoogleUserAdAccount, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, ) google_client_mock.get_user.return_value = build_model(User) ad_account_connection = service.get_active_audience_sharing_connection( audience_id=audience.id, ad_account_id=ad_account.id, identity_id=user_connection.identity_id, ) assert ad_account_connection == user_connection def test_add_ad_accounts( self, build_model: BuildModel, fake: FakerTyped, ) -> None: login_customer_id = str(fake.integer()) user_connection = build_model(GoogleUserConnection, connection_ad_accounts=[]) ad_account_1 = build_model(GoogleAdAccount) ad_account_2 = build_model(GoogleAdAccount) user_ad_account_1 = build_model( UserAdAccount, id=ad_account_1.external_id, login_customer_id=None ) user_ad_account_2 = build_model( UserAdAccount, id=ad_account_2.external_id, login_customer_id=login_customer_id, ) user_connection.add_ad_accounts( ad_accounts=[ad_account_1, ad_account_2], user_ad_accounts=[user_ad_account_1, user_ad_account_2], ) assert user_connection.connection_ad_accounts assert user_connection.connection_ad_accounts == [ GoogleUserConnectionAdAccount( ad_account=ad_account_1, parent_ad_account_id=None ), GoogleUserConnectionAdAccount( ad_account=ad_account_2, parent_ad_account_id=login_customer_id ), ]