from unittest import mock import pytest from fansifter_common.auth.account import Account, AccountAccess from dmp.artists.handlers import GetArtistsHandler, GetArtistsRequest from dmp.fandata.models import ( AccountArtistFullFanDataAccessDbt, FansByArtistAccountDbt, GlobalFansByArtistDbt, ) from dmp.rosters.models import ArtistRosterLocalRep, ArtistRosterMainRep from tests.unit.faker import FakerTyped from tests.unit.types import CreateReportingModel class TestGetArtistsHandler: @pytest.mark.db def test_get_artists_empty( self, handler: GetArtistsHandler, identity_id: str ) -> None: response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 0 assert response.items == [] @pytest.mark.db def test_get_artists( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id + 1, subaccount_id=subaccount_id + 1, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist.global_participant_name assert artist_response.global_participant_id == artist.global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == artist.vendor_id assert artist_response.labels[0].subaccount_id == artist.subaccount_id @pytest.mark.db def test_get_artists_for_specific_artist( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, search=artist.global_participant_name, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist.global_participant_name assert artist_response.global_participant_id == artist.global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == artist.vendor_id assert artist_response.labels[0].subaccount_id == artist.subaccount_id @pytest.mark.db def test_get_artists_with_artist_team_access( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: fan_data_owner_vendor_id = fake.integer() fan_data_owner_subaccount_id = fake.integer() artist_team_vendor_id = fan_data_owner_vendor_id + 1000 artist_team_subaccount_id = fan_data_owner_subaccount_id + 1000 artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id, subaccount_id=fan_data_owner_subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id + 1, subaccount_id=fan_data_owner_subaccount_id + 1, ) create_reporting_model( AccountArtistFullFanDataAccessDbt, global_participant_id=artist.global_participant_id, vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, provider_vendor_id=None, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, ) ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist.global_participant_name assert artist_response.global_participant_id == artist.global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == artist.vendor_id assert artist_response.labels[0].subaccount_id == artist.subaccount_id @pytest.mark.db def test_get_artists_partial_search( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, search=artist.global_participant_name[:5], ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist.global_participant_name assert artist_response.global_participant_id == artist.global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == artist.vendor_id assert artist_response.labels[0].subaccount_id == artist.subaccount_id @pytest.mark.db def test_get_artists_with_artist_team_access_and_provider_vendor_id( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: fan_data_owner_vendor_id = fake.integer() fan_data_owner_subaccount_id = fake.integer() artist_team_vendor_id = fan_data_owner_vendor_id + 1000 artist_team_subaccount_id = fan_data_owner_subaccount_id + 1000 artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id, subaccount_id=fan_data_owner_subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id + 1, subaccount_id=fan_data_owner_subaccount_id + 1, ) create_reporting_model( AccountArtistFullFanDataAccessDbt, global_participant_id=artist.global_participant_id, vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, provider_vendor_id=fan_data_owner_vendor_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, ) ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist.global_participant_name assert artist_response.global_participant_id == artist.global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == artist.vendor_id assert artist_response.labels[0].subaccount_id == artist.subaccount_id @pytest.mark.db def test_get_artists_with_artist_team_access_returns_empty_when_no_access( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: fan_data_owner_vendor_id = fake.integer() fan_data_owner_subaccount_id = fake.integer() artist_team_vendor_id = fan_data_owner_vendor_id + 1000 artist_team_subaccount_id = fan_data_owner_subaccount_id + 1000 requesting_user_vendor_id = fan_data_owner_vendor_id + 2000 requesting_user_subaccount_id = fan_data_owner_subaccount_id + 2000 artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id, subaccount_id=fan_data_owner_subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id + 1, subaccount_id=fan_data_owner_subaccount_id + 1, ) create_reporting_model( AccountArtistFullFanDataAccessDbt, global_participant_id=artist.global_participant_id, vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, provider_vendor_id=None, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=requesting_user_vendor_id, subaccount_id=requesting_user_subaccount_id, ) ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 0 assert not response.items @pytest.mark.db def test_get_artists_with_artist_team_access_and_provider_vendor_id_returns_empty_when_no_access( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: fan_data_owner_vendor_id = fake.integer() fan_data_owner_subaccount_id = fake.integer() artist_team_vendor_id = fan_data_owner_vendor_id + 1000 artist_team_subaccount_id = fan_data_owner_subaccount_id + 1000 requesting_user_vendor_id = fan_data_owner_vendor_id + 2000 requesting_user_subaccount_id = fan_data_owner_subaccount_id + 2000 artist = create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id, subaccount_id=fan_data_owner_subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id + 1, subaccount_id=fan_data_owner_subaccount_id + 1, ) create_reporting_model( AccountArtistFullFanDataAccessDbt, global_participant_id=artist.global_participant_id, vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, provider_vendor_id=fan_data_owner_vendor_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=requesting_user_vendor_id, subaccount_id=requesting_user_subaccount_id, ) ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 0 assert not response.items @pytest.mark.db def test_get_artists_with_direct_access_and_artist_team_access( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: fan_data_owner_vendor_id = fake.integer() fan_data_owner_subaccount_id = fake.integer() artist_team_vendor_id = fan_data_owner_vendor_id + 1000 artist_team_subaccount_id = fan_data_owner_subaccount_id + 1000 direct_access_vendor_id = fan_data_owner_vendor_id + 2000 direct_access_subaccount_id = fan_data_owner_subaccount_id + 2000 artist_of_artist_team = create_reporting_model( FansByArtistAccountDbt, vendor_id=fan_data_owner_vendor_id, subaccount_id=fan_data_owner_subaccount_id, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=direct_access_vendor_id, subaccount_id=direct_access_subaccount_id, global_participant_id=artist_of_artist_team.global_participant_id, global_participant_name=artist_of_artist_team.global_participant_name, ) create_reporting_model( AccountArtistFullFanDataAccessDbt, global_participant_id=artist_of_artist_team.global_participant_id, vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, provider_vendor_id=None, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=artist_team_vendor_id, subaccount_id=artist_team_subaccount_id, ), Account( vendor_id=direct_access_vendor_id, subaccount_id=direct_access_subaccount_id, ), ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist_of_artist_team.global_participant_name assert ( artist_response.global_participant_id == artist_of_artist_team.global_participant_id ) assert len(artist_response.labels) == 2 assert artist_response.labels[0].vendor_id == fan_data_owner_vendor_id assert artist_response.labels[0].subaccount_id == fan_data_owner_subaccount_id assert artist_response.labels[1].vendor_id == direct_access_vendor_id assert artist_response.labels[1].subaccount_id == direct_access_subaccount_id @pytest.mark.db def test_get_artists_multiple_labels( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() artist_1 = create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, ) artist_2 = create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id + 1, subaccount_id=subaccount_id + 1, global_participant_id=artist_1.global_participant_id, global_participant_name=artist_1.global_participant_name, ) create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id + 2, subaccount_id=subaccount_id + 2, global_participant_id=artist_1.global_participant_id, global_participant_name=artist_1.global_participant_name, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account(vendor_id=vendor_id, subaccount_id=subaccount_id), Account(vendor_id=vendor_id + 1, subaccount_id=subaccount_id + 1), ], ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == artist_1.global_participant_name assert artist_response.global_participant_id == artist_1.global_participant_id assert len(artist_response.labels) == 2 assert artist_response.labels[0].vendor_id == artist_1.vendor_id assert artist_response.labels[0].subaccount_id == artist_1.subaccount_id assert artist_response.labels[1].vendor_id == artist_2.vendor_id assert artist_response.labels[1].subaccount_id == artist_2.subaccount_id @pytest.mark.db def test_get_artists_from_main_rep( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == vendor_id assert artist_response.labels[0].subaccount_id == subaccount_id @pytest.mark.db def test_get_artists_from_local_rep( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterLocalRep, global_participant_id=global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, country_code="US", ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == vendor_id assert artist_response.labels[0].subaccount_id == subaccount_id @pytest.mark.db def test_get_artists_from_both_main_and_local_rep( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id_1 = fake.integer() subaccount_id_1 = fake.integer() vendor_id_2 = fake.integer() subaccount_id_2 = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_participant_id, vendor_id=vendor_id_1, subaccount_id=subaccount_id_1, ) create_reporting_model( ArtistRosterLocalRep, global_participant_id=global_participant_id, vendor_id=vendor_id_2, subaccount_id=subaccount_id_2, country_code="US", ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account(vendor_id=vendor_id_1, subaccount_id=subaccount_id_1), Account(vendor_id=vendor_id_2, subaccount_id=subaccount_id_2), ] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 2 labels_set = { (label.vendor_id, label.subaccount_id) for label in artist_response.labels } assert labels_set == { (vendor_id_1, subaccount_id_1), (vendor_id_2, subaccount_id_2), } @pytest.mark.db def test_get_artists_same_label_in_main_and_local_rep( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) create_reporting_model( ArtistRosterLocalRep, global_participant_id=global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, country_code="US", ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == vendor_id assert artist_response.labels[0].subaccount_id == subaccount_id @pytest.mark.db def test_get_artists_no_duplicate_between_global_and_non_global( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( FansByArtistAccountDbt, vendor_id=vendor_id, subaccount_id=subaccount_id, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 1 assert artist_response.labels[0].vendor_id == vendor_id assert artist_response.labels[0].subaccount_id == subaccount_id @pytest.mark.db def test_get_artists_with_both_sme_and_non_sme_labels( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: non_sme_vendor_id = fake.integer() non_sme_subaccount_id = fake.integer() sme_vendor_id = fake.integer() sme_subaccount_id = fake.integer() global_participant_id = fake.uuid4_string() global_participant_name = fake.name() create_reporting_model( FansByArtistAccountDbt, vendor_id=non_sme_vendor_id, subaccount_id=non_sme_subaccount_id, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( GlobalFansByArtistDbt, global_participant_id=global_participant_id, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_participant_id, vendor_id=sme_vendor_id, subaccount_id=sme_subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[ Account( vendor_id=non_sme_vendor_id, subaccount_id=non_sme_subaccount_id ), Account(vendor_id=sme_vendor_id, subaccount_id=sme_subaccount_id), ] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert artist_response.global_participant_id == global_participant_id assert len(artist_response.labels) == 2 labels_set = { (label.vendor_id, label.subaccount_id) for label in artist_response.labels } assert labels_set == { (non_sme_vendor_id, non_sme_subaccount_id), (sme_vendor_id, sme_subaccount_id), } @pytest.mark.db def test_get_artists_search_works_with_global_artists( self, handler: GetArtistsHandler, auth_service_mock: mock.MagicMock, create_reporting_model: CreateReportingModel, identity_id: str, fake: FakerTyped, ) -> None: vendor_id = fake.integer() subaccount_id = fake.integer() global_participant_name = "Taylor Swift" global_artist = create_reporting_model( GlobalFansByArtistDbt, global_participant_name=global_participant_name, ) create_reporting_model( ArtistRosterMainRep, global_participant_id=global_artist.global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) other_artist = create_reporting_model( GlobalFansByArtistDbt, global_participant_name="Ed Sheeran", ) create_reporting_model( ArtistRosterMainRep, global_participant_id=other_artist.global_participant_id, vendor_id=vendor_id, subaccount_id=subaccount_id, ) auth_service_mock.authorize_for_permission.return_value = AccountAccess( accounts=[Account(vendor_id=vendor_id, subaccount_id=subaccount_id)] ) response = handler.handle( GetArtistsRequest( identity_id=identity_id, limit=10, offset=0, search="Taylor", ) ) assert response.total == 1 artist_response = response.items[0] assert artist_response.name == global_participant_name assert ( artist_response.global_participant_id == global_artist.global_participant_id )