GradesService: accept both string id or opaque key
This commit is contained in:
@@ -1,6 +1,19 @@
|
|||||||
|
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):
|
|||||||
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
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user