From 87ceb5fc0ef57672c61477edb8d621aceee3c12f Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Thu, 23 Jan 2020 16:46:55 +0100 Subject: [PATCH] Setup views and tests --- server/core/hep_client.py | 9 +- server/core/settings.py | 5 + server/registration/mutations_public.py | 67 ++- server/registration/serializers.py | 6 + server/users/managers.py | 4 +- server/users/mutations_public.py | 33 +- server/users/tests/orders.json | 526 ++++++++++++++++++++++++ server/users/tests/test_login.py | 20 +- 8 files changed, 637 insertions(+), 33 deletions(-) create mode 100644 server/users/tests/orders.json diff --git a/server/core/hep_client.py b/server/core/hep_client.py index 14942d2b..884bab11 100644 --- a/server/core/hep_client.py +++ b/server/core/hep_client.py @@ -14,11 +14,11 @@ import requests logger = logging.getLogger(__name__) -class MagentoException(Exception): +class HepClientException(Exception): pass -class MagentoClient: +class HepClient: URL = 'https://stage.hep-verlag.ch' # URL = 'https://www.hep-verlag.ch' WEBSITE_ID = 1 @@ -45,7 +45,7 @@ class MagentoClient: response = requests.get(request_url, headers=headers) if response.status_code != 200: - raise MagentoException(response.status_code, response.json()) + raise HepClientException(response.status_code, response.json()) logger.info(response.json()) return response @@ -55,6 +55,9 @@ class MagentoClient: data={'customerEmail': email, 'websiteId': self.WEBSITE_ID}) return response.json() + def is_email_verified(self, email): + return True + def customer_verify_email(self, confirmation_key): response = self._call('/rest/V1/customers/me', method='put', data={'confirmationKey': confirmation_key}) return response.json() diff --git a/server/core/settings.py b/server/core/settings.py index 6d20ef89..99395817 100644 --- a/server/core/settings.py +++ b/server/core/settings.py @@ -361,8 +361,13 @@ SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY") SENDGRID_SANDBOX_MODE_IN_DEBUG = False DEFAULT_FROM_EMAIL = 'myskillbox ' +# Taskbase TASKBASE_USER = os.environ.get("TASKBASE_USER") TASKBASE_PASSWORD = os.environ.get("TASKBASE_PASSWORD") TASKBASE_SUPERUSER = os.environ.get("TASKBASE_SUPERUSER") TASKBASE_SUPERPASSWORD = os.environ.get("TASKBASE_SUPERPASSWORD") TASKBASE_BASEURL = os.environ.get("TASKBASE_BASEURL") + + +USE_LOCAL_REGISTRATION = False + diff --git a/server/registration/mutations_public.py b/server/registration/mutations_public.py index 181fdec5..39224a6b 100644 --- a/server/registration/mutations_public.py +++ b/server/registration/mutations_public.py @@ -8,8 +8,10 @@ # Created on 2019-10-08 # @author: chrigu import graphene +from django.conf import settings from graphene import relay +from core.hep_client import HepClient, HepClientException from core.views import SetPasswordView from registration.models import License from registration.serializers import RegistrationSerializer @@ -51,31 +53,31 @@ class Registration(relay.ClientIDMutation): serializer = RegistrationSerializer(data=registration_data) if serializer.is_valid(): - user = User.objects.create_user_with_random_password(serializer.data['first_name'], - serializer.data['last_name'], - serializer.data['email']) - sb_license = License.objects.create(licensee=user, license_type=serializer.context['license_type']) - if sb_license.license_type.is_teacher_license(): - teacher_role = Role.objects.get(key=Role.objects.TEACHER_KEY) - UserRole.objects.get_or_create(user=user, role=teacher_role) - default_class_name = SchoolClass.generate_default_group_name() - default_class = SchoolClass.objects.create(name=default_class_name) - user.school_classes.add(default_class) + if settings.USE_LOCAL_REGISTRATION: + return cls.create_local_user(serializer, info) else: - student_role = Role.objects.get(key=Role.objects.STUDENT_KEY) - UserRole.objects.get_or_create(user=user, role=student_role) + hep_client = HepClient() - password_reset_view = SetPasswordView() - password_reset_view.request = info.context - form = password_reset_view.form_class({'email': user.email}) + try: + email_available = hep_client.is_email_available(serializer['email']) + except HepClientException: + # Todo: handle error from exception (set on object, code & message) + return cls(success=False, errors=None) - if not form.is_valid(): - return cls(success=False, errors=form.errors) + if not email_available: + errors = [MutationError(field='email', errors=['already_exists'])] + return cls(success=False, errors=errors) - password_reset_view.form_valid(form) + try: + response = hep_client.customer_create(serializer.data, None) + except HepClientException: + # Todo: handle error from exception (set on object, code & message) + return cls(success=False, errors=None) - return cls(success=True) + # create or update local user + + # show verfiy page errors = [] for key, value in serializer.errors.items(): @@ -87,6 +89,33 @@ class Registration(relay.ClientIDMutation): return cls(success=False, errors=errors) + @classmethod + def create_local_user(cls, serializer, info): + user = User.objects.create_user_with_random_password(serializer.data['first_name'], + serializer.data['last_name'], + serializer.data['email']) + sb_license = License.objects.create(licensee=user, license_type=serializer.context['license_type']) + + if sb_license.license_type.is_teacher_license(): + teacher_role = Role.objects.get(key=Role.objects.TEACHER_KEY) + UserRole.objects.get_or_create(user=user, role=teacher_role) + default_class_name = SchoolClass.generate_default_group_name() + default_class = SchoolClass.objects.create(name=default_class_name) + user.school_classes.add(default_class) + else: + student_role = Role.objects.get(key=Role.objects.STUDENT_KEY) + UserRole.objects.get_or_create(user=user, role=student_role) + + password_reset_view = SetPasswordView() + password_reset_view.request = info.context + form = password_reset_view.form_class({'email': user.email}) + + if not form.is_valid(): + return cls(success=False, errors=form.errors) + + password_reset_view.form_valid(form) + + return cls(success=True) class RegistrationMutations: registration = Registration.Field() diff --git a/server/registration/serializers.py b/server/registration/serializers.py index 887fbbe1..ab2e95dd 100644 --- a/server/registration/serializers.py +++ b/server/registration/serializers.py @@ -7,6 +7,7 @@ # # Created on 2019-10-08 # @author: chrigu +from django.conf import settings from django.contrib.auth import get_user_model from rest_framework import serializers from rest_framework.fields import CharField, EmailField @@ -22,7 +23,12 @@ class RegistrationSerializer(serializers.Serializer): skillbox_license = None def validate_email(self, value): + lower_email = value.lower() + + if not settings.USE_LOCAL_REGISTRATION: + return lower_email + # the email is used as username if len(get_user_model().objects.filter(username=lower_email)) > 0: raise serializers.ValidationError(_(u'Diese E-Mail ist bereits registriert')) diff --git a/server/users/managers.py b/server/users/managers.py index e20312cf..cca165b3 100644 --- a/server/users/managers.py +++ b/server/users/managers.py @@ -86,6 +86,8 @@ class UserManager(DjangoUserManager): user, created = self.model.objects.get_or_create(email=email, username=email) user.first_name = first_name user.last_name = last_name - user.set_password(self.model.objects.make_random_password()) + # Todo: remove if not used + # user.set_password(self.model.objects.make_random_password()) + user.set_unusable_password() user.save() return user diff --git a/server/users/mutations_public.py b/server/users/mutations_public.py index 565b9d84..a5638983 100644 --- a/server/users/mutations_public.py +++ b/server/users/mutations_public.py @@ -9,9 +9,11 @@ # @author: chrigu import graphene +from django.conf import settings from django.contrib.auth import authenticate, login from graphene import relay +from core.hep_client import HepClient from registration.models import License @@ -30,10 +32,33 @@ class Login(relay.ClientIDMutation): @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): - user = authenticate(username=kwargs.get('username_input'), password=kwargs.get('password_input')) - if user is None: - error = LoginError(field='invalid_credentials') - return cls(success=False, errors=[error]) + # get token + # wrong password + # + # is email verified + # -> show screen + # local license + # -> show coupon + # get hep orders + # -> show coupon + # save role information + # login + + if not settings.USE_LOCAL_REGISTRATION: + user = authenticate(username=kwargs.get('username_input'), password=kwargs.get('password_input')) + if user is None: + error = LoginError(field='invalid_credentials') + return cls(success=False, errors=[error]) + + else: + hep_client = HepClient() + + # Todo catch error + token = hep_client.customer_token(kwargs.get('username_input'), kwargs.get('password_input')) + # Todo save token + #verify email + + user_license = None diff --git a/server/users/tests/orders.json b/server/users/tests/orders.json new file mode 100644 index 00000000..9b1db3a2 --- /dev/null +++ b/server/users/tests/orders.json @@ -0,0 +1,526 @@ +{ + "items": [ + { + "base_currency_code": "CHF", + "base_discount_amount": 0, + "base_grand_total": 46, + "base_discount_tax_compensation_amount": 0, + "base_shipping_amount": 0, + "base_shipping_discount_amount": 0, + "base_shipping_incl_tax": 0, + "base_shipping_tax_amount": 0, + "base_subtotal": 44.88, + "base_subtotal_incl_tax": 46, + "base_tax_amount": 1.12, + "base_total_due": 46, + "base_to_global_rate": 1, + "base_to_order_rate": 1, + "billing_address_id": 83693, + "created_at": "2018-07-19 15:05:33", + "customer_email": "1heptest19072018@mailinator.com", + "customer_firstname": "Test", + "customer_gender": 2, + "customer_group_id": 4, + "customer_id": 49124, + "customer_is_guest": 0, + "customer_lastname": "Test", + "customer_note": "coupon", + "customer_note_notify": 1, + "customer_prefix": "Frau", + "discount_amount": 0, + "email_sent": 1, + "entity_id": 57612, + "global_currency_code": "CHF", + "grand_total": 46, + "discount_tax_compensation_amount": 0, + "increment_id": "1004614768", + "is_virtual": 1, + "order_currency_code": "CHF", + "protect_code": "71aedb", + "quote_id": 104401, + "shipping_amount": 0, + "shipping_discount_amount": 0, + "shipping_discount_tax_compensation_amount": 0, + "shipping_incl_tax": 0, + "shipping_tax_amount": 0, + "state": "complete", + "status": "complete", + "store_currency_code": "CHF", + "store_id": 1, + "store_name": "hep verlag\nhep verlag\nhep verlag", + "store_to_base_rate": 0, + "store_to_order_rate": 0, + "subtotal": 44.88, + "subtotal_incl_tax": 46, + "tax_amount": 1.12, + "total_due": 46, + "total_item_count": 1, + "total_qty_ordered": 1, + "updated_at": "2018-07-19 15:05:33", + "weight": 0, + "items": [ + { + "amount_refunded": 0, + "base_amount_refunded": 0, + "base_discount_amount": 0, + "base_discount_invoiced": 0, + "base_discount_tax_compensation_amount": 0, + "base_original_price": 46, + "base_price": 44.88, + "base_price_incl_tax": 46, + "base_row_invoiced": 0, + "base_row_total": 44.88, + "base_row_total_incl_tax": 46, + "base_tax_amount": 1.12, + "base_tax_invoiced": 0, + "created_at": "2018-07-19 15:05:33", + "discount_amount": 0, + "discount_invoiced": 0, + "discount_percent": 0, + "free_shipping": 0, + "discount_tax_compensation_amount": 0, + "is_qty_decimal": 0, + "is_virtual": 1, + "item_id": 80317, + "name": "Gesellschaft Ausgabe A (eLehrmittel, Neuauflage)", + "no_discount": 0, + "order_id": 57612, + "original_price": 46, + "price": 44.88, + "price_incl_tax": 46, + "product_id": 8652, + "product_type": "virtual", + "qty_canceled": 0, + "qty_invoiced": 0, + "qty_ordered": 1, + "qty_refunded": 0, + "qty_shipped": 0, + "quote_item_id": 135166, + "row_invoiced": 0, + "row_total": 44.88, + "row_total_incl_tax": 46, + "sku": "978-3-0355-1082-9", + "store_id": 1, + "tax_amount": 1.12, + "tax_invoiced": 0, + "tax_percent": 2.5, + "updated_at": "2018-07-19 15:05:33", + "weight": 0.01 + } + ], + "billing_address": { + "address_type": "billing", + "city": "Test", + "country_id": "CH", + "customer_address_id": 47579, + "email": "1heptest19072018@mailinator.com", + "entity_id": 83693, + "firstname": "Test", + "lastname": "Test", + "parent_id": 57612, + "postcode": "0000", + "prefix": "Frau", + "street": [ + "Test" + ], + "telephone": null + }, + "payment": { + "account_status": null, + "additional_information": [ + "Rechnung", + null, + null + ], + "amount_ordered": 46, + "base_amount_ordered": 46, + "base_shipping_amount": 0, + "cc_last4": null, + "entity_id": 57612, + "method": "checkmo", + "parent_id": 57612, + "shipping_amount": 0, + "extension_attributes": [] + }, + "status_histories": [ + { + "comment": "payed by couponcode", + "created_at": "2018-07-19 15:05:33", + "entity_id": 244885, + "entity_name": "order", + "is_customer_notified": null, + "is_visible_on_front": 0, + "parent_id": 57612, + "status": "complete" + }, + { + "comment": "licence-coupon \"ebf81a59b968\"", + "created_at": "2018-07-19 15:05:33", + "entity_id": 244884, + "entity_name": "order", + "is_customer_notified": null, + "is_visible_on_front": 0, + "parent_id": 57612, + "status": "complete" + }, + { + "comment": null, + "created_at": "2018-07-19 15:05:33", + "entity_id": 244883, + "entity_name": "order", + "is_customer_notified": 0, + "is_visible_on_front": 0, + "parent_id": 57612, + "status": "complete" + }, + { + "comment": "Exported to ERP", + "created_at": "2018-07-19 15:05:33", + "entity_id": 244882, + "entity_name": "order", + "is_customer_notified": 0, + "is_visible_on_front": 0, + "parent_id": 57612, + "status": "complete" + } + ], + "extension_attributes": { + "shipping_assignments": [ + { + "shipping": { + "total": { + "base_shipping_amount": 0, + "base_shipping_discount_amount": 0, + "base_shipping_incl_tax": 0, + "base_shipping_tax_amount": 0, + "shipping_amount": 0, + "shipping_discount_amount": 0, + "shipping_discount_tax_compensation_amount": 0, + "shipping_incl_tax": 0, + "shipping_tax_amount": 0 + } + }, + "items": [ + { + "amount_refunded": 0, + "base_amount_refunded": 0, + "base_discount_amount": 0, + "base_discount_invoiced": 0, + "base_discount_tax_compensation_amount": 0, + "base_original_price": 46, + "base_price": 44.88, + "base_price_incl_tax": 46, + "base_row_invoiced": 0, + "base_row_total": 44.88, + "base_row_total_incl_tax": 46, + "base_tax_amount": 1.12, + "base_tax_invoiced": 0, + "created_at": "2018-07-19 15:05:33", + "discount_amount": 0, + "discount_invoiced": 0, + "discount_percent": 0, + "free_shipping": 0, + "discount_tax_compensation_amount": 0, + "is_qty_decimal": 0, + "is_virtual": 1, + "item_id": 80317, + "name": "Gesellschaft Ausgabe A (eLehrmittel, Neuauflage)", + "no_discount": 0, + "order_id": 57612, + "original_price": 46, + "price": 44.88, + "price_incl_tax": 46, + "product_id": 8652, + "product_type": "virtual", + "qty_canceled": 0, + "qty_invoiced": 0, + "qty_ordered": 1, + "qty_refunded": 0, + "qty_shipped": 0, + "quote_item_id": 135166, + "row_invoiced": 0, + "row_total": 44.88, + "row_total_incl_tax": 46, + "sku": "978-3-0355-1082-9", + "store_id": 1, + "tax_amount": 1.12, + "tax_invoiced": 0, + "tax_percent": 2.5, + "updated_at": "2018-07-19 15:05:33", + "weight": 0.01 + } + ] + } + ] + } + }, + { + "base_currency_code": "CHF", + "base_discount_amount": 0, + "base_grand_total": 24, + "base_discount_tax_compensation_amount": 0, + "base_shipping_amount": 0, + "base_shipping_discount_amount": 0, + "base_shipping_incl_tax": 0, + "base_shipping_tax_amount": 0, + "base_subtotal": 23.41, + "base_subtotal_incl_tax": 24, + "base_tax_amount": 0.59, + "base_total_due": 24, + "base_to_global_rate": 1, + "base_to_order_rate": 1, + "billing_address_id": 83696, + "created_at": "2018-07-19 15:19:00", + "customer_email": "1heptest19072018@mailinator.com", + "customer_firstname": "Test", + "customer_gender": 2, + "customer_group_id": 4, + "customer_id": 49124, + "customer_is_guest": 0, + "customer_lastname": "Test", + "customer_note": "coupon", + "customer_note_notify": 1, + "customer_prefix": "Frau", + "discount_amount": 0, + "email_sent": 1, + "entity_id": 57614, + "global_currency_code": "CHF", + "grand_total": 24, + "discount_tax_compensation_amount": 0, + "increment_id": "1004614770", + "is_virtual": 1, + "order_currency_code": "CHF", + "protect_code": "1a88e9", + "quote_id": 104403, + "shipping_amount": 0, + "shipping_discount_amount": 0, + "shipping_discount_tax_compensation_amount": 0, + "shipping_incl_tax": 0, + "shipping_tax_amount": 0, + "state": "complete", + "status": "complete", + "store_currency_code": "CHF", + "store_id": 1, + "store_name": "hep verlag\nhep verlag\nhep verlag", + "store_to_base_rate": 0, + "store_to_order_rate": 0, + "subtotal": 23.41, + "subtotal_incl_tax": 24, + "tax_amount": 0.59, + "total_due": 24, + "total_item_count": 1, + "total_qty_ordered": 1, + "updated_at": "2018-07-19 15:19:00", + "weight": 0, + "items": [ + { + "amount_refunded": 0, + "base_amount_refunded": 0, + "base_discount_amount": 0, + "base_discount_invoiced": 0, + "base_discount_tax_compensation_amount": 0, + "base_original_price": 24, + "base_price": 23.41, + "base_price_incl_tax": 24, + "base_row_invoiced": 0, + "base_row_total": 23.41, + "base_row_total_incl_tax": 24, + "base_tax_amount": 0.59, + "base_tax_invoiced": 0, + "created_at": "2018-07-19 15:19:00", + "discount_amount": 0, + "discount_invoiced": 0, + "discount_percent": 0, + "free_shipping": 0, + "discount_tax_compensation_amount": 0, + "is_qty_decimal": 0, + "is_virtual": 1, + "item_id": 80320, + "name": "Gesellschaft Ausgabe A, Arbeitsheft (eLehrmittel, Neuauflage)", + "no_discount": 0, + "order_id": 57614, + "original_price": 24, + "price": 23.41, + "price_incl_tax": 24, + "product_id": 8654, + "product_type": "virtual", + "qty_canceled": 0, + "qty_invoiced": 0, + "qty_ordered": 1, + "qty_refunded": 0, + "qty_shipped": 0, + "quote_item_id": 135169, + "row_invoiced": 0, + "row_total": 23.41, + "row_total_incl_tax": 24, + "sku": "978-3-0355-1185-7", + "store_id": 1, + "tax_amount": 0.59, + "tax_invoiced": 0, + "tax_percent": 2.5, + "updated_at": "2018-07-19 15:19:00", + "weight": 0.01 + } + ], + "billing_address": { + "address_type": "billing", + "city": "Test", + "country_id": "CH", + "customer_address_id": 47579, + "email": "1heptest19072018@mailinator.com", + "entity_id": 83696, + "firstname": "Test", + "lastname": "Test", + "parent_id": 57614, + "postcode": "0000", + "prefix": "Frau", + "street": [ + "Test" + ], + "telephone": null + }, + "payment": { + "account_status": null, + "additional_information": [ + "Rechnung", + null, + null + ], + "amount_ordered": 24, + "base_amount_ordered": 24, + "base_shipping_amount": 0, + "cc_last4": null, + "entity_id": 57614, + "method": "checkmo", + "parent_id": 57614, + "shipping_amount": 0, + "extension_attributes": [] + }, + "status_histories": [ + { + "comment": "payed by couponcode", + "created_at": "2018-07-19 15:19:00", + "entity_id": 244890, + "entity_name": "order", + "is_customer_notified": null, + "is_visible_on_front": 0, + "parent_id": 57614, + "status": "complete" + }, + { + "comment": "licence-coupon \"ece5e74a2b36\"", + "created_at": "2018-07-19 15:19:00", + "entity_id": 244889, + "entity_name": "order", + "is_customer_notified": null, + "is_visible_on_front": 0, + "parent_id": 57614, + "status": "complete" + }, + { + "comment": null, + "created_at": "2018-07-19 15:19:00", + "entity_id": 244888, + "entity_name": "order", + "is_customer_notified": 0, + "is_visible_on_front": 0, + "parent_id": 57614, + "status": "complete" + }, + { + "comment": "Exported to ERP", + "created_at": "2018-07-19 15:19:00", + "entity_id": 244887, + "entity_name": "order", + "is_customer_notified": 0, + "is_visible_on_front": 0, + "parent_id": 57614, + "status": "complete" + } + ], + "extension_attributes": { + "shipping_assignments": [ + { + "shipping": { + "total": { + "base_shipping_amount": 0, + "base_shipping_discount_amount": 0, + "base_shipping_incl_tax": 0, + "base_shipping_tax_amount": 0, + "shipping_amount": 0, + "shipping_discount_amount": 0, + "shipping_discount_tax_compensation_amount": 0, + "shipping_incl_tax": 0, + "shipping_tax_amount": 0 + } + }, + "items": [ + { + "amount_refunded": 0, + "base_amount_refunded": 0, + "base_discount_amount": 0, + "base_discount_invoiced": 0, + "base_discount_tax_compensation_amount": 0, + "base_original_price": 24, + "base_price": 23.41, + "base_price_incl_tax": 24, + "base_row_invoiced": 0, + "base_row_total": 23.41, + "base_row_total_incl_tax": 24, + "base_tax_amount": 0.59, + "base_tax_invoiced": 0, + "created_at": "2018-07-19 15:19:00", + "discount_amount": 0, + "discount_invoiced": 0, + "discount_percent": 0, + "free_shipping": 0, + "discount_tax_compensation_amount": 0, + "is_qty_decimal": 0, + "is_virtual": 1, + "item_id": 80320, + "name": "Gesellschaft Ausgabe A, Arbeitsheft (eLehrmittel, Neuauflage)", + "no_discount": 0, + "order_id": 57614, + "original_price": 24, + "price": 23.41, + "price_incl_tax": 24, + "product_id": 8654, + "product_type": "virtual", + "qty_canceled": 0, + "qty_invoiced": 0, + "qty_ordered": 1, + "qty_refunded": 0, + "qty_shipped": 0, + "quote_item_id": 135169, + "row_invoiced": 0, + "row_total": 23.41, + "row_total_incl_tax": 24, + "sku": "978-3-0355-1185-7", + "store_id": 1, + "tax_amount": 0.59, + "tax_invoiced": 0, + "tax_percent": 2.5, + "updated_at": "2018-07-19 15:19:00", + "weight": 0.01 + } + ] + } + ] + } + } + ], + "search_criteria": { + "filter_groups": [ + { + "filters": [ + { + "field": "customer_id", + "value": "49124", + "condition_type": "eq" + } + ] + } + ] + }, + "total_count": 2 +} diff --git a/server/users/tests/test_login.py b/server/users/tests/test_login.py index 68433116..34ab1852 100644 --- a/server/users/tests/test_login.py +++ b/server/users/tests/test_login.py @@ -7,15 +7,25 @@ # # Created on 2019-10-02 # @author: chrigu +import json +from unittest.mock import patch from django.contrib.sessions.middleware import SessionMiddleware from django.test import TestCase, RequestFactory from graphene.test import Client from api.schema_public import schema from core.factories import UserFactory +from core.hep_client import HepClient from registration.factories import LicenseTypeFactory, LicenseFactory from users.models import Role +FAKE_TOKEN = 'abcd12345!' + +with open('orders.json', 'r') as file: + order_data = file.read() + +ORDERS = json.loads(order_data) + class PasswordResetTests(TestCase): def setUp(self): @@ -50,12 +60,10 @@ class PasswordResetTests(TestCase): } }) - def test_user_can_login(self): - password = 'test123' - self.user.set_password(password) - self.user.save() - - result = self.make_login_mutation(self.user.email, password) + @patch.object(HepClient, 'customer_token', return_value={'token': FAKE_TOKEN}) + @patch.object(HepClient, 'customer_orders', return_value=ORDERS) + def test_user_can_login(self, orders_mock, token_mock): + result = self.make_login_mutation(self.user.email, 'test123') self.assertTrue(result.get('data').get('login').get('success')) self.assertTrue(self.user.is_authenticated)