Commit d852aa8b by Nimisha Asthagiri

Missing grades tests and

Don't persist when creating grades unless policy changed.
parent cd60e627
...@@ -30,14 +30,14 @@ class CourseData(object): ...@@ -30,14 +30,14 @@ class CourseData(object):
if self._course: if self._course:
self._course_key = self._course.id self._course_key = self._course.id
else: else:
structure = self.effective_structure structure = self._effective_structure
self._course_key = structure.root_block_usage_key.course_key self._course_key = structure.root_block_usage_key.course_key
return self._course_key return self._course_key
@property @property
def location(self): def location(self):
if not self._location: if not self._location:
structure = self.effective_structure structure = self._effective_structure
if structure: if structure:
self._location = structure.root_block_usage_key self._location = structure.root_block_usage_key
elif self._course: elif self._course:
...@@ -64,7 +64,7 @@ class CourseData(object): ...@@ -64,7 +64,7 @@ class CourseData(object):
@property @property
def grading_policy_hash(self): def grading_policy_hash(self):
structure = self.effective_structure structure = self._effective_structure
if structure: if structure:
return structure.get_transformer_block_field( return structure.get_transformer_block_field(
structure.root_block_usage_key, structure.root_block_usage_key,
...@@ -76,7 +76,7 @@ class CourseData(object): ...@@ -76,7 +76,7 @@ class CourseData(object):
@property @property
def version(self): def version(self):
structure = self.effective_structure structure = self._effective_structure
course_block = structure[self.location] if structure else self.course course_block = structure[self.location] if structure else self.course
return getattr(course_block, 'course_version', None) return getattr(course_block, 'course_version', None)
...@@ -86,17 +86,17 @@ class CourseData(object): ...@@ -86,17 +86,17 @@ class CourseData(object):
course_block = self.structure[self.location] course_block = self.structure[self.location]
return getattr(course_block, 'subtree_edited_on', None) return getattr(course_block, 'subtree_edited_on', None)
@property
def effective_structure(self):
return self._structure or self._collected_block_structure
def __unicode__(self): def __unicode__(self):
return u'Course: course_key: {}'.format(self.course_key) return u'Course: course_key: {}'.format(self.course_key)
def full_string(self): def full_string(self):
if self.effective_structure: if self._effective_structure:
return u'Course: course_key: {}, version: {}, edited_on: {}, grading_policy: {}'.format( return u'Course: course_key: {}, version: {}, edited_on: {}, grading_policy: {}'.format(
self.course_key, self.version, self.edited_on, self.grading_policy_hash, self.course_key, self.version, self.edited_on, self.grading_policy_hash,
) )
else: else:
return u'Course: course_key: {}, empty course structure'.format(self.course_key) return u'Course: course_key: {}, empty course structure'.format(self.course_key)
@property
def _effective_structure(self):
return self._structure or self._collected_block_structure
...@@ -65,6 +65,18 @@ class CourseGradeBase(object): ...@@ -65,6 +65,18 @@ class CourseGradeBase(object):
} }
@lazy @lazy
def subsection_grades(self):
"""
Returns an ordered dictionary of subsection grades,
keyed by subsection location.
"""
subsection_grades = defaultdict(OrderedDict)
for chapter in self.chapter_grades.itervalues():
for subsection_grade in chapter['sections']:
subsection_grades[subsection_grade.location] = subsection_grade
return subsection_grades
@lazy
def locations_to_scores(self): def locations_to_scores(self):
""" """
Returns a dict of problem scores keyed by their locations. Returns a dict of problem scores keyed by their locations.
......
...@@ -153,9 +153,9 @@ class CourseGradeFactory(object): ...@@ -153,9 +153,9 @@ class CourseGradeFactory(object):
course_grade.update() course_grade.update()
should_persist = ( should_persist = (
not read_only and # TODO(TNL-6786) Remove the read_only boolean once all grades are back-filled. (not read_only) and # TODO(TNL-6786) Remove the read_only boolean once all grades are back-filled.
should_persist_grades(course_data.course_key) and should_persist_grades(course_data.course_key) and
not waffle().is_enabled(WRITE_ONLY_IF_ENGAGED) or course_grade.attempted (not waffle().is_enabled(WRITE_ONLY_IF_ENGAGED) or course_grade.attempted)
) )
if should_persist: if should_persist:
course_grade._subsection_grade_factory.bulk_create_unsaved() course_grade._subsection_grade_factory.bulk_create_unsaved()
......
""" """
Tests for CourseData utility class. Tests for CourseData utility class.
""" """
from lms.djangoapps.course_blocks.api import get_course_blocks
from mock import patch from mock import patch
from lms.djangoapps.course_blocks.api import get_course_blocks
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from ..new.course_data import CourseData from ..new.course_data import CourseData
...@@ -16,7 +18,10 @@ class CourseDataTest(ModuleStoreTestCase): ...@@ -16,7 +18,10 @@ class CourseDataTest(ModuleStoreTestCase):
def setUp(self): def setUp(self):
super(CourseDataTest, self).setUp() super(CourseDataTest, self).setUp()
self.course = CourseFactory.create() with self.store.default_store(ModuleStoreEnum.Type.split):
self.course = CourseFactory.create()
# need to re-retrieve the course since the version on the original course isn't accurate.
self.course = self.store.get_course(self.course.id)
self.user = UserFactory.create() self.user = UserFactory.create()
self.one_true_structure = get_course_blocks(self.user, self.course.location) self.one_true_structure = get_course_blocks(self.user, self.course.location)
self.expected_results = { self.expected_results = {
...@@ -45,11 +50,28 @@ class CourseDataTest(ModuleStoreTestCase): ...@@ -45,11 +50,28 @@ class CourseDataTest(ModuleStoreTestCase):
actual = getattr(course_data, arg) actual = getattr(course_data, arg)
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
def test_no_data(self): def test_properties(self):
""" expected_edited_on = getattr(
Tests to ensure ??? happens when none of the data are provided. self.one_true_structure[self.one_true_structure.root_block_usage_key],
'subtree_edited_on',
)
Maybe a dict pairing asked-for properties to resulting exceptions? Or an exception on init? for kwargs in [
""" dict(course=self.course),
dict(collected_block_structure=self.one_true_structure),
dict(structure=self.one_true_structure),
dict(course_key=self.course.id),
]:
course_data = CourseData(self.user, **kwargs)
self.assertEquals(course_data.course_key, self.course.id)
self.assertEquals(course_data.location, self.course.location)
self.assertEquals(course_data.structure.root_block_usage_key, self.one_true_structure.root_block_usage_key)
self.assertEquals(course_data.course.id, self.course.id)
self.assertEquals(course_data.version, self.course.course_version)
self.assertEquals(course_data.edited_on, expected_edited_on)
self.assertIn(u'Course: course_key', unicode(course_data))
self.assertIn(u'Course: course_key', course_data.full_string())
def test_no_data(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
_ = CourseData(self.user) _ = CourseData(self.user)
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