diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 1097f71568..86032527b6 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -4,7 +4,7 @@ Django module container for classes and operations related to the "Course Module import json import logging from cStringIO import StringIO -from datetime import datetime +from datetime import datetime, timedelta import requests from lazy import lazy @@ -187,6 +187,10 @@ class CourseFields(object): scope=Scope.settings ) end = Date(help=_("Date that this class ends"), scope=Scope.settings) + certificate_available_date = Date( + help=_("Date that certificates become available to learners"), + scope=Scope.content + ) cosmetic_display_price = Integer( display_name=_("Cosmetic Course Display Price"), help=_( @@ -530,7 +534,7 @@ class CourseFields(object): default=False, ) cert_html_view_overrides = Dict( - # Translators: This field is the container for course-specific certifcate configuration values + # Translators: This field is the container for course-specific certificate configuration values display_name=_("Certificate Web/HTML View Overrides"), # Translators: These overrides allow for an alternative configuration of the certificate web view help=_("Enter course-specific overrides for the Web/HTML template parameters here (JSON format)"), @@ -539,7 +543,7 @@ class CourseFields(object): # Specific certificate information managed via Studio (should eventually fold other cert settings into this) certificates = Dict( - # Translators: This field is the container for course-specific certifcate configuration values + # Translators: This field is the container for course-specific certificate configuration values display_name=_("Certificate Configuration"), # Translators: These overrides allow for an alternative configuration of the certificate web view help=_("Enter course-specific configuration information here (JSON format)"), @@ -915,6 +919,8 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): except InvalidTabsException as err: raise type(err)('{msg} For course: {course_id}'.format(msg=err.message, course_id=unicode(self.id))) + self.set_default_certificate_available_date() + def set_grading_policy(self, course_policy): """ The JSON object can have the keys GRADER and GRADE_CUTOFFS. If either is @@ -940,6 +946,10 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): self.raw_grader = grading_policy['GRADER'] # used for cms access self.grade_cutoffs = grading_policy['GRADE_CUTOFFS'] + def set_default_certificate_available_date(self): + if (not self.certificate_available_date) and self.end: + self.certificate_available_date = self.end + timedelta(days=2) + @classmethod def read_grading_policy(cls, paths, system): """Load a grading policy from the specified paths, in order, if it exists.""" diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py index ecda5cc450..c6d0a72b91 100644 --- a/common/lib/xmodule/xmodule/seq_module.py +++ b/common/lib/xmodule/xmodule/seq_module.py @@ -523,7 +523,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule): class SequenceDescriptor(SequenceFields, ProctoringFields, MakoModuleDescriptor, XmlDescriptor): """ - A Sequences Descriptor object + A Sequence's Descriptor object """ mako_template = 'widgets/sequence-edit.html' module_class = SequenceModule diff --git a/common/lib/xmodule/xmodule/tests/test_course_module.py b/common/lib/xmodule/xmodule/tests/test_course_module.py index 35c9322017..a5f8b72371 100644 --- a/common/lib/xmodule/xmodule/tests/test_course_module.py +++ b/common/lib/xmodule/xmodule/tests/test_course_module.py @@ -359,7 +359,7 @@ class CourseDescriptorTestCase(unittest.TestCase): Initialize dummy testing course. """ super(CourseDescriptorTestCase, self).setUp() - self.course = get_dummy_course(start=_TODAY) + self.course = get_dummy_course(start=_TODAY, end=_NEXT_WEEK) def test_clean_id(self): """ @@ -388,3 +388,11 @@ class CourseDescriptorTestCase(unittest.TestCase): Test CourseDescriptor.number. """ self.assertEqual(self.course.number, COURSE) + + def test_set_default_certificate_available_date(self): + """ + The certificate_available_date field should default to two days + after the course end date. + """ + expected_certificate_available_date = self.course.end + timedelta(days=2) + self.assertEqual(expected_certificate_available_date, self.course.certificate_available_date)