Stop the commerce API from deleting Masters course modes.

This commit is contained in:
Kyle McCormick
2019-07-23 16:42:06 -04:00
committed by Alex Dusenbery
parent 4feaa7971d
commit 9f9a07db4f
3 changed files with 47 additions and 15 deletions

View File

@@ -107,8 +107,20 @@ class Course(object):
merged_modes.add(merged_mode)
merged_mode_keys.add(merged_mode.mode_slug)
deleted_modes = set(existing_modes.keys()) - merged_mode_keys
self._deleted_modes = [existing_modes[mode] for mode in deleted_modes]
# Masters degrees are not sold through the eCommerce site.
# So, Masters course modes are not included in PUT calls to this API,
# and their omission which would normally cause them to be deleted.
# We don't want that to happen, but for the time being,
# we cannot include in Masters modes in the PUT calls from eCommerce.
# So, here's hack to handle Masters course modes, along with any other
# modes that end up in that boat.
MODES_TO_NOT_DELETE = {
CourseMode.MASTERS,
}
modes_to_delete = set(existing_modes.keys()) - merged_mode_keys
modes_to_delete -= MODES_TO_NOT_DELETE
self._deleted_modes = [existing_modes[mode] for mode in modes_to_delete]
self.modes = list(merged_modes)
@classmethod

View File

@@ -24,6 +24,6 @@ class IsAuthenticatedOrActivationOverridden(BasePermission):
if not request.user.is_authenticated and is_account_activation_requirement_disabled():
try:
request.user = User.objects.get(id=request.session._session_cache['_auth_user_id'])
except DoesNotExist:
except User.DoesNotExist:
pass
return request.user.is_authenticated

View File

@@ -287,25 +287,45 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
self.assertIsNone(updated_verified_mode.expiration_datetime)
def test_update_overwrite(self):
""" Verify that data submitted via PUT overwrites/deletes modes that are
not included in the body of the request. """
course_id = six.text_type(self.course.id)
expected_course_mode = CourseMode(
"""
Verify that data submitted via PUT overwrites/deletes modes that are
not included in the body of the request, EXCEPT the Masters mode,
which it leaves alone.
"""
existing_mode = self.course_mode
existing_masters_mode = CourseMode.objects.create(
course_id=self.course.id,
mode_slug=u'masters',
min_price=10000,
currency=u'USD',
sku=u'DEF456',
bulk_sku=u'BULK-DEF456'
)
new_mode = CourseMode(
course_id=self.course.id,
mode_slug=u'credit',
min_price=500,
currency=u'USD',
sku=u'ABC123',
bulk_sku=u'BULK-ABC123'
)
expected = self._serialize_course(self.course, [expected_course_mode])
path = reverse('commerce_api:v1:courses:retrieve_update', args=[course_id])
response = self.client.put(path, json.dumps(expected), content_type=JSON_CONTENT_TYPE)
self.assertEqual(response.status_code, 200)
actual = json.loads(response.content)
self.assertEqual(actual, expected)
# The existing CourseMode should have been removed.
self.assertFalse(CourseMode.objects.filter(id=self.course_mode.id).exists())
path = reverse('commerce_api:v1:courses:retrieve_update', args=[six.text_type(self.course.id)])
data = json.dumps(self._serialize_course(self.course, [new_mode]))
response = self.client.put(path, data, content_type=JSON_CONTENT_TYPE)
self.assertEqual(response.status_code, 200)
# Check modes list in response, disregarding its order.
expected_dict = self._serialize_course(self.course, [new_mode])
expected_items = expected_dict['modes']
actual_items = json.loads(response.content)['modes']
self.assertCountEqual(actual_items, expected_items)
# The existing non-Masters CourseMode should have been removed.
self.assertFalse(CourseMode.objects.filter(id=existing_mode.id).exists())
# The existing Masters course mode should remain.
self.assertTrue(CourseMode.objects.filter(id=existing_masters_mode.id).exists())
@ddt.data(*itertools.product(
('honor', 'audit', 'verified', 'professional', 'no-id-professional'),