Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HP-2372: Replace APINotImplementedError with ProfileAlreadyExistsForUserError #485

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion open_city_profile/consts.py
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions open_city_profile/exceptions.py
Original file line number Diff line number Diff line change
@@ -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):
6 changes: 3 additions & 3 deletions open_city_profile/views.py
Original file line number Diff line number Diff line change
@@ -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,
14 changes: 6 additions & 8 deletions profiles/schema.py
Original file line number Diff line number Diff line change
@@ -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 "
10 changes: 8 additions & 2 deletions profiles/tests/test_gql_claim_profile_mutation.py
Original file line number Diff line number Diff line change
@@ -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):