Commit cf39bef7 by Tyler Hallada

GradesService: accept both string id or opaque key

parent 39a27ac7
from opaque_keys.edx.keys import CourseKey, UsageKey
from lms.djangoapps.grades.models import PersistentSubsectionGrade, PersistentSubsectionGradeOverride 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): class GradesService(object):
""" """
Course grade service Course grade service
...@@ -8,32 +21,39 @@ class GradesService(object): ...@@ -8,32 +21,39 @@ class GradesService(object):
Provides various functions related to getting, setting, and overriding user grades. 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 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. 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( grade = PersistentSubsectionGrade.objects.get(
user_id=user_id, user_id=user_id,
course_id=course_key_or_id, course_id=course_key,
usage_key=subsection usage_key=usage_key
) )
return { return {
'earned_all': grade.earned_all, 'earned_all': grade.earned_all,
'earned_graded': grade.earned_graded '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) 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. 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( grade = PersistentSubsectionGrade.objects.get(
user_id=user_id, user_id=user_id,
course_id=course_key_or_id, course_id=course_key,
usage_key=subsection usage_key=subsection_key
) )
# Create override that will prevent any future updates to grade # Create override that will prevent any future updates to grade
......
import ddt import ddt
from lms.djangoapps.grades.models import PersistentSubsectionGrade, PersistentSubsectionGradeOverride 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 student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
...@@ -33,7 +34,17 @@ class GradesServiceTests(ModuleStoreTestCase): ...@@ -33,7 +34,17 @@ class GradesServiceTests(ModuleStoreTestCase):
self.assertDictEqual(self.service.get_subsection_grade( self.assertDictEqual(self.service.get_subsection_grade(
user_id=self.user.id, user_id=self.user.id,
course_key_or_id=self.course.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_all': 6.0,
'earned_graded': 5.0 'earned_graded': 5.0
...@@ -76,7 +87,7 @@ class GradesServiceTests(ModuleStoreTestCase): ...@@ -76,7 +87,7 @@ class GradesServiceTests(ModuleStoreTestCase):
self.service.override_subsection_grade( self.service.override_subsection_grade(
user_id=self.user.id, user_id=self.user.id,
course_key_or_id=self.course.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_all=override['earned_all'],
earned_graded=override['earned_graded'] earned_graded=override['earned_graded']
) )
...@@ -89,3 +100,17 @@ class GradesServiceTests(ModuleStoreTestCase): ...@@ -89,3 +100,17 @@ class GradesServiceTests(ModuleStoreTestCase):
self.assertEqual(grade.earned_all, expected['earned_all']) self.assertEqual(grade.earned_all, expected['earned_all'])
self.assertEqual(grade.earned_graded, expected['earned_graded']) 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)
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