Commit 59c7da23 by Renzo Lucioni

Update Course model to allow creation of multiple credit seats

Courses may have multiple credit seats associated with them. To make this possible, the query used to locate existing seats has been extended to include credit provider in the query. Our SKU generation utility has also been modified to include the credit provider in the hash. XCOM-574.
parent 8866134c
......@@ -138,8 +138,24 @@ class Course(models.Model):
attribute_values__value_boolean=id_verification_required
)
if credit_provider is None:
# Yields a match if attribute names do not include 'credit_provider'.
credit_provider_query = ~Q(attributes__name='credit_provider')
else:
# Yields a match if attribute with name 'credit_provider' matches provided value.
credit_provider_query = Q(
attributes__name='credit_provider',
attribute_values__value_text=credit_provider
)
try:
seat = self.seat_products.filter(certificate_type_query).get(id_verification_required_query)
seat = self.seat_products.filter(
certificate_type_query
).filter(
id_verification_required_query
).get(
credit_provider_query
)
logger.info(
'Retrieved course seat child product with certificate type [%s] for [%s] from database.',
......
......@@ -107,31 +107,56 @@ class CourseTests(CourseCatalogTestMixin, TestCase):
""" Verify the method creates or updates a seat Product. """
course = Course.objects.create(id='a/b/c', name='Test Course')
# Test creation
certificate_type = 'honor'
# Test seat creation
certificate_type = 'verified'
id_verification_required = True
price = 0
price = 5
course.create_or_update_seat(certificate_type, id_verification_required, price)
# Two seats: one honor, the other the parent seat product
# Two seats: one verified, the other the parent seat product
self.assertEqual(course.products.count(), 2)
seat = course.seat_products[0]
self.assert_course_seat_valid(seat, course, certificate_type, id_verification_required, price)
# Test update
price = 100
credit_provider = 'MIT'
credit_hours = 2
course.create_or_update_seat(
certificate_type, id_verification_required, price, credit_provider, credit_hours=credit_hours
)
# Test seat update
price = 10
course.create_or_update_seat(certificate_type, id_verification_required, price)
# Again, only two seats with one being the parent seat product.
self.assertEqual(course.products.count(), 2)
seat = course.seat_products[0]
self.assert_course_seat_valid(
seat, course, certificate_type, id_verification_required, price, credit_provider, credit_hours=credit_hours
)
self.assert_course_seat_valid(seat, course, certificate_type, id_verification_required, price)
def test_create_credit_seats(self):
"""Verify that the model's seat creation method allows the creation of multiple credit seats."""
course = Course.objects.create(id='a/b/c', name='Test Course')
credit_data = {'MIT': 2, 'Harvard': 0.5}
certificate_type = 'credit'
id_verification_required = True
price = 10
# Verify that the course can have multiple credit seats added to it
for credit_provider, credit_hours in credit_data.iteritems():
credit_seat = course.create_or_update_seat(
certificate_type,
id_verification_required,
price,
credit_provider=credit_provider,
credit_hours=credit_hours
)
self.assert_course_seat_valid(
credit_seat,
course,
certificate_type,
id_verification_required,
price,
credit_provider=credit_provider,
credit_hours=credit_hours
)
# Expected seat total, with one being the parent seat product.
self.assertEqual(course.products.count(), len(credit_data) + 1)
def test_collision_avoidance(self):
"""
......
......@@ -15,7 +15,8 @@ class UtilsTests(CourseCatalogTestMixin, TestCase):
certificate_type = 'honor'
product = course.create_or_update_seat(certificate_type, False, 0)
_hash = md5(u'{} {} {}'.format(certificate_type, course_id, 'False')).hexdigest()[-7:]
_hash = u'{} {} {} {}'.format(certificate_type, course_id, 'False', '')
_hash = md5(_hash.lower()).hexdigest()[-7:]
expected = _hash.upper()
actual = generate_sku(product)
self.assertEqual(actual, expected)
......@@ -10,11 +10,12 @@ def generate_sku(product):
# Note: This currently supports seats. In the future, this should
# be updated to accommodate other product classes.
_hash = u' '.join((
getattr(product.attr, 'certificate_type', '').lower(),
product.attr.course_key.lower(),
unicode(product.attr.id_verification_required)
getattr(product.attr, 'certificate_type', ''),
product.attr.course_key,
unicode(product.attr.id_verification_required),
getattr(product.attr, 'credit_provider', '')
))
_hash = md5(_hash)
_hash = md5(_hash.lower())
_hash = _hash.hexdigest()[-7:]
return _hash.upper()
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