import datetime from unittest import mock import faker import freezegun import pytest from fansifter_common.utils import timezone from email_campaigns.audiences.enums import AudienceTarget from email_campaigns.audiences.models import Audience from email_campaigns.campaigns.enums import EmailCampaignStatus from email_campaigns.campaigns.exceptions import ( EmailCampaignMustBeDraftError, EmailCampaignSendAtMustBeFutureError, ) from email_campaigns.campaigns.handlers import ( ScheduleCampaignHandler, ScheduleCampaignRequest, ) from email_campaigns.campaigns.models import EmailCampaign from email_campaigns.emails.exceptions import EmailPrivacyFooterMissingError from email_campaigns.emails.models import EmailDomain from tests.unit.types import CreateModel, CreatePgModel class TestScheduleCampaignHandler: @pytest.mark.db @freezegun.freeze_time("2024-10-15 10:30:00") def test_schedule_campaign( self, handler: ScheduleCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, faker: faker.Faker, stripo_client_mock: mock.MagicMock, ) -> None: audience = create_pg_model(Audience, target=AudienceTarget.EMAIL, fan_count=100) email_domain = create_model(EmailDomain) email_username = faker.user_name() sender_name = faker.first_name() subject = faker.sentence() preview_text = faker.sentence() campaign = create_model( EmailCampaign, status=EmailCampaignStatus.DRAFT, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=audience.global_participant_id, audience_id=audience.id, sender_name=sender_name, subject=subject, preview_text=preview_text, email_domain=email_domain, email_username=email_username, ) send_at = timezone.now() + datetime.timedelta(minutes=11) send_at_timezone = "UTC" stripo_client_mock.compress.return_value = "compressed" handler.handle( ScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) ) assert campaign.status == EmailCampaignStatus.SCHEDULED assert campaign.send_at == send_at assert campaign.scheduled_at == timezone.now() assert campaign.send_at_timezone == send_at_timezone assert campaign.recipients_count == audience.fan_count assert campaign.compressed_content == "compressed" @pytest.mark.db def test_schedule_campaign_is_not_draft( self, handler: ScheduleCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, faker: faker.Faker, ) -> None: audience = create_pg_model(Audience) campaign = create_model( EmailCampaign, status=EmailCampaignStatus.IN_PROGRESS, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=audience.global_participant_id, ) send_at = faker.future_datetime(tzinfo=timezone.UTC) send_at_timezone = "UTC" with pytest.raises(EmailCampaignMustBeDraftError): handler.handle( ScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) ) @pytest.mark.db def test_schedule_campaign_send_at_must_be_future( self, handler: ScheduleCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, faker: faker.Faker, ) -> None: audience = create_pg_model(Audience, target=AudienceTarget.EMAIL) campaign = create_model( EmailCampaign, status=EmailCampaignStatus.DRAFT, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=audience.global_participant_id, ) send_at = faker.past_datetime(tzinfo=timezone.UTC) send_at_timezone = "UTC" with pytest.raises(EmailCampaignSendAtMustBeFutureError): handler.handle( ScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) ) @pytest.mark.db def test_schedule_campaign_without_privacy_footer( self, handler: ScheduleCampaignHandler, faker: faker.Faker, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, ) -> None: audience = create_pg_model(Audience, target=AudienceTarget.EMAIL, fan_count=100) email_domain = create_model(EmailDomain) email_username = faker.user_name() sender_name = faker.first_name() subject = faker.sentence() preview_text = faker.sentence() campaign = create_model( EmailCampaign, status=EmailCampaignStatus.DRAFT, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=audience.global_participant_id, audience_id=audience.id, sender_name=sender_name, subject=subject, preview_text=preview_text, email_domain=email_domain, email_username=email_username, html_content="", ) send_at = timezone.now() + datetime.timedelta(minutes=10) send_at_timezone = "UTC" with pytest.raises(EmailPrivacyFooterMissingError): handler.handle( ScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) )