import pytest from faker import Faker from email_campaigns.campaigns.handlers import GetCampaignLinkAnalyticsHandler from email_campaigns.campaigns.models import EmailCampaign from email_campaigns.emails.exceptions import EmailNotFoundError from email_campaigns.emails.handlers import GetEmailLinkAnalyticsRequest from email_campaigns.emails.models import ( EmailAnalyticsBenchmarkByAccountArtistV2Dbt, EmailAnalyticsBenchmarkByLinktV3Dbt, EmailAnalyticsV3Dbt, ) from tests.unit.types import CreateModel class TestGetCampaignLinkAnalyticsHandler: @pytest.mark.db def test_get_campaign_link_analytics( self, handler: GetCampaignLinkAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model( EmailCampaign, name="Test Campaign", custom_list_id=None ) 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, ) url1 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://www.awesome-artist.com", total_clicks=100, unique_clicks=50, percentage_of_total_clicks=0.4, ) url2 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://facebook.com/tickets", total_clicks=150, unique_clicks=100, percentage_of_total_clicks=0.6, ) response = handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == [ { "url": url2.url, "total_clicks": url2.total_clicks, "unique_clicks": url2.unique_clicks, "percentage_of_total_clicks": url2.percentage_of_total_clicks, }, { "url": url1.url, "total_clicks": url1.total_clicks, "unique_clicks": url1.unique_clicks, "percentage_of_total_clicks": url1.percentage_of_total_clicks, }, ] @pytest.mark.db def test_get_campaign_link_analytics_wrong_campaign_id( self, handler: GetCampaignLinkAnalyticsHandler, identity_id: str, faker: Faker, ) -> None: campaign_id = faker.uuid4() with pytest.raises(EmailNotFoundError): handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign_id, identity_id=identity_id, ), ) @pytest.mark.db def test_get_campaign_link_analytics_empty_campaign_id( self, handler: GetCampaignLinkAnalyticsHandler, identity_id: str, ) -> None: campaign_id = "" with pytest.raises(EmailNotFoundError): handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign_id, identity_id=identity_id, ), ) @pytest.mark.db def test_get_campaign_analytics_no_links( self, handler: GetCampaignLinkAnalyticsHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(EmailCampaign, name="Test Campaign") response = handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data is None @pytest.mark.db def test_get_campaign_link_analytics_for_custom_list( self, handler: GetCampaignLinkAnalyticsHandler, 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, ) url1 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://www.awesome-artist.com", total_clicks=100, unique_clicks=50, percentage_of_total_clicks=0.4, ) url2 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://facebook.com/tickets", total_clicks=150, unique_clicks=100, percentage_of_total_clicks=0.6, ) response = handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == [ { "url": url2.url, "total_clicks": url2.total_clicks, "unique_clicks": url2.unique_clicks, "percentage_of_total_clicks": url2.percentage_of_total_clicks, }, { "url": url1.url, "total_clicks": url1.total_clicks, "unique_clicks": url1.unique_clicks, "percentage_of_total_clicks": url1.percentage_of_total_clicks, }, ] @pytest.mark.db def test_get_campaign_link_analytics_correctly_sorted( self, handler: GetCampaignLinkAnalyticsHandler, 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, ) url1 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://www.awesome-artist.com", total_clicks=100, unique_clicks=50, percentage_of_total_clicks=0.25, ) url2 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://facebook.com/tickets", total_clicks=150, unique_clicks=100, percentage_of_total_clicks=0.375, ) url3 = create_model( EmailAnalyticsBenchmarkByLinktV3Dbt, email_id=campaign.id, email_type=campaign.email_type, url="http://youtube.com/channel/some_id", total_clicks=150, unique_clicks=67, percentage_of_total_clicks=0.375, ) response = handler.handle( GetEmailLinkAnalyticsRequest( email_id=campaign.id, identity_id=identity_id, ), ) assert response.data == [ { "url": url2.url, "total_clicks": url2.total_clicks, "unique_clicks": url2.unique_clicks, "percentage_of_total_clicks": url2.percentage_of_total_clicks, }, { "url": url3.url, "total_clicks": url3.total_clicks, "unique_clicks": url3.unique_clicks, "percentage_of_total_clicks": url3.percentage_of_total_clicks, }, { "url": url1.url, "total_clicks": url1.total_clicks, "unique_clicks": url1.unique_clicks, "percentage_of_total_clicks": url1.percentage_of_total_clicks, }, ]