Commit 8930376b by Cliff Dyer Committed by GitHub

Merge pull request #13540 from edx/cdyer/visible-block-version

Add version to VisibleBlocks model.
parents fb10ab07 37fc450b
...@@ -23,6 +23,8 @@ from xmodule_django.models import CourseKeyField, UsageKeyField ...@@ -23,6 +23,8 @@ from xmodule_django.models import CourseKeyField, UsageKeyField
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
BLOCK_RECORD_LIST_VERSION = 1
# Used to serialize information about a block at the time it was used in # Used to serialize information about a block at the time it was used in
# grade calculation. # grade calculation.
BlockRecord = namedtuple('BlockRecord', ['locator', 'weight', 'max_score']) BlockRecord = namedtuple('BlockRecord', ['locator', 'weight', 'max_score'])
...@@ -33,12 +35,13 @@ class BlockRecordList(tuple): ...@@ -33,12 +35,13 @@ class BlockRecordList(tuple):
An immutable ordered list of BlockRecord objects. An immutable ordered list of BlockRecord objects.
""" """
def __new__(cls, blocks, course_key): # pylint: disable=unused-argument def __new__(cls, blocks, course_key, version=None): # pylint: disable=unused-argument
return super(BlockRecordList, cls).__new__(cls, blocks) return super(BlockRecordList, cls).__new__(cls, blocks)
def __init__(self, blocks, course_key): def __init__(self, blocks, course_key, version=None):
super(BlockRecordList, self).__init__(blocks) super(BlockRecordList, self).__init__(blocks)
self.course_key = course_key self.course_key = course_key
self.version = version or BLOCK_RECORD_LIST_VERSION
def __eq__(self, other): def __eq__(self, other):
assert isinstance(other, BlockRecordList) assert isinstance(other, BlockRecordList)
...@@ -73,8 +76,9 @@ class BlockRecordList(tuple): ...@@ -73,8 +76,9 @@ class BlockRecordList(tuple):
for block_dict in list_of_block_dicts: for block_dict in list_of_block_dicts:
block_dict['locator'] = unicode(block_dict['locator']) # BlockUsageLocator is not json-serializable block_dict['locator'] = unicode(block_dict['locator']) # BlockUsageLocator is not json-serializable
data = { data = {
'course_key': unicode(self.course_key), u'blocks': list_of_block_dicts,
'blocks': list_of_block_dicts, u'course_key': unicode(self.course_key),
u'version': self.version,
} }
return json.dumps( return json.dumps(
data, data,
...@@ -98,7 +102,7 @@ class BlockRecordList(tuple): ...@@ -98,7 +102,7 @@ class BlockRecordList(tuple):
) )
for block in block_dicts for block in block_dicts
) )
return cls(record_generator, course_key) return cls(record_generator, course_key, version=data['version'])
@classmethod @classmethod
def from_list(cls, blocks, course_key): def from_list(cls, blocks, course_key):
...@@ -121,7 +125,7 @@ class VisibleBlocksQuerySet(models.QuerySet): ...@@ -121,7 +125,7 @@ class VisibleBlocksQuerySet(models.QuerySet):
""" """
model, _ = self.get_or_create( model, _ = self.get_or_create(
hashed=blocks.hash_value, hashed=blocks.hash_value,
defaults={'blocks_json': blocks.json_value, 'course_id': blocks.course_key}, defaults={u'blocks_json': blocks.json_value, u'course_id': blocks.course_key},
) )
return model return model
......
...@@ -14,6 +14,7 @@ from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator ...@@ -14,6 +14,7 @@ from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator
from lms.djangoapps.grades.models import ( from lms.djangoapps.grades.models import (
BlockRecord, BlockRecord,
BlockRecordList, BlockRecordList,
BLOCK_RECORD_LIST_VERSION,
PersistentSubsectionGrade, PersistentSubsectionGrade,
VisibleBlocks VisibleBlocks
) )
...@@ -32,7 +33,10 @@ class BlockRecordListTestCase(TestCase): ...@@ -32,7 +33,10 @@ class BlockRecordListTestCase(TestCase):
) )
def test_empty_block_record_set(self): def test_empty_block_record_set(self):
empty_json = '{0}"blocks":[],"course_key":"{1}"{2}'.format('{', unicode(self.course_key), '}') empty_json = u'{"blocks":[],"course_key":"%s","version":%s}' % (
unicode(self.course_key),
BLOCK_RECORD_LIST_VERSION,
)
brs = BlockRecordList((), self.course_key) brs = BlockRecordList((), self.course_key)
self.assertFalse(brs) self.assertFalse(brs)
...@@ -100,7 +104,7 @@ class BlockRecordTest(GradesModelTestCase): ...@@ -100,7 +104,7 @@ class BlockRecordTest(GradesModelTestCase):
@ddt.unpack @ddt.unpack
def test_serialization(self, weight, max_score, block_key): def test_serialization(self, weight, max_score, block_key):
""" """
Tests serialization of a BlockRecord using the to_dict() method. Tests serialization of a BlockRecord using the _asdict() method.
""" """
record = BlockRecord(block_key, weight, max_score) record = BlockRecord(block_key, weight, max_score)
expected = OrderedDict([ expected = OrderedDict([
...@@ -130,10 +134,9 @@ class VisibleBlocksTest(GradesModelTestCase): ...@@ -130,10 +134,9 @@ class VisibleBlocksTest(GradesModelTestCase):
for block_dict in list_of_block_dicts: for block_dict in list_of_block_dicts:
block_dict['locator'] = unicode(block_dict['locator']) # BlockUsageLocator is not json-serializable block_dict['locator'] = unicode(block_dict['locator']) # BlockUsageLocator is not json-serializable
expected_data = { expected_data = {
'blocks': [{'locator': unicode(self.record_a.locator), 'max_score': 10, 'weight': 1}],
'course_key': unicode(self.record_a.locator.course_key), 'course_key': unicode(self.record_a.locator.course_key),
'blocks': [ 'version': BLOCK_RECORD_LIST_VERSION,
{'locator': unicode(self.record_a.locator), 'max_score': 10, 'weight': 1},
],
} }
expected_json = json.dumps(expected_data, separators=(',', ':'), sort_keys=True) expected_json = json.dumps(expected_data, separators=(',', ':'), sort_keys=True)
expected_hash = b64encode(sha1(expected_json).digest()) expected_hash = b64encode(sha1(expected_json).digest())
......
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