from datetime import UTC, datetime, timedelta from unittest import mock import faker import pytest from dirty_equals import IsList from fansifter_common.auth.account import Account, AccountAccess from ows_text_campaigns.api.schemas import AgeRange, Gender from ows_text_campaigns.campaigns.dtos import CampaignAnalytics from ows_text_campaigns.campaigns.handlers import ( GetCampaignsHandler, GetCampaignsRequest, ) from ows_text_campaigns.campaigns.models import ( Campaign, CampaignSendsCountryAggregated, UrlShortenerClicksGenderAgeAggregated, ) from tests.unit.types import CreateModel class TestGetCampaignsHandler: @pytest.mark.db def test_get_campaigns( self, handler: GetCampaignsHandler, create_model: CreateModel, auth_service_mock: mock.MagicMock, faker: faker.Faker, identity_id: str, ) -> None: vendor_id_1 = faker.pyint() vendor_id_2 = faker.pyint() now = datetime.now(UTC) text_campaign_1 = create_model( Campaign, name="Test Campaign", vendor_id=vendor_id_1, subaccount_id=0, send_at=now, ) text_campaign_2 = create_model( Campaign, name="Test Campaign 2", vendor_id=vendor_id_2, subaccount_id=0, send_at=now - timedelta(days=1), ) create_model(Campaign, name="Test Campaign 3") auth_service_mock.authorize_for_permission = mock.Mock( return_value=AccountAccess( accounts=[ Account(vendor_id=vendor_id_1, subaccount_id=0), Account(vendor_id=vendor_id_2, subaccount_id=0), ], ) ) response = handler.handle( GetCampaignsRequest( identity_id=identity_id, search=None, vendor_id=None, subaccount_id=None, global_participant_ids=None, statuses=None, order_by=["sendAt.desc"], limit=10, offset=0, ) ) assert response.total == 2 assert response.items == IsList(text_campaign_1, text_campaign_2) assert response.items[0].analytics == CampaignAnalytics( campaign_id=text_campaign_1.id, clicks=0, click_through_rate=0.0, ) assert response.items[1].analytics == CampaignAnalytics( campaign_id=text_campaign_2.id, clicks=0, click_through_rate=0.0, ) @pytest.mark.db def test_get_campaigns_analytics( self, handler: GetCampaignsHandler, create_model: CreateModel, auth_service_mock: mock.MagicMock, faker: faker.Faker, identity_id: str, ) -> None: vendor_id_1 = faker.pyint() campaign = create_model( Campaign, name="Test Campaign", vendor_id=vendor_id_1, subaccount_id=0, recipients_count=100, ) redirect_url = "https://example.com/redirect" create_model( UrlShortenerClicksGenderAgeAggregated, campaign_id=campaign.id, redirect_url=redirect_url, gender=Gender.MALE, age_range=AgeRange.FROM_18_TO_22, clicks=50, ) create_model( CampaignSendsCountryAggregated, campaign_id=campaign.id, country_code="US", sends=100, ) auth_service_mock.authorize_for_permission = mock.Mock( return_value=AccountAccess( accounts=[ Account(vendor_id=vendor_id_1, subaccount_id=0), ], ) ) response = handler.handle( GetCampaignsRequest( identity_id=identity_id, search=None, vendor_id=None, subaccount_id=None, global_participant_ids=None, statuses=None, order_by=["sendAt.desc"], limit=10, offset=0, ) ) assert response.total == 1 assert response.items == IsList(campaign, check_order=False) assert response.items[0].analytics is not None assert response.items[0].analytics.clicks == 50 assert response.items[0].analytics.click_through_rate == 0.5 @pytest.mark.db def test_get_campaigns_analytics_multiple_urls( self, handler: GetCampaignsHandler, create_model: CreateModel, auth_service_mock: mock.MagicMock, faker: faker.Faker, identity_id: str, ) -> None: vendor_id_1 = faker.pyint() campaign = create_model( Campaign, name="Test Campaign", vendor_id=vendor_id_1, subaccount_id=0, recipients_count=100, ) redirect_url_1 = "https://example.com/redirect" redirect_url_2 = "https://example.com/redirect2" create_model( UrlShortenerClicksGenderAgeAggregated, campaign_id=campaign.id, redirect_url=redirect_url_1, gender=Gender.MALE, age_range=AgeRange.FROM_18_TO_22, clicks=50, ) create_model( UrlShortenerClicksGenderAgeAggregated, campaign_id=campaign.id, redirect_url=redirect_url_2, gender=Gender.MALE, age_range=AgeRange.FROM_18_TO_22, clicks=70, ) create_model( CampaignSendsCountryAggregated, campaign_id=campaign.id, country_code="US", sends=140, ) auth_service_mock.authorize_for_permission = mock.Mock( return_value=AccountAccess( accounts=[ Account(vendor_id=vendor_id_1, subaccount_id=0), ], ) ) response = handler.handle( GetCampaignsRequest( identity_id=identity_id, search=None, vendor_id=None, subaccount_id=None, global_participant_ids=None, statuses=None, order_by=["sendAt.desc"], limit=10, offset=0, ) ) assert response.total == 1 assert response.items == IsList(campaign) assert response.items[0].analytics is not None assert response.items[0].analytics.clicks == 70 assert response.items[0].analytics.click_through_rate == 0.5