Commit dd809dfd by sanfordstudent Committed by GitHub

Merge pull request #13961 from edx/sstudent/TNL-5895

Add first_attempted to subsection grades data model
parents 48507af2 6d50044e
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('grades', '0007_add_passed_timestamp_column'),
]
operations = [
migrations.AddField(
model_name='persistentsubsectiongrade',
name='first_attempted',
field=models.DateTimeField(null=True, blank=True),
),
]
......@@ -236,6 +236,11 @@ class PersistentSubsectionGrade(TimeStampedModel):
earned_graded = models.FloatField(blank=False)
possible_graded = models.FloatField(blank=False)
# timestamp for the learner's first attempt at content in
# this subsection. If null, indicates no attempt
# has yet been made.
first_attempted = models.DateTimeField(null=True, blank=True)
# track which blocks were visible at the time of grade calculation
visible_blocks = models.ForeignKey(VisibleBlocks, db_column='visible_blocks_hash', to_field='hashed')
......@@ -253,7 +258,9 @@ class PersistentSubsectionGrade(TimeStampedModel):
"""
Returns a string representation of this model.
"""
return u"{} user: {}, course version: {}, subsection {} ({}). {}/{} graded, {}/{} all".format(
return (
u"{} user: {}, course version: {}, subsection: {} ({}). {}/{} graded, {}/{} all, first_attempted: {}"
).format(
type(self).__name__,
self.user_id,
self.course_version,
......@@ -263,6 +270,7 @@ class PersistentSubsectionGrade(TimeStampedModel):
self.possible_graded,
self.earned_all,
self.possible_all,
self.first_attempted,
)
@classmethod
......
......@@ -210,6 +210,7 @@ class PersistentSubsectionGradeTest(GradesModelTestCase):
"earned_graded": 6.0,
"possible_graded": 8.0,
"visible_blocks": self.block_records,
"first_attempted": "2016-08-01 18:53:24.354741",
}
def test_create(self):
......@@ -235,10 +236,27 @@ class PersistentSubsectionGradeTest(GradesModelTestCase):
with self.assertRaises(IntegrityError):
PersistentSubsectionGrade.create_grade(**self.params)
def test_course_version_is_optional(self):
del self.params["course_version"]
@ddt.data("course_version", "first_attempted")
def test_optional_fields(self, field):
del self.params[field]
PersistentSubsectionGrade.create_grade(**self.params)
@ddt.data(
("user_id", IntegrityError),
("usage_key", KeyError),
("subtree_edited_timestamp", IntegrityError),
("earned_all", IntegrityError),
("possible_all", IntegrityError),
("earned_graded", IntegrityError),
("possible_graded", IntegrityError),
("visible_blocks", KeyError),
)
@ddt.unpack
def test_non_optional_fields(self, field, error):
del self.params[field]
with self.assertRaises(error):
PersistentSubsectionGrade.create_grade(**self.params)
@ddt.data(True, False)
def test_update_or_create_grade(self, already_created):
created_grade = PersistentSubsectionGrade.create_grade(**self.params) if already_created else None
......
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