from datetime import timedelta import pytest from fansifter_common.utils import timezone from dmp.ad_reporting.enums import AdReportingObjective, AdReportingPlatform from dmp.ad_reporting.handlers import ( GetAdReportingReportOverviewHandler, GetAdReportingReportOverviewRequest, ) from dmp.ad_reporting.models import ( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, AdReportingCampaignBenchmarkByAccountArtistDbt, AdReportingCampaignBenchmarkByAccountCountryDbt, AdReportingCampaignBenchmarkByAccountDbt, AdReportingCampaignCountryDbt, AdReportingCampaignDbt, AdReportingReport, ) from dmp.meta.models import MetaAdAccount, MetaUserAdAccount from tests.unit.faker import FakerTyped from tests.unit.types import CreateModel, CreateReportingModel class TestGetAdReportingReportOverviewHandler: @pytest.mark.db def test_get_report_overview( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=fake.uuid4_string(), ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=campaign_1.platform, objective=campaign_1.objective, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=campaign_1.first_global_participant_id, ) benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, ) artist_benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_1.first_global_participant_id, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert response.impressions == campaign_1.impressions + campaign_2.impressions assert response.clicks == campaign_1.clicks + campaign_2.clicks assert response.views_p25 == campaign_1.views_p25 + campaign_2.views_p25 assert response.views == campaign_1.views + campaign_2.views assert response.spend_usd == campaign_1.spend_usd + campaign_2.spend_usd assert len(response.topline_performance) == 1 assert len(response.topline_country_performance) == 0 topline_performance = response.topline_performance[0] assert topline_performance.platform == AdReportingPlatform.META assert topline_performance.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance.campaigns_count == 2 assert topline_performance.start_at == campaign_1.start_at assert topline_performance.end_at == campaign_2.end_at assert topline_performance.impressions == ( campaign_1.impressions + campaign_2.impressions ) assert topline_performance.clicks == (campaign_1.clicks + campaign_2.clicks) assert campaign_1.reach and campaign_2.reach assert topline_performance.reach == campaign_1.reach + campaign_2.reach assert topline_performance.views_p25 == ( campaign_1.views_p25 + campaign_2.views_p25 ) assert topline_performance.views == (campaign_1.views + campaign_2.views) assert topline_performance.purchases == ( (campaign_1.purchases or 0) + (campaign_2.purchases or 0) ) assert topline_performance.estimated_ad_recallers == ( (campaign_1.estimated_ad_recallers or 0) + (campaign_2.estimated_ad_recallers or 0) ) assert topline_performance.spend_usd == ( campaign_1.spend_usd + campaign_2.spend_usd ) assert topline_performance.benchmark == benchmark.rate assert ( topline_performance.vs_benchmark == topline_performance.rate - benchmark.rate ) assert topline_performance.artist_benchmark == artist_benchmark.rate assert ( topline_performance.vs_artist_benchmark == topline_performance.rate - artist_benchmark.rate ) @pytest.mark.db def test_get_report_overview_country( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS ad_account = create_model(MetaAdAccount) global_participant_id = fake.uuid4_string() meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=global_participant_id, ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=platform, objective=objective, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=global_participant_id, ) campaign_country_1 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_1.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="US", ) campaign_country_2 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_2.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="US", ) campaign_country_3 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_2.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="GB", ) country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="GB", ) country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="US", ) artist_country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_1.first_global_participant_id, country_code="GB", ) artist_country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_2.first_global_participant_id, country_code="US", ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 1 assert len(response.topline_country_performance) == 2 topline_performance_1 = response.topline_country_performance[0] # GB topline_performance_2 = response.topline_country_performance[1] # US assert topline_performance_1.platform == AdReportingPlatform.META assert topline_performance_1.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_1.country_code == "GB" assert topline_performance_1.campaigns_count == 1 assert topline_performance_1.impressions == campaign_country_3.impressions assert topline_performance_1.clicks == campaign_country_3.clicks assert topline_performance_1.reach == campaign_country_3.reach assert topline_performance_1.views_p25 == campaign_country_3.views_p25 assert topline_performance_1.views == campaign_country_3.views assert topline_performance_1.purchases == campaign_country_3.purchases or 0 assert ( topline_performance_1.estimated_ad_recallers == campaign_country_3.estimated_ad_recallers or 0 ) assert topline_performance_1.spend_usd == campaign_country_3.spend_usd assert topline_performance_1.benchmark == country_benchmark_1.rate assert ( topline_performance_1.vs_benchmark == topline_performance_1.rate - country_benchmark_1.rate ) assert topline_performance_1.artist_benchmark == artist_country_benchmark_1.rate assert ( topline_performance_1.vs_artist_benchmark == topline_performance_1.rate - artist_country_benchmark_1.rate ) assert topline_performance_2.platform == AdReportingPlatform.META assert topline_performance_2.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_2.country_code == "US" assert topline_performance_2.campaigns_count == 2 assert topline_performance_2.impressions == ( campaign_country_1.impressions + campaign_country_2.impressions ) assert topline_performance_2.clicks == ( campaign_country_1.clicks + campaign_country_2.clicks ) assert campaign_country_1.reach and campaign_country_2.reach assert ( topline_performance_2.reach == campaign_country_1.reach + campaign_country_2.reach ) assert topline_performance_2.views_p25 == ( campaign_country_1.views_p25 + campaign_country_2.views_p25 ) assert topline_performance_2.views == ( campaign_country_1.views + campaign_country_2.views ) assert topline_performance_2.purchases == ( (campaign_country_1.purchases or 0) + (campaign_country_2.purchases or 0) ) assert topline_performance_2.estimated_ad_recallers == ( (campaign_country_1.estimated_ad_recallers or 0) + (campaign_country_2.estimated_ad_recallers or 0) ) assert topline_performance_2.spend_usd == ( campaign_country_1.spend_usd + campaign_country_2.spend_usd ) assert topline_performance_2.benchmark == country_benchmark_2.rate assert ( topline_performance_2.vs_benchmark == topline_performance_2.rate - country_benchmark_2.rate ) assert topline_performance_2.artist_benchmark == artist_country_benchmark_2.rate assert ( topline_performance_2.vs_artist_benchmark == topline_performance_2.rate - artist_country_benchmark_2.rate ) @pytest.mark.db def test_get_report_overview_country_without_impressions( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS ad_account = create_model(MetaAdAccount) global_participant_id = fake.uuid4_string() meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=global_participant_id, ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=platform, objective=objective, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=global_participant_id, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_1.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="US", impressions=0, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_2.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="US", impressions=0, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_2.id, platform=platform, objective=objective, global_participant_id=global_participant_id, country_code="GB", impressions=0, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="GB", ) create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="US", ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_1.first_global_participant_id, country_code="GB", ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_2.first_global_participant_id, country_code="US", ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 1 assert not response.topline_country_performance @pytest.mark.db def test_get_report_overview_multiple_objectives( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=fake.uuid4_string(), ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=AdReportingPlatform.TIKTOK, objective=AdReportingObjective.ENGAGEMENT, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=campaign_1.first_global_participant_id, ) benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, ) benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign_2.platform, objective=campaign_2.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, ) artist_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_1.first_global_participant_id, ) artist_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign_2.platform, objective=campaign_2.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=campaign_1.first_global_participant_id, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert response.impressions == campaign_1.impressions + campaign_2.impressions assert response.clicks == campaign_1.clicks + campaign_2.clicks assert response.views_p25 == campaign_1.views_p25 + campaign_2.views_p25 assert response.views == campaign_1.views + campaign_2.views assert response.spend_usd == campaign_1.spend_usd + campaign_2.spend_usd assert len(response.topline_performance) == 2 assert len(response.topline_country_performance) == 0 topline_performance_1 = response.topline_performance[0] assert topline_performance_1.platform == AdReportingPlatform.META assert topline_performance_1.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_1.campaigns_count == 1 assert topline_performance_1.start_at == campaign_1.start_at assert topline_performance_1.end_at == campaign_1.end_at assert topline_performance_1.impressions == campaign_1.impressions assert topline_performance_1.clicks == campaign_1.clicks assert topline_performance_1.reach == campaign_1.reach assert topline_performance_1.views_p25 == campaign_1.views_p25 assert topline_performance_1.views == campaign_1.views assert topline_performance_1.purchases == campaign_1.purchases assert topline_performance_1.follows == campaign_1.follows assert ( topline_performance_1.estimated_ad_recallers == campaign_1.estimated_ad_recallers ) assert topline_performance_1.spend_usd == campaign_1.spend_usd assert topline_performance_1.benchmark == benchmark_1.rate assert ( topline_performance_1.vs_benchmark == topline_performance_1.rate - benchmark_1.rate ) assert topline_performance_1.artist_benchmark == artist_benchmark_1.rate assert ( topline_performance_1.vs_artist_benchmark == topline_performance_1.rate - artist_benchmark_1.rate ) topline_performance_2 = response.topline_performance[1] assert topline_performance_2.platform == AdReportingPlatform.TIKTOK assert topline_performance_2.objective == AdReportingObjective.ENGAGEMENT assert topline_performance_2.campaigns_count == 1 assert topline_performance_2.start_at == campaign_2.start_at assert topline_performance_2.end_at == campaign_2.end_at assert topline_performance_2.impressions == campaign_2.impressions assert topline_performance_2.clicks == campaign_2.clicks assert topline_performance_2.reach == campaign_2.reach assert topline_performance_2.views_p25 == campaign_2.views_p25 assert topline_performance_2.views == campaign_2.views assert topline_performance_2.purchases == campaign_2.purchases assert topline_performance_2.follows == campaign_2.follows assert ( topline_performance_2.estimated_ad_recallers == campaign_2.estimated_ad_recallers ) assert topline_performance_2.spend_usd == campaign_2.spend_usd assert topline_performance_2.benchmark == benchmark_2.rate assert ( topline_performance_2.vs_benchmark == topline_performance_2.rate - benchmark_2.rate ) assert topline_performance_2.artist_benchmark == artist_benchmark_2.rate assert ( topline_performance_2.vs_artist_benchmark == topline_performance_2.rate - artist_benchmark_2.rate ) @pytest.mark.db def test_get_report_overview_country_multiple_objectives( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() platform = AdReportingPlatform.TIKTOK objective_1 = AdReportingObjective.OUTCOME_AWARENESS objective_2 = AdReportingObjective.OUTCOME_LEADS global_participant_id = fake.uuid4_string() ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective_1, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=global_participant_id, ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=platform, objective=objective_2, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=global_participant_id, ) campaign_country_1 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="US", campaign_id=campaign_1.id, platform=platform, objective=campaign_1.objective, global_participant_id=global_participant_id, ) campaign_country_2 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="US", campaign_id=campaign_2.id, platform=platform, objective=campaign_2.objective, global_participant_id=global_participant_id, ) campaign_country_3 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="GB", campaign_id=campaign_2.id, platform=platform, objective=campaign_2.objective, global_participant_id=global_participant_id, ) country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective_2, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="GB", ) country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform, objective=objective_2, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="US", ) artist_country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective_1, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code="US", ) artist_country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform, objective=objective_2, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code="US", ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 2 assert len(response.topline_country_performance) == 3 topline_performance_1 = response.topline_country_performance[0] topline_performance_2 = response.topline_country_performance[1] topline_performance_3 = response.topline_country_performance[2] assert topline_performance_1.platform == AdReportingPlatform.TIKTOK assert topline_performance_1.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_1.country_code == "US" assert topline_performance_1.campaigns_count == 1 assert topline_performance_1.impressions == campaign_country_1.impressions assert topline_performance_1.clicks == campaign_country_1.clicks assert topline_performance_1.reach == campaign_country_1.reach assert topline_performance_1.views_p25 == campaign_country_1.views_p25 assert topline_performance_1.views == campaign_country_1.views assert topline_performance_1.purchases == campaign_country_1.purchases or 0 assert ( topline_performance_1.estimated_ad_recallers == campaign_country_1.estimated_ad_recallers or 0 ) assert topline_performance_1.spend_usd == campaign_country_1.spend_usd assert topline_performance_1.benchmark is None assert topline_performance_1.vs_benchmark is None assert topline_performance_1.artist_benchmark == artist_country_benchmark_1.rate assert ( topline_performance_1.vs_artist_benchmark == topline_performance_1.rate - artist_country_benchmark_1.rate ) assert topline_performance_2.platform == AdReportingPlatform.TIKTOK assert topline_performance_2.objective == AdReportingObjective.OUTCOME_LEADS assert topline_performance_2.country_code == "GB" assert topline_performance_2.campaigns_count == 1 assert topline_performance_2.impressions == campaign_country_3.impressions assert topline_performance_2.clicks == campaign_country_3.clicks assert topline_performance_2.reach == campaign_country_3.reach assert topline_performance_2.views_p25 == campaign_country_3.views_p25 assert topline_performance_2.views == campaign_country_3.views assert topline_performance_2.purchases == campaign_country_3.purchases or 0 assert ( topline_performance_2.estimated_ad_recallers == campaign_country_3.estimated_ad_recallers or 0 ) assert topline_performance_2.spend_usd == campaign_country_3.spend_usd assert topline_performance_2.benchmark == country_benchmark_1.rate assert ( topline_performance_2.vs_benchmark == topline_performance_2.rate - country_benchmark_1.rate ) assert topline_performance_2.artist_benchmark is None assert topline_performance_2.vs_artist_benchmark is None assert topline_performance_3.platform == AdReportingPlatform.TIKTOK assert topline_performance_3.objective == AdReportingObjective.OUTCOME_LEADS assert topline_performance_3.country_code == "US" assert topline_performance_3.campaigns_count == 1 assert topline_performance_3.impressions == campaign_country_2.impressions assert topline_performance_3.clicks == campaign_country_2.clicks assert topline_performance_3.reach == campaign_country_2.reach assert topline_performance_3.views_p25 == campaign_country_2.views_p25 assert topline_performance_3.views == campaign_country_2.views assert topline_performance_3.purchases == campaign_country_2.purchases or 0 assert ( topline_performance_3.estimated_ad_recallers == campaign_country_2.estimated_ad_recallers or 0 ) assert topline_performance_3.spend_usd == campaign_country_2.spend_usd assert topline_performance_3.benchmark == country_benchmark_2.rate assert ( topline_performance_3.vs_benchmark == topline_performance_3.rate - country_benchmark_2.rate ) assert topline_performance_3.artist_benchmark == artist_country_benchmark_2.rate assert ( topline_performance_3.vs_artist_benchmark == topline_performance_3.rate - artist_country_benchmark_2.rate ) @pytest.mark.db def test_get_report_overview_country_multiple_platforms( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: dt_now = timezone.now() platform_1 = AdReportingPlatform.META platform_2 = AdReportingPlatform.TIKTOK objective = AdReportingObjective.OUTCOME_AWARENESS global_participant_id = fake.uuid4_string() ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform_1, objective=objective, start_at=dt_now + timedelta(days=1), end_at=dt_now + timedelta(days=10), global_participant_id=global_participant_id, ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, platform=platform_2, objective=objective, start_at=campaign_1.start_at + timedelta(days=1), end_at=campaign_1.end_at + timedelta(days=1), global_participant_id=global_participant_id, ) campaign_country_1 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="US", campaign_id=campaign_1.id, platform=campaign_1.platform, objective=campaign_1.objective, global_participant_id=global_participant_id, ) campaign_country_2 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="US", campaign_id=campaign_2.id, platform=campaign_2.platform, objective=campaign_2.objective, global_participant_id=global_participant_id, ) campaign_country_3 = create_reporting_model( AdReportingCampaignCountryDbt, country_code="GB", campaign_id=campaign_2.id, platform=campaign_2.platform, objective=campaign_2.objective, global_participant_id=global_participant_id, ) country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform_2, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="GB", ) country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, platform=platform_2, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, country_code="US", ) artist_country_benchmark_1 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform_1, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code="US", ) artist_country_benchmark_2 = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, platform=platform_2, objective=objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code="US", ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 2 assert len(response.topline_country_performance) == 3 topline_performance_1 = response.topline_country_performance[0] topline_performance_2 = response.topline_country_performance[1] topline_performance_3 = response.topline_country_performance[2] assert topline_performance_1.platform == AdReportingPlatform.META assert topline_performance_1.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_1.country_code == "US" assert topline_performance_1.campaigns_count == 1 assert topline_performance_1.impressions == campaign_country_1.impressions assert topline_performance_1.clicks == campaign_country_1.clicks assert topline_performance_1.reach == campaign_country_1.reach assert topline_performance_1.views_p25 == campaign_country_1.views_p25 assert topline_performance_1.views == campaign_country_1.views assert topline_performance_1.purchases == campaign_country_1.purchases or 0 assert ( topline_performance_1.estimated_ad_recallers == campaign_country_1.estimated_ad_recallers or 0 ) assert topline_performance_1.spend_usd == campaign_country_1.spend_usd assert topline_performance_1.benchmark is None assert topline_performance_1.vs_benchmark is None assert topline_performance_1.artist_benchmark == artist_country_benchmark_1.rate assert ( topline_performance_1.vs_artist_benchmark == topline_performance_1.rate - artist_country_benchmark_1.rate ) assert topline_performance_2.platform == AdReportingPlatform.TIKTOK assert topline_performance_2.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_2.country_code == "GB" assert topline_performance_2.campaigns_count == 1 assert topline_performance_2.impressions == campaign_country_3.impressions assert topline_performance_2.clicks == campaign_country_3.clicks assert topline_performance_2.reach == campaign_country_3.reach assert topline_performance_2.views_p25 == campaign_country_3.views_p25 assert topline_performance_2.views == campaign_country_3.views assert topline_performance_2.purchases == campaign_country_3.purchases or 0 assert ( topline_performance_2.estimated_ad_recallers == campaign_country_3.estimated_ad_recallers or 0 ) assert topline_performance_2.spend_usd == campaign_country_3.spend_usd assert topline_performance_2.benchmark == country_benchmark_1.rate assert ( topline_performance_2.vs_benchmark == topline_performance_2.rate - country_benchmark_1.rate ) assert topline_performance_2.artist_benchmark is None assert topline_performance_2.vs_artist_benchmark is None assert topline_performance_3.platform == AdReportingPlatform.TIKTOK assert topline_performance_3.objective == AdReportingObjective.OUTCOME_AWARENESS assert topline_performance_3.country_code == "US" assert topline_performance_3.campaigns_count == 1 assert topline_performance_3.impressions == campaign_country_2.impressions assert topline_performance_3.clicks == campaign_country_2.clicks assert topline_performance_3.reach == campaign_country_2.reach assert topline_performance_3.views_p25 == campaign_country_2.views_p25 assert topline_performance_3.views == campaign_country_2.views assert topline_performance_3.purchases == campaign_country_2.purchases or 0 assert ( topline_performance_3.estimated_ad_recallers == campaign_country_2.estimated_ad_recallers or 0 ) assert topline_performance_3.spend_usd == campaign_country_2.spend_usd assert topline_performance_3.benchmark == country_benchmark_2.rate assert ( topline_performance_3.vs_benchmark == topline_performance_3.rate - country_benchmark_2.rate ) assert topline_performance_3.artist_benchmark == artist_country_benchmark_2.rate assert ( topline_performance_3.vs_artist_benchmark == topline_performance_3.rate - artist_country_benchmark_2.rate ) @pytest.mark.db def test_get_report_overview_benchmark_with_multiple_account( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: ad_account = create_model(MetaAdAccount) meta_user_ad_account_1 = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, ) meta_user_ad_account_2 = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, global_participant_id=fake.uuid4_string(), ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account_1.vendor_id, subaccount_id=meta_user_ad_account_1.subaccount_id, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account_2.vendor_id, subaccount_id=meta_user_ad_account_2.subaccount_id, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account_1.vendor_id, subaccount_id=meta_user_ad_account_1.subaccount_id, global_participant_id=campaign.first_global_participant_id, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 1 assert len(response.topline_country_performance) == 0 topline_performance = response.topline_performance[0] assert topline_performance.benchmark is None assert topline_performance.vs_benchmark is None assert topline_performance.artist_benchmark is None assert topline_performance.vs_artist_benchmark is None @pytest.mark.db def test_get_report_overview_artist_benchmark_with_multiple_account( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, ) global_participant_id_1 = fake.uuid4_string() global_participant_id_2 = fake.uuid4_string() campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, _global_participant_ids={ global_participant_id_1, global_participant_id_2, }, ) benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id_1, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign.platform, objective=campaign.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id_2, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 1 assert len(response.topline_country_performance) == 0 topline_performance = response.topline_performance[0] assert topline_performance.benchmark == benchmark.rate assert topline_performance.artist_benchmark is None @pytest.mark.db def test_get_report_overview_artist_benchmark_without_all_artists_set( self, handler: GetAdReportingReportOverviewHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: ad_account = create_model(MetaAdAccount) meta_user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, ) global_participant_id = fake.uuid4_string() campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, _global_participant_ids=[global_participant_id], ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, account_id=campaign_1.external_id, platform=campaign_1.platform, objective=campaign_1.objective, ) benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, platform=campaign_1.platform, objective=campaign_1.objective, vendor_id=meta_user_ad_account.vendor_id, subaccount_id=meta_user_ad_account.subaccount_id, global_participant_id=global_participant_id, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportOverviewRequest( identity_id=identity_id, report_id=report.id, ) ) assert len(response.topline_performance) == 1 assert len(response.topline_country_performance) == 0 topline_performance = response.topline_performance[0] assert topline_performance.benchmark == benchmark.rate assert topline_performance.artist_benchmark is None