import datetime 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 ( EmailCampaignMustBeScheduledError, EmailCampaignSendAtMustBeFutureError, ) from email_campaigns.campaigns.handlers import ( EditScheduleCampaignHandler, EditScheduleCampaignRequest, ) from email_campaigns.campaigns.models import EmailCampaign from email_campaigns.emails.models import EmailDomain from tests.unit.types import CreateModel, CreatePgModel class TestEditScheduleCampaignHandler: @pytest.mark.db @freezegun.freeze_time("2021-01-01 00:00:00") def test_edit_schedule_campaign( self, handler: EditScheduleCampaignHandler, create_pg_model: CreatePgModel, create_model: CreateModel, identity_id: str, faker: faker.Faker, ) -> 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.SCHEDULED, 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=9) send_at_timezone = "UTC" handler.handle( EditScheduleCampaignRequest( 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 @pytest.mark.db def test_schedule_campaign_is_not_in_scheduled_statuses( self, handler: EditScheduleCampaignHandler, create_pg_model: CreatePgModel, create_model: CreateModel, 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(EmailCampaignMustBeScheduledError): handler.handle( EditScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) ) @pytest.mark.db def test_edit_schedule_campaign_send_at_must_be_future( self, handler: EditScheduleCampaignHandler, 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.SCHEDULED, 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( EditScheduleCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, send_at=send_at, timezone=send_at_timezone, ) )