From 9c4e2de2966b3daa2c2b5c05558f5abf9b77bf61 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 28 Jan 2020 15:28:32 +0100 Subject: [PATCH] Select correct product (basic version) --- server/core/hep_client.py | 65 ++++++++++++++++----- server/core/settings.py | 1 + server/core/tests/test_hep_client.py | 87 +++++++++++++++++++++++++++- server/registration/managers.py | 5 +- server/registration/models.py | 4 +- server/users/mutations_public.py | 9 +-- server/users/tests/test_login.py | 23 ++++++-- 7 files changed, 163 insertions(+), 31 deletions(-) diff --git a/server/core/hep_client.py b/server/core/hep_client.py index a937e3c7..35931d21 100644 --- a/server/core/hep_client.py +++ b/server/core/hep_client.py @@ -7,7 +7,7 @@ # # Created on 23.01.20 # @author: chrigu -from datetime import datetime +from datetime import datetime, timedelta from django.conf import settings import logging @@ -18,6 +18,10 @@ logger = logging.getLogger(__name__) MYSKILLBOX_TEACHER_EDITION_ISBN = "000-4-5678-9012-3" MYSKILLBOX_STUDENT_EDITION_ISBN = "123-4-5678-9012-3" +TEACHER_EDITION_DURATION = 365 +STUDENT_EDITION_DURATION = 4*365 + + class HepClientException(Exception): pass @@ -105,31 +109,64 @@ class HepClient: def myskillbox_product_for_customer(self, admin_token, customer_id): orders = self._customer_orders(admin_token, customer_id) - # Todo return only relevant product - return self._extract_myskillbox_products(orders) + products = self._extract_myskillbox_products(orders) + + if len(products) == 0: + return None + else: + return self._get_relevant_product(products) def _extract_myskillbox_products(self, orders): - # Todo retun all products - product = None + products = [] for order_item in orders['items']: for item in order_item['items']: - if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN: + if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN or item['sku'] == MYSKILLBOX_STUDENT_EDITION_ISBN: product = { - 'edition': 'teacher', 'raw': item, 'activated': self._get_item_activation(order_item) } - elif not product and item['sku'] == MYSKILLBOX_STUDENT_EDITION_ISBN: - product = { - 'edition': 'student', - 'raw': item, - 'activated': self._get_item_activation(order_item) - } + if item['sku'] == MYSKILLBOX_TEACHER_EDITION_ISBN: + product['edition'] = 'teacher' + + else: + product['edition'] = 'student' + + products.append(product) + + return products - return product def _get_item_activation(self, item): for history in item['status_histories']: + # todo can there be no date? if history['comment'] == 'payed by couponcode': return datetime.strptime(history['created_at'], '%Y-%m-%d %H:%M:%S') + + def _get_relevant_product(self, products): + + def filter_inactive_products(product): + if product['edition'] == 'teacher': + expiry_delta = product['activated'] + timedelta(TEACHER_EDITION_DURATION) + else: + expiry_delta = product['activated'] + timedelta(STUDENT_EDITION_DURATION) + + if HepClient.is_product_valid(expiry_delta): + return True + else: + return False + + active_products = list(filter(filter_inactive_products, products)) + print(active_products) + + # todo can a teacher have multiple licenses? + # clarify with hep + if len(active_products) == 0: + return None + elif len(active_products) == 1: + return active_products[0] + + + @staticmethod + def is_product_valid(expiry_date): + return expiry_date >= datetime.now() diff --git a/server/core/settings.py b/server/core/settings.py index a662e88c..c34a47e1 100644 --- a/server/core/settings.py +++ b/server/core/settings.py @@ -374,3 +374,4 @@ USE_LOCAL_REGISTRATION = False # HEP HEP_ADMIN_TOKEN = "asdf" + diff --git a/server/core/tests/test_hep_client.py b/server/core/tests/test_hep_client.py index 775f6a76..ecfddf15 100644 --- a/server/core/tests/test_hep_client.py +++ b/server/core/tests/test_hep_client.py @@ -8,10 +8,91 @@ # Created on 23.01.20 # @author: chrigu import json +from datetime import datetime, timedelta -from django.test import TestCase, Client -from core.factories import UserFactory +from django.test import TestCase +from core.hep_client import HepClient, TEACHER_EDITION_DURATION class HepClientTestCases(TestCase): - pass + def setUp(self): + self.hep_client = HepClient() + self.now = datetime.now() + + def test_has_no_valid_product(self): + products = [ + { + 'edition': 'teacher', + 'raw': {}, + 'activated': self.now - timedelta(2*TEACHER_EDITION_DURATION) + }, + { + 'edition': 'teacher', + 'raw': {}, + 'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION) + }, + { + 'edition': 'teacher', + 'raw': {}, + 'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION) + } + ] + + relevant_product = self.hep_client._get_relevant_product(products) + self.assertIsNone(relevant_product) + + def test_has_valid_product(self): + products = [ + { + 'edition': 'teacher', + 'raw': { + 'id': 0 + }, + 'activated': self.now - timedelta(7) + }, + { + 'edition': 'teacher', + 'raw': { + 'id': 1 + }, + 'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION) + }, + { + 'edition': 'teacher', + 'raw': { + 'id': 2 + }, + 'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION) + } + ] + + relevant_product = self.hep_client._get_relevant_product(products) + self.assertEqual(relevant_product['raw']['id'], 0) + + def test_has_multiple_valid_products(self): + products = [ + { + 'edition': 'teacher', + 'raw': { + 'id': 0 + }, + 'activated': self.now - timedelta(7) + }, + { + 'edition': 'teacher', + 'raw': { + 'id': 1 + }, + 'activated': self.now - timedelta(3 * TEACHER_EDITION_DURATION) + }, + { + 'edition': 'teacher', + 'raw': { + 'id': 2 + }, + 'activated': self.now - timedelta(4 * TEACHER_EDITION_DURATION) + } + ] + + relevant_product = self.hep_client._get_relevant_product(products) + self.assertEqual(relevant_product['raw']['id'], 0) diff --git a/server/registration/managers.py b/server/registration/managers.py index 3e35002b..b54d267d 100644 --- a/server/registration/managers.py +++ b/server/registration/managers.py @@ -10,10 +10,9 @@ from datetime import timedelta from django.db import models -from users.models import Role -TEACHER_EDITION_DURATION = 365 -STUDENT_EDITION_DURATION = 4*365 +from core.hep_client import TEACHER_EDITION_DURATION, STUDENT_EDITION_DURATION +from users.models import Role class LicenseManager(models.Manager): diff --git a/server/registration/models.py b/server/registration/models.py index 78de8ee8..2c79542c 100644 --- a/server/registration/models.py +++ b/server/registration/models.py @@ -9,9 +9,9 @@ # @author: chrigu from datetime import datetime -from django.utils.translation import ugettext_lazy as _ from django.db import models +from core.hep_client import HepClient from registration.managers import LicenseManager from users.managers import RoleManager from users.models import Role, User @@ -29,7 +29,7 @@ class License(models.Model): return self.for_role.key == RoleManager.TEACHER_KEY def is_valid(self): - return datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day) <= datetime.now() + return HepClient.is_product_valid(datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day)) def __str__(self): return 'License for role: %s' % self.for_role diff --git a/server/users/mutations_public.py b/server/users/mutations_public.py index c1e95087..3641b8f2 100644 --- a/server/users/mutations_public.py +++ b/server/users/mutations_public.py @@ -86,10 +86,11 @@ class Login(relay.ClientIDMutation): # todo go to shop pass - UserRole.objects.create_role_for_user(user, license.for_role.key) - default_class_name = SchoolClass.generate_default_group_name() - default_class = SchoolClass.objects.create(name=default_class_name) - user.school_classes.add(default_class) + if license.for_role.key == Role.objects.TEACHER_KEY: + UserRole.objects.create_role_for_user(user, license.for_role.key) + default_class_name = SchoolClass.generate_default_group_name() + default_class = SchoolClass.objects.create(name=default_class_name) + user.school_classes.add(default_class) # if teacher create class # if student add to class if exists??? diff --git a/server/users/tests/test_login.py b/server/users/tests/test_login.py index 9a0b2523..e434a1a2 100644 --- a/server/users/tests/test_login.py +++ b/server/users/tests/test_login.py @@ -9,7 +9,7 @@ # @author: chrigu import json import os -from datetime import timedelta +from datetime import timedelta, datetime from unittest.mock import patch from django.contrib.sessions.middleware import SessionMiddleware from django.test import TestCase, RequestFactory @@ -21,23 +21,33 @@ from core.factories import UserFactory from core.hep_client import HepClient from registration.factories import LicenseFactory from registration.models import License -from users.models import Role, MagentoToken, User +from users.models import Role, MagentoToken, User, SchoolClass FAKE_TOKEN = 'abcd12345!' +## Setup json data dir_path = os.path.dirname(os.path.realpath(__file__)) with open('{}/valid_teacher_orders.json'.format(dir_path), 'r') as file: order_data = file.read() -ORDERS = json.loads(order_data) - with open('{}/me_data.json'.format(dir_path), 'r') as file: me_data = file.read() ME_DATA = json.loads(me_data) +order_items = json.loads(order_data) + +for order_item in order_items['items']: + for status in order_item['status_histories']: + if status['comment'] == 'payed by couponcode': + yesterday = datetime.now() - timedelta(1) + status['created_at'] = datetime.strftime(yesterday, '%Y-%m-%d %H:%M:%S') + + +ORDERS = order_items + class PasswordResetTests(TestCase): def setUp(self): @@ -103,11 +113,14 @@ class PasswordResetTests(TestCase): license = License.objects.get(licensee=user) self.assertEqual(license.for_role.key, Role.objects.TEACHER_KEY) + school_class = SchoolClass.objects.get(users__in=[user]) + self.assertIsNotNone(school_class) + self.assertTrue(result.get('data').get('login').get('success')) self.assertTrue(self.user.is_authenticated) ## can login with license and user - # can login with no user and license + ## can login with no user and license # can login with no user and local license # cannot login without user # cannot login with user and not verfied