# mypy: disable-error-code=operator import decimal from decimal import Decimal from unittest import mock import pytest from dirty_equals import IsApprox from fansifter_common.auth.account import Account, AccountAccess from dmp.ad_reporting.enums import ( AdReportingBudgetType, AdReportingObjective, AdReportingPlatform, ) from dmp.ad_reporting.exceptions import AdReportingReportNotFoundError from dmp.ad_reporting.handlers import ( GetAdReportingReportCampaignsHandler, GetAdReportingReportCampaignsRequest, ) 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 TestGetAdReportingReportCampaignsHandler: @pytest.mark.db def test_get_report_campaigns( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, ) -> None: ad_account_1 = create_model(MetaAdAccount) ad_account_2 = create_model(MetaAdAccount) create_model( MetaUserAdAccount, ad_account_id=ad_account_1.id, identity_id=identity_id, ) create_model( MetaUserAdAccount, ad_account_id=ad_account_2.id, identity_id=identity_id, ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account_1.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, ) # This campaign should not be returned create_reporting_model( AdReportingCampaignDbt, account_id=ad_account_2.external_id, platform=AdReportingPlatform.META, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) assert response.summary.total == 1 assert response.items[0].id == campaign_1.id @pytest.mark.db def test_get_report_campaigns_with_country_filter_empty( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, auth_service_mock: mock.MagicMock, ) -> None: ad_account = create_model(MetaAdAccount) user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ] ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="GB", ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, countries=["US"], ) ) assert response.summary.total == 1 assert response.summary.clicks == 0 assert response.summary.spend_usd == 0 assert response.summary.reach is None assert response.summary.actions is None assert response.summary.rate is None assert len(response.items) == 1 assert response.items[0].accounts == {user_ad_account.account} assert response.items[0].clicks == 0 assert response.items[0].spend_usd == 0 assert response.items[0].reach is None assert response.items[0].frequency is None assert response.items[0].artist_benchmark is None assert response.items[0].benchmark is None assert response.items[0].vs_artist_benchmark is None @pytest.mark.db def test_get_report_campaigns_with_country_filter_recalculate_single_campaign( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, auth_service_mock: mock.MagicMock, ) -> None: ad_account = create_model(MetaAdAccount) user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ] ) campaign = create_reporting_model( AdReportingCampaignDbt, name="included_campaign", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, name="NOT_included_campaign", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, external_id=campaign.external_id, name="included_campaign", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="GB", ) campaign_country_1 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, external_id=campaign.external_id, name="included_campaign", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="US", estimated_ad_recallers=fake.integer(), ) campaign_country_2 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, external_id=campaign.external_id, name="included_campaign", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="EE", estimated_ad_recallers=fake.integer(), ) create_reporting_model( AdReportingCampaignCountryDbt, name="NOT_included_campaign", campaign_id=campaign_2.id, external_id=campaign_2.external_id, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="US", estimated_ad_recallers=fake.integer(), ) create_reporting_model( AdReportingCampaignCountryDbt, name="NOT_included_campaign", campaign_id=campaign_2.id, external_id=campaign_2.external_id, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="EE", estimated_ad_recallers=fake.integer(), ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, countries=["US", "EE"], ) ) assert response.summary.total == 1 assert ( response.summary.clicks == campaign_country_1.clicks + campaign_country_2.clicks ) assert campaign_country_1.reach and campaign_country_2.reach assert campaign_country_1.estimated_ad_recallers is not None assert campaign_country_2.estimated_ad_recallers is not None assert ( response.summary.reach == campaign_country_1.reach + campaign_country_2.reach ) assert ( response.summary.spend_usd == campaign_country_1.spend_usd + campaign_country_2.spend_usd ) assert response.summary.rate == IsApprox( Decimal( ( campaign_country_1.estimated_ad_recallers + campaign_country_2.estimated_ad_recallers ) / (campaign_country_1.reach + campaign_country_2.reach) ), delta=Decimal("0.001"), ) assert len(response.items) == 1 assert response.items[0].accounts == {user_ad_account.account} assert ( response.items[0].clicks == campaign_country_1.clicks + campaign_country_2.clicks ) assert ( response.items[0].reach == campaign_country_1.reach + campaign_country_2.reach ) assert ( response.items[0].spend_usd == campaign_country_1.spend_usd + campaign_country_2.spend_usd ) assert response.items[0].rate == IsApprox( Decimal( ( campaign_country_1.estimated_ad_recallers + campaign_country_2.estimated_ad_recallers ) / (campaign_country_1.reach + campaign_country_2.reach) ), delta=Decimal("0.001"), ) assert response.items[0].artist_benchmark is None assert response.items[0].benchmark is None assert response.items[0].vs_artist_benchmark is None @pytest.mark.db def test_get_report_campaigns_with_country_filter_multiple_campaigns( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, auth_service_mock: mock.MagicMock, ) -> None: ad_account = create_model(MetaAdAccount) user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ] ) campaign_1 = create_reporting_model( AdReportingCampaignDbt, name="a", account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) campaign_2 = create_reporting_model( AdReportingCampaignDbt, name="b", account_id=ad_account.external_id, platform=AdReportingPlatform.TIKTOK, objective=AdReportingObjective.VIDEO_VIEWS, impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), currency=campaign_1.currency, rate_type=campaign_1.rate_type, action_type=campaign_1.action_type, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_1.id, external_id=campaign_1.external_id, name=campaign_1.name, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="GB", impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) campaign_country_1 = create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_1.id, external_id=campaign_1.external_id, name=campaign_1.name, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="US", impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign_1.id, external_id=campaign_1.external_id, name=campaign_1.name, account_id=ad_account.external_id, platform=AdReportingPlatform.META, objective=AdReportingObjective.OUTCOME_AWARENESS, country_code="EE", impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) campaign_country_2 = create_reporting_model( AdReportingCampaignCountryDbt, name=campaign_2.name, campaign_id=campaign_2.id, external_id=campaign_2.external_id, account_id=ad_account.external_id, platform=AdReportingPlatform.TIKTOK, objective=AdReportingObjective.VIDEO_VIEWS, country_code="US", impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) create_reporting_model( AdReportingCampaignCountryDbt, name=campaign_2.name, campaign_id=campaign_2.id, account_id=ad_account.external_id, platform=AdReportingPlatform.TIKTOK, objective=AdReportingObjective.VIDEO_VIEWS, country_code="GB", impressions=fake.integer(length=5), follows=fake.integer(length=5), clicks=fake.integer(length=5), views=fake.integer(length=5), estimated_ad_recallers=fake.integer(length=5), purchases=fake.integer(length=5), ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign_1.id, campaign_2.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.desc"], limit=10, offset=0, countries=["US"], ) ) assert response.summary.total == 2 assert ( response.summary.clicks == campaign_country_1.clicks + campaign_country_2.clicks ) assert ( response.summary.impressions == campaign_country_1.impressions + campaign_country_2.impressions ) assert campaign_country_1.reach and campaign_country_2.reach assert ( response.summary.reach == campaign_country_1.reach + campaign_country_2.reach ) assert ( response.summary.estimated_ad_recallers and campaign_country_1.estimated_ad_recallers and campaign_country_2.estimated_ad_recallers ) assert ( response.summary.estimated_ad_recallers == campaign_country_1.estimated_ad_recallers + campaign_country_2.estimated_ad_recallers ) assert ( response.summary.views_p25 == campaign_country_1.views_p25 + campaign_country_2.views_p25 ) assert ( response.summary.views == campaign_country_1.views + campaign_country_2.views ) assert ( response.summary.purchases and campaign_country_1.purchases and campaign_country_2.purchases ) assert ( response.summary.purchases == int(campaign_country_1.purchases) + campaign_country_2.purchases ) assert ( response.summary.follows and campaign_country_1.follows and campaign_country_2.follows ) assert ( response.summary.follows == campaign_country_1.follows + campaign_country_2.follows ) assert ( response.summary.spend_usd == campaign_country_1.spend_usd + campaign_country_2.spend_usd ) assert response.summary.actions is None assert response.summary.action_type == campaign_1.action_type assert response.summary.rate is None assert response.summary.rate_type == campaign_1.rate_type assert response.summary.cost_per_action_usd is None assert response.summary.cost_per_action is None assert response.summary.frequency == IsApprox( decimal.Decimal( (campaign_country_1.impressions + campaign_country_2.impressions) / (campaign_country_1.reach + campaign_country_2.reach) ) ) assert campaign_1.daily_budget is not None assert campaign_2.daily_budget is not None assert ( response.summary.budget == campaign_1.daily_budget + campaign_2.daily_budget ) assert response.summary.budget_type == AdReportingBudgetType.DAILY_BUDGET assert len(response.items) == 2 assert response.items[0].id == campaign_2.id assert response.items[0].account_id == ad_account.external_id assert response.items[0].accounts == {user_ad_account.account} assert response.items[0].action_type == campaign_2.action_type assert response.items[0].currency == campaign_2.currency assert response.items[0].effective_status == campaign_2.effective_status assert response.items[0].end_at == campaign_2.end_at assert response.items[0].external_id == campaign_2.external_id assert ( response.items[0].global_participant_ids == campaign_2.global_participant_ids ) assert response.items[0].name == campaign_2.name assert response.items[0].objective == campaign_2.objective assert response.items[0].platform == campaign_2.platform assert response.items[0].rate_type == campaign_2.rate_type assert response.items[0].start_at == campaign_2.start_at assert response.items[0].targeting_countries == set( campaign_2.targeting_countries ) assert response.items[0].actions == campaign_country_2.actions assert response.items[0].clicks == campaign_country_2.clicks assert response.items[0].cost_per_action == IsApprox( decimal.Decimal(campaign_country_2.spend / campaign_country_2.actions) ) assert response.items[0].cost_per_action_usd == IsApprox( decimal.Decimal(campaign_country_2.spend_usd / campaign_country_2.actions) ) assert ( response.items[0].estimated_ad_recallers == campaign_country_2.estimated_ad_recallers ) assert response.items[0].follows == campaign_country_2.follows assert response.items[0].frequency == IsApprox( decimal.Decimal(campaign_country_2.impressions / campaign_country_2.reach) ) assert response.items[0].impressions == campaign_country_2.impressions assert response.items[0].purchases == campaign_country_2.purchases assert response.items[0].rate == IsApprox( Decimal((campaign_country_2.views or 0) / campaign_country_2.impressions), delta=Decimal("0.001"), ) assert response.items[0].reach == campaign_country_2.reach assert response.items[0].spend == campaign_country_2.spend assert response.items[0].spend_usd == campaign_country_2.spend_usd assert response.items[0].views == campaign_country_2.views assert response.items[0].views_p25 == campaign_country_2.views_p25 assert response.items[0].artist_benchmark is None assert response.items[0].benchmark is None assert response.items[0].vs_artist_benchmark is None assert response.items[0].vs_artist_benchmark is None assert response.items[1].id == campaign_1.id assert response.items[1].account_id == ad_account.external_id assert response.items[1].accounts == {user_ad_account.account} assert response.items[1].action_type == campaign_1.action_type assert response.items[1].currency == campaign_1.currency assert response.items[1].effective_status == campaign_1.effective_status assert response.items[1].end_at == campaign_1.end_at assert response.items[1].external_id == campaign_1.external_id assert ( response.items[1].global_participant_ids == campaign_1.global_participant_ids ) assert response.items[1].name == campaign_1.name assert response.items[1].objective == campaign_1.objective assert response.items[1].platform == campaign_1.platform assert response.items[1].rate_type == campaign_1.rate_type assert response.items[1].start_at == campaign_1.start_at assert response.items[1].targeting_countries == set( campaign_1.targeting_countries ) assert response.items[1].actions == campaign_country_1.actions assert response.items[1].clicks == campaign_country_1.clicks assert response.items[1].cost_per_action == IsApprox( decimal.Decimal(campaign_country_1.spend / campaign_country_1.actions) ) assert response.items[1].cost_per_action_usd == IsApprox( decimal.Decimal(campaign_country_1.spend_usd / campaign_country_1.actions) ) assert ( response.items[1].estimated_ad_recallers == campaign_country_1.estimated_ad_recallers ) assert response.items[1].follows == campaign_country_1.follows assert campaign_country_1.reach assert response.items[1].frequency == IsApprox( decimal.Decimal(campaign_country_1.impressions / campaign_country_1.reach) ) assert response.items[1].impressions == campaign_country_1.impressions assert response.items[1].purchases == campaign_country_1.purchases assert response.items[1].rate == IsApprox( Decimal( (campaign_country_1.estimated_ad_recallers or 0) / campaign_country_1.reach ), delta=Decimal("0.001"), ) assert response.items[1].reach == campaign_country_1.reach assert response.items[1].spend == campaign_country_1.spend assert response.items[1].spend_usd == campaign_country_1.spend_usd assert response.items[1].views == campaign_country_1.views assert response.items[1].views_p25 == campaign_country_1.views_p25 assert response.items[1].artist_benchmark is None assert response.items[1].benchmark is None assert response.items[1].vs_artist_benchmark is None assert response.items[1].vs_artist_benchmark is None @pytest.mark.db def test_get_report_campaigns_with_country_filter_showing_benchmarks( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, auth_service_mock: mock.MagicMock, ) -> None: ad_account = create_model(MetaAdAccount) global_participant_id = fake.uuid4_string() country_code = fake.country() platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, ) ] ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, global_participant_id=global_participant_id, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, account_id=ad_account.external_id, platform=platform, objective=objective, country_code=country_code, global_participant_id=global_participant_id, ) benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, country_code=country_code, platform=platform, objective=objective, ) artist_benchmark = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code=country_code, platform=platform, objective=objective, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, countries=[country_code], ) ) assert len(response.items) == 1 assert response.items[0].benchmark == benchmark.rate assert response.items[0].artist_benchmark == artist_benchmark.rate @pytest.mark.db def test_get_report_campaigns_with_country_filter_not_showing_benchmarks( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: ad_account = create_model(MetaAdAccount) global_participant_id = fake.uuid4_string() country_1 = fake.uuid4_string() country_2 = fake.uuid4_string() platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, global_participant_id=global_participant_id, ) create_reporting_model( AdReportingCampaignCountryDbt, campaign_id=campaign.id, account_id=ad_account.external_id, platform=platform, objective=objective, country_code=country_1, global_participant_id=global_participant_id, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountCountryDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, country_code=country_1, platform=platform, objective=objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistCountryDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, global_participant_id=global_participant_id, country_code=country_1, platform=platform, objective=objective, ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id}, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, countries=[country_1, country_2], ) ) assert len(response.items) == 1 assert response.items[0].artist_benchmark is None assert response.items[0].benchmark is None @pytest.mark.db def test_get_report_campaigns_not_found( self, handler: GetAdReportingReportCampaignsHandler, identity_id: str, fake: FakerTyped, ) -> None: with pytest.raises(AdReportingReportNotFoundError): handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=fake.uuid4_string(), search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) @pytest.mark.db def test_get_ad_reporting_report_campaigns_single_bm( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, account: Account, fake: FakerTyped, ) -> None: ad_account = create_model(MetaAdAccount) user_ad_account = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_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(), ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id} ) bm = create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) artist_bm = create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account.vendor_id, subaccount_id=user_ad_account.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=campaign.global_participant_id, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) assert response assert response.items assert response.items[0].benchmark == bm.rate assert response.items[0].vs_benchmark == campaign.rate - bm.rate assert response.items[0].artist_benchmark == artist_bm.rate assert response.items[0].vs_artist_benchmark == campaign.rate - artist_bm.rate @pytest.mark.db def test_get_ad_reporting_report_campaigns_multiple_bm( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS global_participant_id_1 = fake.uuid4_string() global_participant_id_2 = fake.uuid4_string() ad_account = create_model(MetaAdAccount) user_ad_account_1 = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id ) 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=platform, objective=objective, _global_participant_ids=[global_participant_id_1, global_participant_id_2], ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id} ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_1, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_2, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) assert response assert response.items assert response.items[0].benchmark is None assert response.items[0].vs_benchmark is None assert response.items[0].artist_benchmark is None assert response.items[0].vs_artist_benchmark is None @pytest.mark.db def test_get_ad_reporting_report_campaigns_single_vendor_access( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, auth_service_mock: mock.MagicMock, identity_id: str, fake: FakerTyped, ) -> None: platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS global_participant_id_1 = fake.uuid4_string() ad_account = create_model(MetaAdAccount) user_ad_account_1 = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id ) user_ad_account_2 = create_model(MetaUserAdAccount, ad_account_id=ad_account.id) account = Account( vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[account] ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, _global_participant_ids=[global_participant_id_1], ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id} ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_1, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_1, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) assert response assert response.items assert response.items[0].accounts == {account} @pytest.mark.db def test_get_ad_reporting_report_campaigns_multiple_vendor_access( self, handler: GetAdReportingReportCampaignsHandler, create_model: CreateModel, create_reporting_model: CreateReportingModel, auth_service_mock: mock.MagicMock, identity_id: str, fake: FakerTyped, ) -> None: platform = AdReportingPlatform.META objective = AdReportingObjective.OUTCOME_AWARENESS global_participant_id_1 = fake.uuid4_string() ad_account = create_model(MetaAdAccount) user_ad_account_1 = create_model( MetaUserAdAccount, ad_account_id=ad_account.id, identity_id=identity_id ) user_ad_account_2 = create_model(MetaUserAdAccount, ad_account_id=ad_account.id) account_1 = Account( vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, ) account_2 = Account( vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[account_1, account_2] ) campaign = create_reporting_model( AdReportingCampaignDbt, account_id=ad_account.external_id, platform=platform, objective=objective, _global_participant_ids=[global_participant_id_1], ) report = create_reporting_model( AdReportingReport, identity_id=identity_id, campaign_ids={campaign.id} ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_1.vendor_id, subaccount_id=user_ad_account_1.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_1, ) create_reporting_model( AdReportingCampaignBenchmarkByAccountArtistDbt, vendor_id=user_ad_account_2.vendor_id, subaccount_id=user_ad_account_2.subaccount_id, platform=campaign.platform, objective=campaign.objective, global_participant_id=global_participant_id_1, ) response = handler.handle( GetAdReportingReportCampaignsRequest( identity_id=identity_id, report_id=report.id, search=None, global_participant_id=None, platform=None, objective=None, order_by=["name.asc"], limit=10, offset=0, ) ) assert response assert response.items assert response.items[0].accounts == {account_1, account_2}