Auto setting of verification deadlines with manual overrides
This commit is contained in:
@@ -58,8 +58,9 @@ class Course(object):
|
||||
def save(self, *args, **kwargs): # pylint: disable=unused-argument
|
||||
""" Save the CourseMode objects to the database. """
|
||||
|
||||
# Update the verification deadline for the course (not the individual modes)
|
||||
VerificationDeadline.set_deadline(self.id, self.verification_deadline)
|
||||
# Override the verification deadline for the course (not the individual modes)
|
||||
if self.verification_deadline is not None:
|
||||
VerificationDeadline.set_deadline(self.id, self.verification_deadline, is_explicit=True)
|
||||
|
||||
for mode in self.modes:
|
||||
mode.course_id = self.id
|
||||
@@ -87,7 +88,8 @@ class Course(object):
|
||||
merged_mode.min_price = posted_mode.min_price
|
||||
merged_mode.currency = posted_mode.currency
|
||||
merged_mode.sku = posted_mode.sku
|
||||
merged_mode.expiration_datetime = posted_mode.expiration_datetime
|
||||
if posted_mode.expiration_datetime is not None:
|
||||
merged_mode.expiration_datetime = posted_mode.expiration_datetime
|
||||
merged_mode.save()
|
||||
|
||||
merged_modes.add(merged_mode)
|
||||
|
||||
@@ -1531,7 +1531,7 @@ def financial_assistance_form(request):
|
||||
{'name': enrollment.course_overview.display_name, 'value': unicode(enrollment.course_id)}
|
||||
for enrollment in CourseEnrollment.enrollments_for_user(user).order_by('-created')
|
||||
if CourseMode.objects.filter(
|
||||
Q(expiration_datetime__isnull=True) | Q(expiration_datetime__gt=datetime.now(UTC())),
|
||||
Q(_expiration_datetime__isnull=True) | Q(_expiration_datetime__gt=datetime.now(UTC())),
|
||||
course_id=enrollment.course_id,
|
||||
mode_slug=CourseMode.VERIFIED
|
||||
).exists()
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('verify_student', '0002_auto_20151124_1024'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='historicalverificationdeadline',
|
||||
name='deadline_is_explicit',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='verificationdeadline',
|
||||
name='deadline_is_explicit',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -958,7 +958,7 @@ class VerificationDeadline(TimeStampedModel):
|
||||
# The system prefers to set this automatically based on default settings. But
|
||||
# if the field is set manually we want a way to indicate that so we don't
|
||||
# overwrite the manual setting of the field.
|
||||
deadline_is_explicit = models.BooleanField(default=True)
|
||||
deadline_is_explicit = models.BooleanField(default=False)
|
||||
|
||||
# Maintain a history of changes to deadlines for auditing purposes
|
||||
history = HistoricalRecords()
|
||||
@@ -966,7 +966,7 @@ class VerificationDeadline(TimeStampedModel):
|
||||
ALL_DEADLINES_CACHE_KEY = "verify_student.all_verification_deadlines"
|
||||
|
||||
@classmethod
|
||||
def set_deadline(cls, course_key, deadline):
|
||||
def set_deadline(cls, course_key, deadline, is_explicit=False):
|
||||
"""
|
||||
Configure the verification deadline for a course.
|
||||
|
||||
@@ -984,11 +984,12 @@ class VerificationDeadline(TimeStampedModel):
|
||||
else:
|
||||
record, created = VerificationDeadline.objects.get_or_create(
|
||||
course_key=course_key,
|
||||
defaults={"deadline": deadline}
|
||||
defaults={"deadline": deadline, "deadline_is_explicit": is_explicit}
|
||||
)
|
||||
|
||||
if not created:
|
||||
record.deadline = deadline
|
||||
record.deadline_is_explicit = is_explicit
|
||||
record.save()
|
||||
|
||||
@classmethod
|
||||
|
||||
24
lms/djangoapps/verify_student/signals.py
Normal file
24
lms/djangoapps/verify_student/signals.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Signal handler for setting default course verification dates
|
||||
"""
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.dispatch.dispatcher import receiver
|
||||
from xmodule.modulestore.django import SignalHandler, modulestore
|
||||
|
||||
from .models import VerificationDeadline
|
||||
|
||||
|
||||
@receiver(SignalHandler.course_published)
|
||||
def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Catches the signal that a course has been published in Studio and
|
||||
sets the verification deadline date to a default.
|
||||
"""
|
||||
try:
|
||||
deadline = VerificationDeadline.objects.get(course_key=course_key)
|
||||
if deadline and not deadline.deadline_is_explicit:
|
||||
course = modulestore().get_course(course_key)
|
||||
if course and deadline.deadline != course.end:
|
||||
VerificationDeadline.set_deadline(course_key, course.end)
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
4
lms/djangoapps/verify_student/startup.py
Normal file
4
lms/djangoapps/verify_student/startup.py
Normal file
@@ -0,0 +1,4 @@
|
||||
"""
|
||||
Setup the signals on startup.
|
||||
"""
|
||||
import lms.djangoapps.verify_student.signals # pylint: disable=unused-import
|
||||
49
lms/djangoapps/verify_student/tests/test_signals.py
Normal file
49
lms/djangoapps/verify_student/tests/test_signals.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""
|
||||
Unit tests for the VerificationDeadline signals
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from pytz import UTC
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
from lms.djangoapps.verify_student.models import VerificationDeadline
|
||||
from lms.djangoapps.verify_student.signals import _listen_for_course_publish
|
||||
|
||||
|
||||
class VerificationDeadlineSignalTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the VerificationDeadline signal
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(VerificationDeadlineSignalTest, self).setUp()
|
||||
self.end = datetime.now(tz=UTC).replace(microsecond=0) + timedelta(days=7)
|
||||
self.course = CourseFactory.create(end=self.end)
|
||||
VerificationDeadline.objects.all().delete()
|
||||
|
||||
def test_no_deadline(self):
|
||||
""" Verify the signal does not raise error when no deadlines found. """
|
||||
_listen_for_course_publish('store', self.course.id)
|
||||
|
||||
self.assertIsNone(_listen_for_course_publish('store', self.course.id))
|
||||
|
||||
def test_deadline(self):
|
||||
""" Verify deadline is set to course end date by signal. """
|
||||
deadline = datetime.now(tz=UTC) - timedelta(days=7)
|
||||
VerificationDeadline.set_deadline(self.course.id, deadline)
|
||||
|
||||
_listen_for_course_publish('store', self.course.id)
|
||||
self.assertEqual(VerificationDeadline.deadline_for_course(self.course.id), self.course.end)
|
||||
|
||||
def test_deadline_explicit(self):
|
||||
""" Verify deadline is unchanged by signal when explicitly set. """
|
||||
deadline = datetime.now(tz=UTC) - timedelta(days=7)
|
||||
VerificationDeadline.set_deadline(self.course.id, deadline, is_explicit=True)
|
||||
|
||||
_listen_for_course_publish('store', self.course.id)
|
||||
|
||||
actual_deadline = VerificationDeadline.deadline_for_course(self.course.id)
|
||||
self.assertNotEqual(actual_deadline, self.course.end)
|
||||
self.assertEqual(actual_deadline, deadline)
|
||||
Reference in New Issue
Block a user