diff --git a/open_city_profile/consts.py b/open_city_profile/consts.py index b8518b3f..616a1165 100644 --- a/open_city_profile/consts.py +++ b/open_city_profile/consts.py @@ -1,5 +1,4 @@ # Common errors -API_NOT_IMPLEMENTED_ERROR = "API_NOT_IMPLEMENTED_ERROR" GENERAL_ERROR = "GENERAL_ERROR" OBJECT_DOES_NOT_EXIST_ERROR = "OBJECT_DOES_NOT_EXIST_ERROR" INVALID_EMAIL_FORMAT_ERROR = "INVALID_EMAIL_FORMAT" @@ -21,6 +20,7 @@ SERVICE_CONNECTION_ALREADY_EXISTS_ERROR = "SERVICE_CONNECTION_ALREADY_EXISTS_ERROR" SERVICE_CONNECTION_DOES_NOT_EXIST_ERROR = "SERVICE_CONNECTION_DOES_NOT_EXIST_ERROR" SERVICE_NOT_IDENTIFIED_ERROR = "SERVICE_NOT_IDENTIFIED_ERROR" +PROFILE_ALREADY_EXISTS_FOR_USER_ERROR = "PROFILE_ALREADY_EXISTS_FOR_USER_ERROR" PROFILE_MUST_HAVE_PRIMARY_EMAIL = "PROFILE_MUST_HAVE_PRIMARY_EMAIL" # Service specific GDPR errors diff --git a/open_city_profile/exceptions.py b/open_city_profile/exceptions.py index 734fe88b..bf9a8083 100644 --- a/open_city_profile/exceptions.py +++ b/open_city_profile/exceptions.py @@ -8,8 +8,8 @@ class ProfileGraphQLError(GraphQLError): # Open city profile -class APINotImplementedError(ProfileGraphQLError): - """The functionality is not yet implemented""" +class ProfileAlreadyExistsForUserError(ProfileGraphQLError): + """Profile already exists for the user""" class ConnectedServiceDataQueryFailedError(GraphQLError): diff --git a/open_city_profile/views.py b/open_city_profile/views.py index d0923f5b..cf3d3102 100644 --- a/open_city_profile/views.py +++ b/open_city_profile/views.py @@ -8,7 +8,6 @@ from helusers.oidc import AuthenticationError from open_city_profile.consts import ( - API_NOT_IMPLEMENTED_ERROR, CONNECTED_SERVICE_DATA_QUERY_FAILED_ERROR, CONNECTED_SERVICE_DELETION_FAILED_ERROR, CONNECTED_SERVICE_DELETION_NOT_ALLOWED_ERROR, @@ -19,6 +18,7 @@ MISSING_GDPR_API_TOKEN_ERROR, OBJECT_DOES_NOT_EXIST_ERROR, PERMISSION_DENIED_ERROR, + PROFILE_ALREADY_EXISTS_FOR_USER_ERROR, PROFILE_DOES_NOT_EXIST_ERROR, PROFILE_MUST_HAVE_PRIMARY_EMAIL, SERVICE_CONNECTION_ALREADY_EXISTS_ERROR, @@ -29,13 +29,13 @@ VALIDATION_ERROR, ) from open_city_profile.exceptions import ( - APINotImplementedError, ConnectedServiceDataQueryFailedError, ConnectedServiceDeletionFailedError, ConnectedServiceDeletionNotAllowedError, DataConflictError, InvalidEmailFormatError, MissingGDPRApiTokenError, + ProfileAlreadyExistsForUserError, ProfileDoesNotExistError, ProfileGraphQLError, ProfileMustHavePrimaryEmailError, @@ -52,7 +52,6 @@ ObjectDoesNotExist: OBJECT_DOES_NOT_EXIST_ERROR, TokenExpiredError: TOKEN_EXPIRED_ERROR, PermissionDenied: PERMISSION_DENIED_ERROR, - APINotImplementedError: API_NOT_IMPLEMENTED_ERROR, ValidationError: VALIDATION_ERROR, graphene_validator.errors.ValidationGraphQLError: VALIDATION_ERROR, InvalidEmailFormatError: INVALID_EMAIL_FORMAT_ERROR, @@ -64,6 +63,7 @@ ConnectedServiceDataQueryFailedError: CONNECTED_SERVICE_DATA_QUERY_FAILED_ERROR, ConnectedServiceDeletionFailedError: CONNECTED_SERVICE_DELETION_FAILED_ERROR, ConnectedServiceDeletionNotAllowedError: CONNECTED_SERVICE_DELETION_NOT_ALLOWED_ERROR, + ProfileAlreadyExistsForUserError: PROFILE_ALREADY_EXISTS_FOR_USER_ERROR, ProfileDoesNotExistError: PROFILE_DOES_NOT_EXIST_ERROR, ProfileMustHavePrimaryEmailError: PROFILE_MUST_HAVE_PRIMARY_EMAIL, MissingGDPRApiTokenError: MISSING_GDPR_API_TOKEN_ERROR, diff --git a/profiles/schema.py b/profiles/schema.py index 6f1c9ff6..1cc6b041 100644 --- a/profiles/schema.py +++ b/profiles/schema.py @@ -35,10 +35,10 @@ staff_required, ) from open_city_profile.exceptions import ( - APINotImplementedError, ConnectedServiceDeletionFailedError, ConnectedServiceDeletionNotAllowedError, InvalidEmailFormatError, + ProfileAlreadyExistsForUserError, ProfileDoesNotExistError, ProfileMustHavePrimaryEmailError, ServiceConnectionDoesNotExist, @@ -596,7 +596,6 @@ def resolve_sensitivedata(self: Profile, info, **kwargs): ): return self.sensitivedata else: - # TODO: Raise PermissionDenied error (HP-2370) return None def resolve_verified_personal_information(self: Profile, info, **kwargs): @@ -1361,14 +1360,13 @@ def mutate_and_get_payload(cls, root, info, **input): profile_to_claim = get_claimable_profile(token=input["token"]) if Profile.objects.filter(user=info.context.user).exists(): - # Logged in user has a profile - # TODO: Add implementation (OM-385/HP-2368) - raise APINotImplementedError( - "Claiming a profile with existing profile not yet implemented" + # Logged-in user has a profile + raise ProfileAlreadyExistsForUserError( + "User already has a profile. Claiming is not allowed." ) else: with transaction.atomic(): - # Logged in user has no profile, let's use claimed profile + # Logged-in user has no profile, let's use claimed profile update_profile(profile_to_claim, input["profile"]) profile_to_claim.user = info.context.user profile_to_claim.save() @@ -1862,7 +1860,7 @@ class Mutation(graphene.ObjectType): "an error.\n\n" "Possible error codes:\n\n" "* `PROFILE_MUST_HAVE_PRIMARY_EMAIL`: If trying to get rid of the profile's primary email.\n" - "* `API_NOT_IMPLEMENTED_ERROR`: Returned if the currently authenticated user already has a profile." + "* `PROFILE_ALREADY_EXISTS_FOR_USER_ERROR`: Returned if the currently authenticated user already has a profile." ) create_my_profile_temporary_read_access_token = CreateMyProfileTemporaryReadAccessTokenMutation.Field( description="Creates and returns an access token for the profile which is linked to the currently " diff --git a/profiles/tests/test_gql_claim_profile_mutation.py b/profiles/tests/test_gql_claim_profile_mutation.py index f66e6d2f..93c89706 100644 --- a/profiles/tests/test_gql_claim_profile_mutation.py +++ b/profiles/tests/test_gql_claim_profile_mutation.py @@ -3,7 +3,10 @@ from django.utils import timezone -from open_city_profile.consts import API_NOT_IMPLEMENTED_ERROR, TOKEN_EXPIRED_ERROR +from open_city_profile.consts import ( + PROFILE_ALREADY_EXISTS_FOR_USER_ERROR, + TOKEN_EXPIRED_ERROR, +) from open_city_profile.tests.asserts import assert_match_error_code from profiles.models import Profile @@ -270,7 +273,10 @@ def test_user_cannot_claim_claimable_profile_with_existing_profile(user_gql_clie executed = user_gql_client.execute(query) assert "errors" in executed - assert executed["errors"][0]["extensions"]["code"] == API_NOT_IMPLEMENTED_ERROR + assert ( + executed["errors"][0]["extensions"]["code"] + == PROFILE_ALREADY_EXISTS_FOR_USER_ERROR + ) def test_anon_user_can_not_claim_claimable_profile(anon_user_gql_client):