from unittest import mock import faker import pytest from anydi import Container from fansifter_common.identifiers.types import ( CRMProfileIdentifier, FansifterProfileIdentifier, ) from preference_center.profile.cache import ProfileCache from preference_center.profile.exceptions import ProfileNotFoundError from preference_center.profile.models import Profile from preference_center.profile.services import ProfileService from tests.unit.faker import FakerTyped from tests.unit.types import CreateModel class TestProfileService: @pytest.mark.db def test_get_profile_by_fansifter_identifier( self, service: ProfileService, create_model: CreateModel ) -> None: profile = create_model(Profile) identifier = FansifterProfileIdentifier.model_construct(profile_id=profile.id) result = service.get_profile_by_identifier(identifier) assert result == profile @pytest.mark.db def test_get_profile_by_crm_identifier( self, service: ProfileService, create_model: CreateModel, faker: faker.Faker, ) -> None: crm_id = faker.pystr() profile = create_model(Profile, crm_id=crm_id) identifier = CRMProfileIdentifier.model_construct(crm_id=crm_id) result = service.get_profile_by_identifier(identifier) assert result == profile @pytest.mark.db def test_get_profile_by_crm_identifier_not_found( self, service: ProfileService, faker: faker.Faker ) -> None: crm_id = faker.pystr() identifier = CRMProfileIdentifier.model_construct(crm_id=crm_id) with pytest.raises(ProfileNotFoundError): service.get_profile_by_identifier(identifier) @pytest.mark.db def test_get_profile_by_crm_identifier_deleted( self, service: ProfileService, create_model: CreateModel, faker: faker.Faker, ) -> None: crm_id = faker.pystr() create_model(Profile, crm_id=crm_id, deleted=True) identifier = CRMProfileIdentifier.model_construct(crm_id=crm_id) with pytest.raises(ProfileNotFoundError): service.get_profile_by_identifier(identifier) def test_get_crm_identifier( self, service: ProfileService, fake: FakerTyped ) -> None: crm_id = fake.pystr() identifier = CRMProfileIdentifier.model_construct(crm_id=crm_id) token = service.encode_profile_identifier(identifier) assert service.decode_profile_identifier(token) == identifier @pytest.mark.db def test_get_profile_by_identifier_cached_miss( self, service: ProfileService, create_model: CreateModel, container: Container ) -> None: profile = create_model(Profile) identifier = FansifterProfileIdentifier.model_construct(profile_id=profile.id) cache_mock = mock.MagicMock() cache_mock.get_profile.return_value = None with container.override(ProfileCache, cache_mock): result = service.get_profile_by_identifier_cached(identifier) assert result == profile cache_mock.get_profile.assert_called_once_with(identifier) cache_mock.set_profile.assert_called_once_with(identifier, profile=profile) @pytest.mark.db def test_get_profile_by_identifier_cached_hit( self, service: ProfileService, create_model: CreateModel, container: Container ) -> None: profile = create_model(Profile) identifier = FansifterProfileIdentifier.model_construct(profile_id=profile.id) cache_mock = mock.MagicMock() cache_mock.get_profile.return_value = profile with container.override(ProfileCache, cache_mock): result = service.get_profile_by_identifier_cached(identifier) assert result == profile cache_mock.get_profile.assert_called_once_with(identifier) cache_mock.set_profile.assert_not_called() @pytest.mark.db def test_get_profile_by_identifier_cached_deleted( self, service: ProfileService, create_model: CreateModel, container: Container ) -> None: profile = create_model(Profile, deleted=True) identifier = FansifterProfileIdentifier.model_construct(profile_id=profile.id) cache_mock = mock.MagicMock() cache_mock.get_profile.return_value = profile with ( container.override(ProfileCache, cache_mock), pytest.raises(ProfileNotFoundError), ): service.get_profile_by_identifier_cached(identifier) cache_mock.get_profile.assert_called_once_with(identifier)