Repository: saleor/saleor

Issue:
Add mutation for removing user account
### What I'm trying to achieve
As a user of storefront I would like to remove my account. Right now it is only possible for staff/admin user accounts

### Describe a proposed solution
Add mutation for removing account by regular user




Discussion:

Resolving patch:
diff --git a/saleor/graphql/account/mutations.py b/saleor/graphql/account/mutations.py
--- a/saleor/graphql/account/mutations.py
+++ b/saleor/graphql/account/mutations.py
@@ -297,6 +297,23 @@ def perform_mutation(cls, root, info, **data):
         return super().perform_mutation(root, info, **data)
 
 
+class AccountRequestDeletion(BaseMutation):
+    class Meta:
+        description = (
+            "Sends an email with the account removal link for the logged-in user."
+        )
+
+    @classmethod
+    def check_permissions(cls, user):
+        return user.is_authenticated
+
+    @classmethod
+    def perform_mutation(cls, root, info, **data):
+        user = info.context.user
+        emails.send_account_delete_confirmation_email.delay(str(user.token), user.email)
+        return AccountRequestDeletion()
+
+
 class UserDelete(UserDeleteMixin, ModelDeleteMutation):
     class Meta:
         abstract = True
diff --git a/saleor/graphql/account/schema.py b/saleor/graphql/account/schema.py
--- a/saleor/graphql/account/schema.py
+++ b/saleor/graphql/account/schema.py
@@ -8,6 +8,7 @@
 from .enums import CountryCodeEnum
 from .filters import CustomerFilter, StaffUserFilter
 from .mutations import (
+    AccountRequestDeletion,
     AccountUpdate,
     AddressCreate,
     AddressDelete,
@@ -111,6 +112,7 @@ class AccountMutations(graphene.ObjectType):
 
     logged_user_update = LoggedUserUpdate.Field()
     account_update = AccountUpdate.Field()
+    account_request_deletion = AccountRequestDeletion.Field()
 
     staff_create = StaffCreate.Field()
     staff_delete = StaffDelete.Field()


Test patch:
diff --git a/tests/api/test_account.py b/tests/api/test_account.py
--- a/tests/api/test_account.py
+++ b/tests/api/test_account.py
@@ -938,6 +938,43 @@ def test_logged_customer_update_anonymous_user(api_client, query):
     assert_no_permission(response)
 
 
+ACCOUNT_REQUEST_DELETION_QUERY = """
+    mutation accountRequestDeletion {
+        accountRequestDeletion {
+            errors {
+                field
+                message
+            }
+        }
+    }
+"""
+
+
+@patch("saleor.account.emails.send_account_delete_confirmation_email.delay")
+def test_account_request_deletion(
+    send_account_delete_confirmation_email_mock, user_api_client
+):
+    user = user_api_client.user
+
+    response = user_api_client.post_graphql(ACCOUNT_REQUEST_DELETION_QUERY)
+    content = get_graphql_content(response)
+    data = content["data"]["accountRequestDeletion"]
+
+    assert not data["errors"]
+    send_account_delete_confirmation_email_mock.assert_called_once_with(
+        str(user.token), user.email
+    )
+
+
+@patch("saleor.account.emails.send_account_delete_confirmation_email.delay")
+def test_account_request_deletion_anonymous_user(
+    send_account_delete_confirmation_email_mock, api_client
+):
+    response = api_client.post_graphql(ACCOUNT_REQUEST_DELETION_QUERY, {})
+    assert_no_permission(response)
+    send_account_delete_confirmation_email_mock.assert_not_called()
+
+
 @patch(
     "saleor.graphql.account.utils.account_events.staff_user_deleted_a_customer_event"
 )