from unittest import mock import faker import pytest from fansifter_common.exceptions import InvalidInputError from fansifter_common.identifiers.types import FansifterProfileIdentifier from preference_center.profile.exceptions import ( ProfileBirthdayUpdateNotAllowedError, ProfileDateOfBirthUpdateNotAllowedError, ProfileEmailAlreadyInUseError, ) from preference_center.profile.handlers import ( UpdateProfileHandler, UpdateProfileRequest, ) from preference_center.profile.models import Profile from tests.unit.types import CreateModel, CreateProfileToken class TestUpdateProfileHandler: @pytest.mark.db def test_update_profile( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, faker: faker.Faker, ) -> None: updated_by = faker.pystr() profile = create_model(Profile) token = create_profile_token( FansifterProfileIdentifier.model_construct( profile_id=profile.id, impersonated_by=updated_by ) ) email = faker.email() first_name = faker.first_name() last_name = faker.last_name() phone_number = faker.phone_number() date_of_birth = faker.date_of_birth(minimum_age=18) result = handler.handle( UpdateProfileRequest( ip_country="EE", token=token, values={ "email": email, "first_name": first_name, "last_name": last_name, "phone_number": phone_number, "date_of_birth": date_of_birth, }, ) ) assert result.id == profile.id assert result.first_name == first_name assert result.last_name == last_name assert result.email == email assert result.phone_number == phone_number assert result.date_of_birth == date_of_birth assert result.updated_by == updated_by @pytest.mark.db def test_update_profile_kafka_message_published( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, producer_mock: mock.MagicMock, faker: faker.Faker, ) -> None: profile = create_model(Profile, first_name=None) token = create_profile_token( FansifterProfileIdentifier.model_construct(profile_id=profile.id) ) first_name = faker.first_name() result = handler.handle( UpdateProfileRequest( ip_country="US", token=token, values={ "first_name": first_name, }, ) ) assert result.id == profile.id assert result.first_name == first_name producer_mock.publish.assert_called_once() @pytest.mark.db def test_update_profile_kafka_message_not_published( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, producer_mock: mock.MagicMock, faker: faker.Faker, ) -> None: first_name = faker.first_name() profile = create_model(Profile, first_name=first_name) token = create_profile_token(FansifterProfileIdentifier(profileId=profile.id)) result = handler.handle( UpdateProfileRequest( ip_country="EE", token=token, values={ "first_name": first_name, }, ) ) assert result.id == profile.id assert result.first_name == first_name producer_mock.publish.assert_not_called() @pytest.mark.db def test_update_profile_email_update( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, faker: faker.Faker, ) -> None: old_email = faker.email() new_email = faker.email() profile = create_model(Profile, email=old_email) token = create_profile_token(FansifterProfileIdentifier(profileId=profile.id)) result = handler.handle( UpdateProfileRequest( ip_country="US", token=token, values={ "email": new_email, }, ) ) assert result.email == new_email @pytest.mark.db def test_update_profile_email_must_be_unique( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, ) -> None: other_profile = create_model(Profile) profile = create_model(Profile) token = create_profile_token(FansifterProfileIdentifier(profileId=profile.id)) with pytest.raises(InvalidInputError) as exc: handler.handle( UpdateProfileRequest( ip_country="US", token=token, values={ "email": other_profile.email, }, ) ) assert exc.value.field_errors == { "email": { "message": ProfileEmailAlreadyInUseError.message, "code": ProfileEmailAlreadyInUseError.code, } } @pytest.mark.db def test_update_profile_date_of_birth_update_not_allowed( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, faker: faker.Faker, ) -> None: profile = create_model(Profile) token = create_profile_token(FansifterProfileIdentifier(profileId=profile.id)) date_of_birth = faker.date_of_birth(minimum_age=18) with pytest.raises(ProfileDateOfBirthUpdateNotAllowedError): handler.handle( UpdateProfileRequest( ip_country="US", token=token, values={ "date_of_birth": date_of_birth, }, ) ) @pytest.mark.db def test_update_profile_birthday_update_not_allowed( self, handler: UpdateProfileHandler, create_model: CreateModel, create_profile_token: CreateProfileToken, faker: faker.Faker, ) -> None: profile = create_model(Profile) token = create_profile_token(FansifterProfileIdentifier(profileId=profile.id)) birthday = faker.date_of_birth(minimum_age=18).strftime("%m/%d") with pytest.raises(ProfileBirthdayUpdateNotAllowedError): handler.handle( UpdateProfileRequest( ip_country="EE", token=token, values={ "birthday": birthday, }, ) )