Commit da80e91d by Albert St. Aubin Committed by Albert (AJ) St. Aubin

adding the id_required attribute to entitlement products

[LEARNER-5456]

This change will allow the id_required attribute to be added to
Entitlement Products which will ensure correct fulfillment.
parent 08708e1e
...@@ -42,7 +42,7 @@ def create_parent_course_entitlement(name, UUID): ...@@ -42,7 +42,7 @@ def create_parent_course_entitlement(name, UUID):
return parent, created return parent, created
def create_or_update_course_entitlement(certificate_type, price, partner, UUID, name): def create_or_update_course_entitlement(certificate_type, price, partner, UUID, name, id_verification_required=False):
""" Create or Update Course Entitlement Products """ """ Create or Update Course Entitlement Products """
certificate_type = certificate_type.lower() certificate_type = certificate_type.lower()
...@@ -69,6 +69,7 @@ def create_or_update_course_entitlement(certificate_type, price, partner, UUID, ...@@ -69,6 +69,7 @@ def create_or_update_course_entitlement(certificate_type, price, partner, UUID,
course_entitlement.title = 'Course {}'.format(name) course_entitlement.title = 'Course {}'.format(name)
course_entitlement.attr.certificate_type = certificate_type course_entitlement.attr.certificate_type = certificate_type
course_entitlement.attr.UUID = UUID course_entitlement.attr.UUID = UUID
course_entitlement.attr.id_verification_required = id_verification_required
course_entitlement.parent = parent_entitlement course_entitlement.parent = parent_entitlement
course_entitlement.save() course_entitlement.save()
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from oscar.core.loading import get_model
from ecommerce.core.constants import COURSE_ENTITLEMENT_PRODUCT_CLASS_NAME
ProductAttribute = get_model("catalogue", "ProductAttribute")
ProductClass = get_model("catalogue", "ProductClass")
def create_idverifyreq_attribute(apps, schema_editor):
"""Create entitlement code 'id_verification_required' attribute."""
entitlement_code_class = ProductClass.objects.get(name=COURSE_ENTITLEMENT_PRODUCT_CLASS_NAME)
ProductAttribute.objects.create(
product_class=entitlement_code_class,
name='id_verification_required',
code='id_verification_required',
type='boolean',
required=False
)
def remove_idverifyreq_attribute(apps, schema_editor):
"""Remove enrollment code 'id_verification_required' attribute."""
enrollment_code_class = ProductClass.objects.get(name=COURSE_ENTITLEMENT_PRODUCT_CLASS_NAME)
ProductAttribute.objects.get(
product_class=enrollment_code_class,
name='id_verification_required'
).delete()
class Migration(migrations.Migration):
dependencies = [
('catalogue', '0001_initial'),
('catalogue', '0025_course_entitlement'),
('catalogue', '0030_auto_20180124_1131')
]
operations = [
migrations.RunPython(create_idverifyreq_attribute, remove_idverifyreq_attribute)
]
...@@ -16,10 +16,12 @@ class CourseEntitlementTest(TestCase): ...@@ -16,10 +16,12 @@ class CourseEntitlementTest(TestCase):
product_class, _ = ProductClass.objects.get_or_create(name=COURSE_ENTITLEMENT_PRODUCT_CLASS_NAME) product_class, _ = ProductClass.objects.get_or_create(name=COURSE_ENTITLEMENT_PRODUCT_CLASS_NAME)
product = ProductFactory(product_class=product_class) product = ProductFactory(product_class=product_class)
product.attr.course_key = 'foo-bar' product.attr.UUID = '8724c585-acb2-42ab-986e-bc0847ef122c'
product.attr.certificate_type = 'verified' product.attr.certificate_type = 'verified'
product.attr.id_verification_required = False
product.attr.save() product.attr.save()
product.refresh_from_db() product.refresh_from_db()
self.assertEqual(product.attr.course_key, 'foo-bar') self.assertEqual(product.attr.UUID, '8724c585-acb2-42ab-986e-bc0847ef122c')
self.assertEqual(product.attr.certificate_type, 'verified') self.assertEqual(product.attr.certificate_type, 'verified')
self.assertEqual(product.attr.id_verification_required, False)
...@@ -211,7 +211,7 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi ...@@ -211,7 +211,7 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi
self.client.login(username=user.username, password=self.password) self.client.login(username=user.username, password=self.password)
return self._get_receipt_response(order.number) return self._get_receipt_response(order.number)
def _create_order_for_receipt(self, user, credit=False): def _create_order_for_receipt(self, user, credit=False, entitlement=False, id_verification_required=False):
""" """
Helper function for creating an order and mocking verification status API response. Helper function for creating an order and mocking verification status API response.
...@@ -228,7 +228,11 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi ...@@ -228,7 +228,11 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi
status=200, status=200,
is_verified=False is_verified=False
) )
return self.create_order(credit=credit) return self.create_order(
credit=credit,
entitlement=entitlement,
id_verification_required=id_verification_required
)
def test_login_required_get_request(self): def test_login_required_get_request(self):
""" The view should redirect to the login page if the user is not logged in. """ """ The view should redirect to the login page if the user is not logged in. """
...@@ -285,6 +289,35 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi ...@@ -285,6 +289,35 @@ class ReceiptResponseViewTests(DiscoveryMockMixin, LmsApiMockMixin, RefundTestMi
self.assertDictContainsSubset(context_data, response.context_data) self.assertDictContainsSubset(context_data, response.context_data)
@httpretty.activate @httpretty.activate
def test_get_receipt_for_existing_entitlement_order(self):
""" Order owner should be able to see the Receipt Page."""
order = self._create_order_for_receipt(self.user, entitlement=True, id_verification_required=True)
response = self._get_receipt_response(order.number)
context_data = {
'payment_method': None,
'display_credit_messaging': False,
'verification_url': self.site.siteconfiguration.build_lms_url('verify_student/reverify'),
}
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset(context_data, response.context_data)
@httpretty.activate
def test_get_receipt_for_entitlement_order_no_id_required(self):
""" Order owner should be able to see the Receipt Page with no ID verification in context."""
order = self._create_order_for_receipt(self.user, entitlement=True, id_verification_required=False)
response = self._get_receipt_response(order.number)
context_data = {
'payment_method': None,
'display_credit_messaging': False,
}
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset(context_data, response.context_data)
@httpretty.activate
def test_get_receipt_for_existing_order_as_staff_user(self): def test_get_receipt_for_existing_order_as_staff_user(self):
""" Staff users can preview Receipts for all Orders.""" """ Staff users can preview Receipts for all Orders."""
staff_user = self.create_user(is_staff=True) staff_user = self.create_user(is_staff=True)
......
...@@ -240,23 +240,23 @@ class ReceiptResponseView(ThankYouView): ...@@ -240,23 +240,23 @@ class ReceiptResponseView(ThankYouView):
def get_order_verification_context(self, order): def get_order_verification_context(self, order):
context = {} context = {}
verified_course_id = None
request = self.request request = self.request
site = request.site site = request.site
# NOTE: Only display verification and credit completion details to the user who actually placed the order. # NOTE: Only display verification and credit completion details to the user who actually placed the order.
if request.user == order.user: if request.user != order.user:
for line in order.lines.all(): return context
product = line.product
if not verified_course_id and getattr(product.attr, 'id_verification_required', False): for line in order.lines.all():
verified_course_id = product.attr.course_key product = line.product
if verified_course_id: if (getattr(product.attr, 'id_verification_required', False) and
(getattr(product.attr, 'course_key', False) or getattr(product.attr, 'UUID', False))):
context.update({ context.update({
'verification_url': site.siteconfiguration.build_lms_url('verify_student/reverify'), 'verification_url': site.siteconfiguration.build_lms_url('verify_student/reverify'),
'user_verified': request.user.is_verified(site), 'user_verified': request.user.is_verified(site),
}) })
return context
return context return context
......
...@@ -40,7 +40,7 @@ class RefundTestMixin(DiscoveryTestMixin): ...@@ -40,7 +40,7 @@ class RefundTestMixin(DiscoveryTestMixin):
) )
def create_order(self, user=None, credit=False, multiple_lines=False, free=False, def create_order(self, user=None, credit=False, multiple_lines=False, free=False,
entitlement=False, status=ORDER.COMPLETE): entitlement=False, status=ORDER.COMPLETE, id_verification_required=False):
user = user or self.user user = user or self.user
basket = BasketFactory(owner=user, site=self.site) basket = BasketFactory(owner=user, site=self.site)
...@@ -52,8 +52,15 @@ class RefundTestMixin(DiscoveryTestMixin): ...@@ -52,8 +52,15 @@ class RefundTestMixin(DiscoveryTestMixin):
elif free: elif free:
basket.add_product(self.honor_product) basket.add_product(self.honor_product)
elif entitlement: elif entitlement:
self.course_entitlement = create_or_update_course_entitlement('verified', 100, self.partner, '111', 'Foo') course_entitlement = create_or_update_course_entitlement(
basket.add_product(self.course_entitlement) certificate_type='verified',
price=100,
partner=self.partner,
UUID='111',
name='Foo',
id_verification_required=id_verification_required
)
basket.add_product(course_entitlement)
else: else:
basket.add_product(self.verified_product) basket.add_product(self.verified_product)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment