from unittest import mock import faker import pytest from fansifter_common.adapters.ows_account import Vendor from fansifter_common.auth.account import Account from fansifter_common.core.enums import Brand from fansifter_common.email import EmailType from email_campaigns.automated.enums import AutomatedEmailType from email_campaigns.automated.exceptions import ( AutomatedEmailSenderEmailNotValidError, AutomatedEmailTypeChangeNotAllowedError, ) from email_campaigns.automated.handlers import ( UpdateAutomatedEmailHandler, UpdateAutomatedEmailRequest, ) from email_campaigns.automated.models import AutomatedEmail from email_campaigns.emails.exceptions import InvalidEmailDomainIdError from email_campaigns.emails.models import EmailDomain from email_campaigns.rosters.models import CustomList from email_campaigns.rosters.types import FanDataListId from tests.unit.types import BuildModel, CreateModel class TestUpdateAutomatedEmailHandler: @pytest.mark.db def test_update_automated_email( self, handler: UpdateAutomatedEmailHandler, build_model: BuildModel, create_model: CreateModel, identity_id: str, account: Account, ows_account_client_mock: mock.MagicMock, campaign_public_preview_cache_mock: mock.MagicMock, faker: faker.Faker, ) -> None: # Reset mock to clear any previous calls campaign_public_preview_cache_mock.reset_mock() vendor = build_model( Vendor, vendor_id=account.vendor_id, company_brand=Brand.SME ) name = faker.name() subject = faker.sentence() automated_email_type = AutomatedEmailType.TRIGGERED sender_name = faker.first_name() email_username = faker.user_name() preview_text = faker.sentence() global_participant_id = faker.uuid4() email_domain = create_model( EmailDomain, brand=vendor.brand, vendor_id=None, subaccount_id=None ) automated_email = create_model( AutomatedEmail, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, ) ows_account_client_mock.get_vendor.return_value = vendor result = handler.handle( UpdateAutomatedEmailRequest( identity_id=identity_id, email_id=automated_email.id, name=name, fandata_list_id=FanDataListId.from_artist_id(global_participant_id), sender_name=sender_name, type=automated_email_type, email_domain_id=email_domain.id, email_username=email_username, subject=subject, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, preview_text=preview_text, ) ) assert result.name == name assert result.vendor_id == account.vendor_id assert result.subaccount_id == account.subaccount_id assert result.global_participant_id == global_participant_id assert result.custom_list_id is None assert result.type == automated_email_type assert result.sender_name == sender_name assert result.email_domain_id == email_domain.id assert result.email_username == email_username assert result.subject == subject assert result.preview_text == preview_text assert result.updated_by == identity_id # Verify cache was invalidated campaign_public_preview_cache_mock.delete.assert_called_once_with( automated_email.id, email_type=EmailType.AUTOMATED ) @pytest.mark.db def test_update_automated_email_artist( self, handler: UpdateAutomatedEmailHandler, build_model: BuildModel, create_model: CreateModel, identity_id: str, account: Account, ows_account_client_mock: mock.MagicMock, faker: faker.Faker, ) -> None: vendor = build_model( Vendor, vendor_id=account.vendor_id, company_brand=Brand.SME ) name = faker.name() global_participant_id = faker.uuid4() custom_list = create_model( CustomList, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, ) email_domain = create_model( EmailDomain, brand=vendor.brand, vendor_id=None, subaccount_id=None ) automated_email = create_model( AutomatedEmail, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, email_domain=email_domain, ) ows_account_client_mock.get_vendor.return_value = vendor result = handler.handle( UpdateAutomatedEmailRequest( identity_id=identity_id, email_id=automated_email.id, vendor_id=automated_email.vendor_id, subaccount_id=automated_email.subaccount_id, name=name, fandata_list_id=FanDataListId.from_custom_list_id(custom_list.id), type=automated_email.type, sender_name=automated_email.sender_name, email_domain_id=automated_email.email_domain_id, email_username=automated_email.email_username, subject=automated_email.subject, preview_text=automated_email.preview_text, ) ) assert result.global_participant_id is None assert result.custom_list_id == custom_list.id @pytest.mark.db def test_update_automated_email_invalid_domain( self, handler: UpdateAutomatedEmailHandler, build_model: BuildModel, create_model: CreateModel, identity_id: str, faker: faker.Faker, account: Account, ) -> None: vendor = build_model( Vendor, vendor_id=account.vendor_id, company_brand=Brand.SME ) name = faker.name() subject = faker.sentence() sender_name = faker.first_name() email_username = faker.user_name() preview_text = faker.sentence() global_participant_id = faker.uuid4() email_domain = create_model(EmailDomain, brand=vendor.brand) automated_email = create_model( AutomatedEmail, email_domain=email_domain, vendor_id=vendor.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, ) with pytest.raises(InvalidEmailDomainIdError): handler.handle( UpdateAutomatedEmailRequest( identity_id=identity_id, email_id=automated_email.id, vendor_id=vendor.vendor_id, subaccount_id=account.subaccount_id, name=name, fandata_list_id=FanDataListId.from_artist_id(global_participant_id), sender_name=sender_name, type=automated_email.type, email_domain_id=faker.uuid4(), email_username=email_username, subject=subject, preview_text=preview_text, ) ) @pytest.mark.db def test_update_automated_email_type_change_rejected( self, handler: UpdateAutomatedEmailHandler, create_model: CreateModel, identity_id: str, account: Account, faker: faker.Faker, ) -> None: global_participant_id = faker.uuid4() automated_email = create_model( AutomatedEmail, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, type=AutomatedEmailType.TRIGGERED, ) with pytest.raises(AutomatedEmailTypeChangeNotAllowedError): handler.handle( UpdateAutomatedEmailRequest( identity_id=identity_id, email_id=automated_email.id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, name=automated_email.name, fandata_list_id=FanDataListId.from_artist_id(global_participant_id), sender_name=automated_email.sender_name, type=AutomatedEmailType.OPT_IN, email_domain_id=automated_email.email_domain_id, email_username=automated_email.email_username, subject=automated_email.subject, preview_text=automated_email.preview_text, ) ) @pytest.mark.db def test_update_automated_email_sender_email_with_diacritics_rejected( self, handler: UpdateAutomatedEmailHandler, build_model: BuildModel, create_model: CreateModel, identity_id: str, account: Account, ows_account_client_mock: mock.MagicMock, faker: faker.Faker, ) -> None: vendor = build_model( Vendor, vendor_id=account.vendor_id, company_brand=Brand.SME ) name = faker.name() subject = faker.sentence() sender_name = "Chance Peña" email_username_with_diacritics = "chancepeña" preview_text = faker.sentence() global_participant_id = faker.uuid4() email_domain = create_model( EmailDomain, brand=vendor.brand, domain="sonymusic.com", vendor_id=None, subaccount_id=None, ) automated_email = create_model( AutomatedEmail, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, ) ows_account_client_mock.get_vendor.return_value = vendor with pytest.raises(AutomatedEmailSenderEmailNotValidError): handler.handle( UpdateAutomatedEmailRequest( identity_id=identity_id, email_id=automated_email.id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, name=name, fandata_list_id=FanDataListId.from_artist_id(global_participant_id), sender_name=sender_name, type=automated_email.type, email_domain_id=email_domain.id, email_username=email_username_with_diacritics, subject=subject, preview_text=preview_text, ) )