From cf39bef74fa28cc60deb76088e165e25e00c0de4 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Wed, 26 Jul 2017 15:49:26 -0400 Subject: [PATCH] GradesService: accept both string id or opaque key --- lms/djangoapps/grades/services.py | 32 ++++++++++++++++---- lms/djangoapps/grades/tests/test_services.py | 31 +++++++++++++++++-- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/lms/djangoapps/grades/services.py b/lms/djangoapps/grades/services.py index 7fec14824d..d6f76444d2 100644 --- a/lms/djangoapps/grades/services.py +++ b/lms/djangoapps/grades/services.py @@ -1,6 +1,19 @@ +from opaque_keys.edx.keys import CourseKey, UsageKey from lms.djangoapps.grades.models import PersistentSubsectionGrade, PersistentSubsectionGradeOverride +def _get_key(key_or_id, key_cls): + """ + Helper method to get a course/usage key either from a string or a key_cls, + where the key_cls (CourseKey or UsageKey) will simply be returned. + """ + return ( + key_cls.from_string(key_or_id) + if isinstance(key_or_id, basestring) + else key_or_id + ) + + class GradesService(object): """ Course grade service @@ -8,32 +21,39 @@ class GradesService(object): Provides various functions related to getting, setting, and overriding user grades. """ - def get_subsection_grade(self, user_id, course_key_or_id, subsection): + def get_subsection_grade(self, user_id, course_key_or_id, usage_key_or_id): """ Finds and returns the earned subsection grade for user Result is a dict of two key value pairs with keys: earned_all and earned_graded. """ + course_key = _get_key(course_key_or_id, CourseKey) + usage_key = _get_key(usage_key_or_id, UsageKey) + grade = PersistentSubsectionGrade.objects.get( user_id=user_id, - course_id=course_key_or_id, - usage_key=subsection + course_id=course_key, + usage_key=usage_key ) return { 'earned_all': grade.earned_all, 'earned_graded': grade.earned_graded } - def override_subsection_grade(self, user_id, course_key_or_id, subsection, earned_all=None, earned_graded=None): + def override_subsection_grade(self, user_id, course_key_or_id, usage_key_or_id, earned_all=None, + earned_graded=None): """ Override subsection grade (the PersistentSubsectionGrade model must already exist) Will not override earned_all or earned_graded value if they are None. Both default to None. """ + course_key = _get_key(course_key_or_id, CourseKey) + subsection_key = _get_key(usage_key_or_id, UsageKey) + grade = PersistentSubsectionGrade.objects.get( user_id=user_id, - course_id=course_key_or_id, - usage_key=subsection + course_id=course_key, + usage_key=subsection_key ) # Create override that will prevent any future updates to grade diff --git a/lms/djangoapps/grades/tests/test_services.py b/lms/djangoapps/grades/tests/test_services.py index 223440cf77..7b09eb2918 100644 --- a/lms/djangoapps/grades/tests/test_services.py +++ b/lms/djangoapps/grades/tests/test_services.py @@ -1,6 +1,7 @@ import ddt from lms.djangoapps.grades.models import PersistentSubsectionGrade, PersistentSubsectionGradeOverride -from lms.djangoapps.grades.services import GradesService +from lms.djangoapps.grades.services import GradesService, _get_key +from opaque_keys.edx.keys import CourseKey, UsageKey from student.tests.factories import UserFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory @@ -33,7 +34,17 @@ class GradesServiceTests(ModuleStoreTestCase): self.assertDictEqual(self.service.get_subsection_grade( user_id=self.user.id, course_key_or_id=self.course.id, - subsection=self.subsection.location + usage_key_or_id=self.subsection.location + ), { + 'earned_all': 6.0, + 'earned_graded': 5.0 + }) + + # test with id strings as parameters instead + self.assertDictEqual(self.service.get_subsection_grade( + user_id=self.user.id, + course_key_or_id=str(self.course.id), + usage_key_or_id=str(self.subsection.location) ), { 'earned_all': 6.0, 'earned_graded': 5.0 @@ -76,7 +87,7 @@ class GradesServiceTests(ModuleStoreTestCase): self.service.override_subsection_grade( user_id=self.user.id, course_key_or_id=self.course.id, - subsection=self.subsection.location, + usage_key_or_id=self.subsection.location, earned_all=override['earned_all'], earned_graded=override['earned_graded'] ) @@ -89,3 +100,17 @@ class GradesServiceTests(ModuleStoreTestCase): self.assertEqual(grade.earned_all, expected['earned_all']) self.assertEqual(grade.earned_graded, expected['earned_graded']) + + @ddt.data( + ['edX/DemoX/Demo_Course', CourseKey.from_string('edX/DemoX/Demo_Course'), CourseKey], + ['course-v1:edX+DemoX+Demo_Course', CourseKey.from_string('course-v1:edX+DemoX+Demo_Course'), CourseKey], + [CourseKey.from_string('course-v1:edX+DemoX+Demo_Course'), + CourseKey.from_string('course-v1:edX+DemoX+Demo_Course'), CourseKey], + ['block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow', + UsageKey.from_string('block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow'), UsageKey], + [UsageKey.from_string('block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow'), + UsageKey.from_string('block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow'), UsageKey], + ) + @ddt.unpack + def test_get_key(self, input_key, output_key, key_cls): + self.assertEqual(_get_key(input_key, key_cls), output_key)