from unittest import mock import faker import pytest from anydi import Container from fansifter_common.auth.account import Account from ows_text_campaigns.artist.models import ArtistPhoneNumber, ArtistSettings from ows_text_campaigns.audiences.enums import AudienceTarget, FanDataListType from ows_text_campaigns.audiences.exceptions import InvalidAudienceIdError from ows_text_campaigns.audiences.models import Audience, AudienceFanDataList from ows_text_campaigns.campaigns.enums import CampaignStatus from ows_text_campaigns.campaigns.exceptions import ( CampaignMustBeDraftError, MalformedCampaignError, ) from ows_text_campaigns.campaigns.handlers import ( UpdateCampaignHandler, UpdateCampaignRequest, ) from ows_text_campaigns.campaigns.models import Campaign from ows_text_campaigns.rosters.exceptions import MainRepArtistOnlyAllowedError from ows_text_campaigns.rosters.services import GlobalFanDataAccessService from tests.unit.types import CreateModel, CreatePgModel class TestUpdateCampaignHandler: @pytest.mark.db def test_update_campaign( self, handler: UpdateCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, account: Account, faker: faker.Faker, ) -> None: name = faker.name() global_participant_id = faker.uuid4() create_model( ArtistSettings, global_participant_id=global_participant_id, phone_numbers=[ ArtistPhoneNumber( global_participant_id=global_participant_id, phone_number=faker.phone_number(), ) ], ) audience = create_pg_model( Audience, target=AudienceTarget.TEXT, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, fan_count=100, fandata_lists=[ AudienceFanDataList( list_id=global_participant_id, type=FanDataListType.ARTIST ) ], ) campaign = create_model( Campaign, status=CampaignStatus.DRAFT, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, ) campaign = handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, name=name, audience_id=audience.id, ) ) assert campaign.name == name assert campaign.vendor_id == account.vendor_id assert campaign.subaccount_id == account.subaccount_id assert campaign.global_participant_id == audience.global_participant_id assert campaign.audience_id == audience.id assert campaign.audience == audience assert campaign.recipients_count == audience.fan_count assert campaign.updated_by == identity_id @pytest.mark.db def test_update_campaign_remove_audience( self, handler: UpdateCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, account: Account, faker: faker.Faker, ) -> None: name = faker.name() global_participant_id = faker.uuid4() create_model( ArtistSettings, global_participant_id=global_participant_id, phone_numbers=[ ArtistPhoneNumber( global_participant_id=global_participant_id, phone_number=faker.phone_number(), ) ], ) audience = create_pg_model( Audience, target=AudienceTarget.EMAIL, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, fan_count=100, fandata_lists=[ AudienceFanDataList( list_id=global_participant_id, type=FanDataListType.ARTIST ) ], ) campaign = create_model( Campaign, status=CampaignStatus.DRAFT, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, audience_id=audience.id, recipients_count=audience.fan_count, ) campaign = handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, name=name, audience_id=None, ) ) assert campaign.audience_id is None assert campaign.recipients_count is None @pytest.mark.db def test_update_campaign_must_be_draft( self, handler: UpdateCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, faker: faker.Faker, ) -> None: global_participant_id = faker.uuid4() audience = create_pg_model( Audience, target=AudienceTarget.EMAIL, fandata_lists=[ AudienceFanDataList( list_id=global_participant_id, type=FanDataListType.ARTIST ) ], ) campaign = create_model( Campaign, status=CampaignStatus.SENT, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=global_participant_id, ) with pytest.raises(CampaignMustBeDraftError): handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, global_participant_id=campaign.global_participant_id, name=campaign.name, audience_id=audience.id, ) ) @pytest.mark.db def test_update_campaign_invalid_audience_id( self, handler: UpdateCampaignHandler, create_model: CreateModel, identity_id: str, faker: faker.Faker, ) -> None: campaign = create_model(Campaign, status=CampaignStatus.DRAFT) with pytest.raises(InvalidAudienceIdError): handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=campaign.vendor_id, subaccount_id=campaign.subaccount_id, global_participant_id=campaign.global_participant_id, name=campaign.name, audience_id=faker.uuid4(), ) ) @pytest.mark.db def test_update_campaign_malformed( self, handler: UpdateCampaignHandler, create_model: CreateModel, create_pg_model: CreatePgModel, identity_id: str, faker: faker.Faker, ) -> None: global_participant_id = faker.uuid4() audience = create_pg_model( Audience, target=AudienceTarget.EMAIL, fandata_lists=[ AudienceFanDataList( list_id=global_participant_id, type=FanDataListType.ARTIST, ) ], ) campaign = create_model( Campaign, status=CampaignStatus.DRAFT, vendor_id=audience.vendor_id, subaccount_id=audience.subaccount_id, global_participant_id=global_participant_id, ) with pytest.raises(MalformedCampaignError): handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=campaign.vendor_id + 1, subaccount_id=campaign.subaccount_id, global_participant_id=campaign.global_participant_id, name=campaign.name, audience_id=audience.id, ) ) @pytest.mark.db def test_update_campaign_main_rep_required( self, container: Container, handler: UpdateCampaignHandler, create_model: CreateModel, identity_id: str, account: Account, faker: faker.Faker, ) -> None: name = faker.name() global_participant_id = faker.uuid4() create_model( ArtistSettings, global_participant_id=global_participant_id, phone_numbers=[ ArtistPhoneNumber( global_participant_id=global_participant_id, phone_number=faker.phone_number(), ) ], ) campaign = create_model( Campaign, status=CampaignStatus.DRAFT, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, ) global_fandata_access_service_mock = mock.MagicMock( spec=GlobalFanDataAccessService, is_enabled_for_vendor=mock.MagicMock(return_value=True), ) with ( container.override( GlobalFanDataAccessService, instance=global_fandata_access_service_mock, ), pytest.raises(MainRepArtistOnlyAllowedError) as exc_info, ): handler.handle( UpdateCampaignRequest( identity_id=identity_id, campaign_id=campaign.id, vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=global_participant_id, name=name, audience_id=None, ) ) assert exc_info.value.message == "Main Rep Artist Only Allowed" assert exc_info.value.global_participant_id == global_participant_id