import pytest from faker import Faker from email_campaigns.campaigns.handlers import GetCampaignAnalyticsHandler from email_campaigns.campaigns.models import EmailCampaign from email_campaigns.emails.exceptions import EmailNotFoundError from email_campaigns.emails.handlers import GetEmailAnalyticsRequest from email_campaigns.emails.models import ( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, EmailAnalyticsV3Dbt, ) from email_campaigns.emails.types import EmailAnalytics from tests.unit.types import CreateModel class TestGetCampaignAnalyticsHandler: @pytest.mark.db def test_get_campaign_analytics( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(EmailCampaign, name="Test Campaign") create_model( EmailAnalyticsV3Dbt, email_id=campaign.id, email_type=campaign.email_type, sends=10, drops=0, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, unique_bounces=0, unique_spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_opens_dropoff=0.6, unique_clicks_dropoff=0.5, ) create_model( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, email_type=campaign.email_type, global_participant_id=campaign.global_participant_id, custom_list_id=campaign.custom_list_id, avg_open_rate=0.8, avg_click_through_rate=0.8, avg_bounce_rate=0.1, avg_delivered_rate=0.9, avg_unique_clicks=6.0, avg_click_to_open_rate=0.2, avg_spam_complaints_rate=0.1, avg_unsubscribe_rate=0.0, ) response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == EmailAnalytics( email_id=campaign.id, email_type=campaign.email_type, campaign_id=campaign.id, sends=10, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, bounces=0, spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_clicks_dropoff=0.5, unique_opens_dropoff=0.6, bounce_rate_change=-0.1, spam_complaints_rate_change=0.0, unsubscribe_rate_change=0.0, open_rate_change=-0.2, delivered_rate_change=0.1, unique_clicks_change=-0.5, click_through_rate_change=-0.5, click_to_open_rate_change=0.1, ) @pytest.mark.db def test_get_campaign_analytics_wrong_campaign_id( self, handler: GetCampaignAnalyticsHandler, identity_id: str, faker: Faker, ) -> None: campaign_id = faker.uuid4() with pytest.raises(EmailNotFoundError): handler.handle( GetEmailAnalyticsRequest( email_id=campaign_id, identity_id=identity_id, ), ) @pytest.mark.db def test_get_campaign_analytics_empty_campaign_id( self, handler: GetCampaignAnalyticsHandler, identity_id: str, ) -> None: campaign_id = "" with pytest.raises(EmailNotFoundError): handler.handle( GetEmailAnalyticsRequest( email_id=campaign_id, identity_id=identity_id, ), ) @pytest.mark.db def test_get_campaign_analytics_no_metrics( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(EmailCampaign, name="Test Campaign") response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data is None @pytest.mark.db def test_get_campaign_analytics_no_benchmarks_data( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(EmailCampaign, name="Test Campaign") create_model( EmailAnalyticsV3Dbt, email_id=campaign.id, email_type=campaign.email_type, sends=10, drops=0, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, unique_bounces=0, unique_spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_opens_dropoff=0.6, unique_clicks_dropoff=0.5, ) response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == EmailAnalytics( email_id=campaign.id, email_type=campaign.email_type, campaign_id=campaign.id, sends=10, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, bounces=0, spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_clicks_dropoff=0.5, unique_opens_dropoff=0.6, bounce_rate_change=None, spam_complaints_rate_change=None, unsubscribe_rate_change=None, open_rate_change=None, delivered_rate_change=None, unique_clicks_change=None, click_through_rate_change=None, click_to_open_rate_change=None, ) @pytest.mark.db def test_get_campaign_analytics_no_metrics_data( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(EmailCampaign, name="Test Campaign") create_model( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, email_type=campaign.email_type, global_participant_id=campaign.global_participant_id, custom_list_id=campaign.custom_list_id, avg_open_rate=0.8, avg_click_through_rate=0.8, avg_bounce_rate=0.1, avg_delivered_rate=0.9, avg_unique_clicks=6, avg_click_to_open_rate=0.2, avg_spam_complaints_rate=0.1, avg_unsubscribe_rate=0.1, ) response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data is None @pytest.mark.db def test_get_campaign_analytics_for_custom_list( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: custom_list_id = "abcde12345" campaign = create_model( EmailCampaign, name="Test Campaign", global_participant_id=None, custom_list_id=custom_list_id, ) create_model( EmailAnalyticsV3Dbt, email_id=campaign.id, email_type=campaign.email_type, sends=10, drops=0, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, unique_bounces=0, unique_spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_opens_dropoff=0.6, unique_clicks_dropoff=0.5, ) create_model( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, email_type=campaign.email_type, global_participant_id=campaign.global_participant_id, custom_list_id=campaign.custom_list_id, avg_open_rate=0.8, avg_click_through_rate=0.8, avg_bounce_rate=0.1, avg_delivered_rate=0.9, avg_unique_clicks=6.0, avg_click_to_open_rate=0.2, avg_spam_complaints_rate=0.1, avg_unsubscribe_rate=0.0, ) response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == EmailAnalytics( campaign_id=campaign.id, email_id=campaign.id, email_type=campaign.email_type, sends=10, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, bounces=0, spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_clicks_dropoff=0.5, unique_opens_dropoff=0.6, bounce_rate_change=-0.1, spam_complaints_rate_change=0.0, unsubscribe_rate_change=0.0, open_rate_change=-0.2, delivered_rate_change=0.1, unique_clicks_change=-0.5, click_through_rate_change=-0.5, click_to_open_rate_change=0.1, ) @pytest.mark.db def test_division_by_zero_for_delivered_rate_change( self, handler: GetCampaignAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: custom_list_id = "abcde12345" campaign = create_model( EmailCampaign, name="Test Campaign", global_participant_id=None, custom_list_id=custom_list_id, ) create_model( EmailAnalyticsV3Dbt, email_id=campaign.id, email_type=campaign.email_type, sends=10, drops=0, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, unique_bounces=0, unique_spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_opens_dropoff=0.6, unique_clicks_dropoff=0.5, ) create_model( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, email_type=campaign.email_type, global_participant_id=campaign.global_participant_id, custom_list_id=campaign.custom_list_id, avg_open_rate=0.8, avg_click_through_rate=0.8, avg_bounce_rate=0.1, avg_delivered_rate=0.9, avg_unique_clicks=0.0, avg_click_to_open_rate=0.2, avg_spam_complaints_rate=0.1, avg_unsubscribe_rate=0.0, ) response = handler.handle( GetEmailAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == EmailAnalytics( campaign_id=campaign.id, email_id=campaign.id, email_type=campaign.email_type, sends=10, delivered=10, opens=6, clicks=3, unique_opens=6, unique_clicks=3, bounces=0, spam_complaints=1, unsubscribes=0, open_rate=0.6, delivered_rate=1.0, click_through_rate=0.3, click_to_open_rate=0.3, bounce_rate=0.0, spam_complaints_rate=0.1, unsubscribe_rate=0.0, unique_clicks_dropoff=0.5, unique_opens_dropoff=0.6, bounce_rate_change=-0.1, spam_complaints_rate_change=0.0, unsubscribe_rate_change=0.0, open_rate_change=-0.2, delivered_rate_change=0.1, unique_clicks_change=None, click_through_rate_change=-0.5, click_to_open_rate_change=0.1, )