import faker import pytest from dirty_equals import IsList, IsPartialDataclass from fansifter_common.utils import timezone from app.enums import CampaignStatus from app.models import ( AudienceEmailFan, Campaign, CampaignBatch, Domain, DomainToISPMapping, FanPersonalDataDbt, Profile, ) from app.repositories import CampaignBatchRepository from tests.unit.types import CreateModel class TestCampaignBatchRepository: @pytest.mark.db def test_create_bulk( self, repository: CampaignBatchRepository, create_model: CreateModel, faker: faker.Faker, ) -> None: audience_id = faker.uuid4() provider_1 = "google.com" provider_2 = "microsoft.com" # Create domain domain = create_model(Domain, domain="sonymusic-pde.com") # Create 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") profile_2 = create_model(Profile, email="fan2@domain2.com") profile_3 = create_model(Profile, email="fan3@domain2.com") profile_4 = create_model(Profile, email="fan4@domain3.com") # should be ignored profile_5 = create_model(Profile, email="fan5@domain1.com") # Create personal data 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) # should be ignored personal_data_6 = create_model(FanPersonalDataDbt, fan_email="fan6@domain4.com") # Create audience email fan 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, ) create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data_6.fan_id, ) # should be ignored create_model( AudienceEmailFan, audience_id=audience_id, fan_id=faker.uuid4(), ) create_model( AudienceEmailFan, audience_id=faker.uuid4(), fan_id=personal_data_5.fan_id, ) campaign = create_model(Campaign, domain_id=domain.id, audience_id=audience_id) repository.create_bulk(campaign_id=campaign.id, fansifter_only=False) assert repository.all() == IsList( IsPartialDataclass( campaign_id=campaign.id, domain_id=domain.id, provider=provider_1, batch_size=1, ), IsPartialDataclass( campaign_id=campaign.id, domain_id=domain.id, provider=provider_2, batch_size=2, ), IsPartialDataclass( campaign_id=campaign.id, domain_id=domain.id, provider="OTHER", batch_size=1, ), check_order=False, ) @pytest.mark.db def test_create_bulk_with_fan_email_allowed_domains( self, repository: CampaignBatchRepository, create_model: CreateModel, faker: faker.Faker, ) -> None: audience_id = faker.uuid4() # Create domain domain = create_model(Domain, domain="sonymusic-pde.com") # Create profile profile = create_model(Profile, email="fan1@domain1.com") # Create personal data personal_data = create_model(FanPersonalDataDbt, fan_email=profile.email) # Create audience email fan create_model( AudienceEmailFan, audience_id=audience_id, fan_id=personal_data.fan_id, ) campaign = create_model(Campaign, domain_id=domain.id, audience_id=audience_id) repository.create_bulk(campaign_id=campaign.id, fansifter_only=True) assert repository.all() == [] @pytest.mark.db def test_find_active_returns_only_in_progress_campaigns( self, repository: CampaignBatchRepository, create_model: CreateModel, ) -> None: # Active campaign campaign_active = create_model( Campaign, status=CampaignStatus.IN_PROGRESS, prepared_at=timezone.now(), cancelled_at=None, ) # Inactive campaigns campaign_completed = create_model( Campaign, status=CampaignStatus.SENT, prepared_at=timezone.now(), ) campaign_cancelled = create_model( Campaign, status=CampaignStatus.CANCELLED, prepared_at=timezone.now(), cancelled_at=timezone.now(), ) campaign_unprepared = create_model( Campaign, status=CampaignStatus.IN_PROGRESS, prepared_at=None, ) # Batches active_batch = create_model(CampaignBatch, campaign_id=campaign_active.id) create_model(CampaignBatch, campaign_id=campaign_completed.id) create_model(CampaignBatch, campaign_id=campaign_cancelled.id) create_model(CampaignBatch, campaign_id=campaign_unprepared.id) result = repository.find_active() assert result == IsList( active_batch, ) batch = result[0] assert batch.campaign is not None assert batch.campaign.id == campaign_active.id assert batch.campaign.status == CampaignStatus.IN_PROGRESS @pytest.mark.db def test_find_active_returns_empty_when_no_active( self, repository: CampaignBatchRepository, create_model: CreateModel, ) -> None: create_model( Campaign, status=CampaignStatus.SENT, prepared_at=timezone.now(), ) create_model( Campaign, status=CampaignStatus.CANCELLED, prepared_at=timezone.now(), cancelled_at=timezone.now(), ) result = repository.find_active() assert result == []