from unittest import mock import pytest from dirty_equals import IsPartialDataclass from faker import Faker from dmp.google.exceptions import GoogleAdAccountNotFoundError from dmp.google.handlers import ( DeleteGoogleAdAccountsHandler, DeleteGoogleAdAccountsRequest, ) from dmp.google.models import ( GoogleAdAccount, GoogleAdReportingConnection, GoogleUserAdAccount, GoogleUserConnection, GoogleUserConnectionAdAccount, ) from dmp.google.repositories import ( GoogleAdReportingConnectionRepository, GoogleUserAdAccountRepository, GoogleUserConnectionRepository, ) from tests.unit.types import CreateModel class TestDeleteGoogleAdAccountsHandler: @pytest.mark.db def test_delete_ad_accounts( self, handler: DeleteGoogleAdAccountsHandler, fivetran_client_mock: mock.MagicMock, create_model: CreateModel, user_connection_repository: GoogleUserConnectionRepository, user_ad_account_repository: GoogleUserAdAccountRepository, faker: Faker, ) -> None: vendor_id = faker.pyint() subaccount_id = faker.pyint() identity_id_1 = faker.uuid4() identity_id_2 = faker.uuid4() ad_account_1 = create_model(GoogleAdAccount) ad_account_2 = create_model(GoogleAdAccount) user_connection_1 = create_model( GoogleUserConnection, is_valid=True, identity_id=identity_id_1, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account_1), GoogleUserConnectionAdAccount(ad_account=ad_account_2), ], ) # second user connection for the same identity user_connection_2 = create_model( GoogleUserConnection, id="user_connection_2", is_valid=True, identity_id=identity_id_1, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account_1) ], ) ad_reporting_connection_1 = create_model( GoogleAdReportingConnection, identity_id=identity_id_1, ad_accounts=[ad_account_1, ad_account_2], ) user_connection_3 = create_model( GoogleUserConnection, is_valid=True, identity_id=identity_id_2, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account_1), GoogleUserConnectionAdAccount(ad_account=ad_account_2), ], ) ad_reporting_connection_2 = create_model( GoogleAdReportingConnection, identity_id=identity_id_2, ad_accounts=[ad_account_1, ad_account_2], ) create_model( GoogleUserAdAccount, identity_id=identity_id_1, ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_model( GoogleUserAdAccount, identity_id=identity_id_2, ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_model( GoogleUserAdAccount, identity_id=identity_id_2, ad_account_id=ad_account_2.id, ) create_model( GoogleUserAdAccount, identity_id=identity_id_1, ad_account_id=ad_account_2.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) handler.handle( DeleteGoogleAdAccountsRequest( identity_id=faker.uuid4(), ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ), ) user_ad_account = user_ad_account_repository.find_by_ad_account_id_and_account( ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) assert not user_ad_account assert user_connection_1.connection_ad_accounts == [ IsPartialDataclass(ad_account_id=ad_account_2.id) ] assert ad_reporting_connection_1.ad_accounts == [ad_account_2] assert len(user_connection_2.connection_ad_accounts) == 0 assert user_connection_repository.get(user_connection_2.id) is None assert ad_reporting_connection_2.ad_accounts == [ad_account_2] assert user_connection_3.connection_ad_accounts == [ IsPartialDataclass(ad_account_id=ad_account_2.id) ] fivetran_client_mock.delete_connection.assert_not_called() @pytest.mark.db def test_delete_ad_accounts_with_last_user_ad_account( self, handler: DeleteGoogleAdAccountsHandler, fivetran_client_mock: mock.MagicMock, create_model: CreateModel, user_connection_repository: GoogleUserConnectionRepository, ad_reporting_connection_repository: GoogleAdReportingConnectionRepository, user_ad_account_repository: GoogleUserAdAccountRepository, faker: Faker, ) -> None: vendor_id = faker.pyint() subaccount_id = faker.pyint() identity_id_1 = faker.uuid4() identity_id_2 = faker.uuid4() ad_account_1 = create_model(GoogleAdAccount) ad_account_2 = create_model(GoogleAdAccount) user_connection_1 = create_model( GoogleUserConnection, is_valid=True, identity_id=identity_id_1, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account_2), GoogleUserConnectionAdAccount(ad_account=ad_account_1), ], ) ad_reporting_connection_1 = create_model( GoogleAdReportingConnection, identity_id=identity_id_1, ad_accounts=[ad_account_1, ad_account_2], ) user_connection_2 = create_model( GoogleUserConnection, is_valid=True, identity_id=identity_id_2, connection_ad_accounts=[ GoogleUserConnectionAdAccount(ad_account=ad_account_1), ], ) ad_reporting_connection_2 = create_model( GoogleAdReportingConnection, identity_id=identity_id_2, ad_accounts=[ad_account_1], ) create_model( GoogleUserAdAccount, identity_id=identity_id_1, ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_model( GoogleUserAdAccount, identity_id=identity_id_2, ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_model( GoogleUserAdAccount, identity_id=identity_id_1, ad_account_id=ad_account_2.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) handler.handle( DeleteGoogleAdAccountsRequest( identity_id=faker.uuid4(), ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ), ) user_ad_account = user_ad_account_repository.find_by_ad_account_id_and_account( ad_account_id=ad_account_1.id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) assert not user_ad_account assert user_connection_1.connection_ad_accounts == [ IsPartialDataclass(ad_account_id=ad_account_2.id) ] assert ad_reporting_connection_1.ad_accounts == [ad_account_2] assert user_connection_repository.get(user_connection_2.id) is None assert ( ad_reporting_connection_repository.get(ad_reporting_connection_2.id) is None ) fivetran_client_mock.delete_connection.assert_called_once() @pytest.mark.db def test_delete_ad_accounts_wrong_ad_account_id( self, handler: DeleteGoogleAdAccountsHandler, identity_id: str, faker: Faker, ) -> None: ad_account_id = faker.uuid4() with pytest.raises(GoogleAdAccountNotFoundError): handler.handle( DeleteGoogleAdAccountsRequest( identity_id=identity_id, ad_account_id=ad_account_id, vendor_id=faker.pyint(), subaccount_id=faker.pyint(), ), )