from datetime import timedelta import faker import pytest from dirty_equals import IsList, IsPartialDataclass from fansifter_common.utils import timezone from app.models import ( AudienceEmailFan, Campaign, CampaignBatch, Domain, DomainToISPMapping, FanPersonalDataDbt, FansifterTeamPersonalDataDbt, Profile, ) from app.repositories import BatchRecipientRepository from tests.unit.types import CreateModel class TestBatchRecipientRepository: @pytest.mark.db def test_create_bulk( self, repository: BatchRecipientRepository, create_model: CreateModel, faker: faker.Faker, ) -> None: audience_id = faker.uuid4() provider_1 = "google.com" provider_2 = "microsoft.com" # Create campaign domain domain = create_model(Domain, domain="sonymusic-pde.com") # Domain-to-ISP mapping create_model(DomainToISPMapping, domain="domain1.com", isp=provider_1) create_model(DomainToISPMapping, domain="domain2.com", isp=provider_2) # Create profiles profile_1 = create_model(Profile, email="fan1@domain1.com", first_name="Anna") profile_2 = create_model(Profile, email="fan2@domain2.com", first_name=None) profile_3 = create_model(Profile, email="fan3@domain2.com") profile_4 = create_model(Profile, email="fan4@domain3.com") # no ISP mapping profile_5 = create_model(Profile, email="fan4@domain1.com") # no ISP mapping # Create personal data records personal_data_1 = create_model(FanPersonalDataDbt, fan_email=profile_1.email) personal_data_2 = create_model(FanPersonalDataDbt, fan_email=profile_2.email) personal_data_3 = create_model(FanPersonalDataDbt, fan_email=profile_3.email) personal_data_4 = create_model(FanPersonalDataDbt, fan_email=profile_4.email) personal_data_5 = create_model(FanPersonalDataDbt, fan_email=profile_5.email) # Create audience email fans create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_1.fan_id, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_2.fan_id, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_3.fan_id, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_4.fan_id, ) # should be ignored create_model( AudienceEmailFan, audience_id=faker.uuid4(), fan_id=personal_data_5.fan_id, ) # Create campaign and batches campaign = create_model(Campaign, domain_id=domain.id, audience_id=audience_id) batch_1 = create_model( CampaignBatch, campaign_id=campaign.id, domain_id=domain.id, provider=provider_1, batch_size=1, ) batch_2 = create_model( CampaignBatch, campaign_id=campaign.id, domain_id=domain.id, provider=provider_2, batch_size=2, ) batch_3 = create_model( CampaignBatch, campaign_id=campaign.id, domain_id=domain.id, provider="OTHER", batch_size=1, ) # Create batch recipients repository.create_bulk(campaign_id=campaign.id, fansifter_only=False) recipients = repository.all() # Verify that recipients are correctly assigned to batches assert recipients == IsList( IsPartialDataclass( batch_id=batch_1.id, fan_id=personal_data_1.fan_id, fan_email=personal_data_1.fan_email, profile_id=profile_1.id, fan_first_name="Anna", ), IsPartialDataclass( batch_id=batch_2.id, fan_id=personal_data_2.fan_id, fan_email=personal_data_2.fan_email, profile_id=profile_2.id, fan_first_name=None, ), IsPartialDataclass( batch_id=batch_2.id, fan_id=personal_data_3.fan_id, fan_email=personal_data_3.fan_email, profile_id=profile_3.id, ), IsPartialDataclass( batch_id=batch_3.id, fan_id=personal_data_4.fan_id, fan_email=personal_data_4.fan_email, profile_id=profile_4.id, ), check_order=False, ) @pytest.mark.db def test_create_bulk_with_fan_email_allowed_domains( self, repository: BatchRecipientRepository, create_model: CreateModel, faker: faker.Faker, ) -> None: audience_id = faker.uuid4() # Create campaign domain domain = create_model(Domain, domain="sonymusic-pde.com") # Create profiles profile_1 = create_model(Profile, email="fan1@allowed-domain.com") profile_2 = create_model(Profile, email="fan2@restricted-domain.com") # Create personal data records personal_data_1 = create_model( FansifterTeamPersonalDataDbt, fan_email=profile_1.email ) personal_data_2 = create_model(FanPersonalDataDbt, fan_email=profile_2.email) # Create audience email fans create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_1.fan_id, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_2.fan_id, ) # Create campaign and batches campaign = create_model(Campaign, domain_id=domain.id, audience_id=audience_id) batch = create_model( CampaignBatch, campaign_id=campaign.id, domain_id=domain.id, provider="OTHER", batch_size=1, ) # Create batch recipients repository.create_bulk(campaign_id=campaign.id, fansifter_only=True) recipients = repository.all() assert recipients == IsList( IsPartialDataclass( batch_id=batch.id, fan_id=personal_data_1.fan_id, fan_email=personal_data_1.fan_email, profile_id=profile_1.id, ), ) @pytest.mark.db def test_create_bulk_with_duplicated_fan_emails( self, repository: BatchRecipientRepository, create_model: CreateModel, faker: faker.Faker, ) -> None: audience_id = faker.uuid4() # Create campaign domain domain = create_model(Domain, domain="sonymusic-pde.com") # Create profiles profile_1 = create_model(Profile, email="fan1@allowed-domain.com") profile_2 = create_model( Profile, email="fan2@allowed-domain.com", updated_at=timezone.now() ) # Duplicated profile create_model( Profile, email="fan2@allowed-domain.com", updated_at=timezone.now() - timedelta(minutes=1), ) # Create personal data records personal_data_1 = create_model(FanPersonalDataDbt, fan_email=profile_1.email) personal_data_2 = create_model(FanPersonalDataDbt, fan_email=profile_2.email) # Create audience email fans create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_1.fan_id, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_2.fan_id, ) # Create campaign and batches campaign = create_model(Campaign, domain_id=domain.id, audience_id=audience_id) batch = create_model( CampaignBatch, campaign_id=campaign.id, domain_id=domain.id, provider="OTHER", batch_size=2, ) # Create batch recipients repository.create_bulk(campaign_id=campaign.id, fansifter_only=False) recipients = repository.all() assert len(recipients) == 2 assert recipients == IsList( IsPartialDataclass( batch_id=batch.id, fan_id=personal_data_1.fan_id, fan_email=personal_data_1.fan_email, profile_id=profile_1.id, ), IsPartialDataclass( batch_id=batch.id, fan_id=personal_data_2.fan_id, fan_email=personal_data_2.fan_email, profile_id=profile_2.id, ), check_order=False, )