Merge pull request #19547 from cpennington/add-test-for-fbe-banner
Add a test of the FBE Upgrade banner
This commit is contained in:
@@ -1730,7 +1730,7 @@ class CourseEnrollment(models.Model):
|
||||
if self.dynamic_upgrade_deadline is not None:
|
||||
# When course modes expire they aren't found any more and None would be returned.
|
||||
# Replicate that behavior here by returning None if the personalized deadline is in the past.
|
||||
if datetime.now(UTC) >= self.dynamic_upgrade_deadline:
|
||||
if self.dynamic_upgrade_deadline <= datetime.now(UTC):
|
||||
log.debug('Schedules: Returning None since dynamic upgrade deadline has already passed.')
|
||||
return None
|
||||
|
||||
@@ -1777,15 +1777,13 @@ class CourseEnrollment(models.Model):
|
||||
'Schedules: Pulling upgrade deadline for CourseEnrollment %d from Schedule %d.',
|
||||
self.id, self.schedule.id
|
||||
)
|
||||
upgrade_deadline = self.schedule.upgrade_deadline
|
||||
return self.schedule.upgrade_deadline
|
||||
except ObjectDoesNotExist:
|
||||
# NOTE: Schedule has a one-to-one mapping with CourseEnrollment. If no schedule is associated
|
||||
# with this enrollment, Django will raise an exception rather than return None.
|
||||
log.debug('Schedules: No schedule exists for CourseEnrollment %d.', self.id)
|
||||
return None
|
||||
|
||||
return upgrade_deadline
|
||||
|
||||
@cached_property
|
||||
def course_upgrade_deadline(self):
|
||||
"""
|
||||
|
||||
@@ -355,7 +355,7 @@ def _create_mock_json_request(user, data, method='POST'):
|
||||
return request
|
||||
|
||||
|
||||
def get_expiration_banner_text(user, course):
|
||||
def get_expiration_banner_text(user, course, language='en-us'):
|
||||
"""
|
||||
Get text for banner that messages user course expiration date
|
||||
for different tests that depend on it.
|
||||
@@ -367,7 +367,6 @@ def get_expiration_banner_text(user, course):
|
||||
if upgrade_deadline is None or now() < upgrade_deadline:
|
||||
upgrade_deadline = enrollment.course_upgrade_deadline
|
||||
|
||||
language = get_language()
|
||||
language_is_es = language and language.split('-')[0].lower() == 'es'
|
||||
if language_is_es:
|
||||
formatted_expiration_date = strftime_localized(expiration_date, '%-d de %b. de %Y').lower()
|
||||
|
||||
@@ -70,7 +70,7 @@ def get_user_course_expiration_date(user, course):
|
||||
return None
|
||||
|
||||
enrollment = CourseEnrollment.get_enrollment(user, course.id)
|
||||
if enrollment is None or enrollment.mode != 'audit':
|
||||
if enrollment is None or enrollment.mode != CourseMode.AUDIT:
|
||||
return None
|
||||
|
||||
try:
|
||||
@@ -140,7 +140,7 @@ def register_course_expired_message(request, course):
|
||||
upgrade_deadline = enrollment.upgrade_deadline
|
||||
now = timezone.now()
|
||||
course_upgrade_deadline = enrollment.course_upgrade_deadline
|
||||
if (not upgrade_deadline) or (now > upgrade_deadline):
|
||||
if (not upgrade_deadline) or (upgrade_deadline < now):
|
||||
upgrade_deadline = course_upgrade_deadline
|
||||
|
||||
expiration_message = _('{strong_open}Audit Access Expires {expiration_date}{strong_close}'
|
||||
|
||||
106
openedx/features/course_duration_limits/tests/test_access.py
Normal file
106
openedx/features/course_duration_limits/tests/test_access.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""Tests of openedx.features.course_duration_limits.access"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import itertools
|
||||
|
||||
from course_modes.models import CourseMode
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
from django.test import RequestFactory
|
||||
from django.utils import timezone
|
||||
from courseware.models import DynamicUpgradeDeadlineConfiguration
|
||||
from mock import patch
|
||||
from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
|
||||
from openedx.features.course_duration_limits.access import (
|
||||
register_course_expired_message,
|
||||
get_user_course_expiration_date,
|
||||
)
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from pytz import UTC
|
||||
from student.tests.factories import CourseEnrollmentFactory
|
||||
from util.date_utils import strftime_localized
|
||||
import ddt
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestAccess(CacheIsolationTestCase):
|
||||
"""Tests of openedx.features.course_duration_limits.access"""
|
||||
def setUp(self):
|
||||
super(TestAccess, self).setUp()
|
||||
|
||||
CourseDurationLimitConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=UTC))
|
||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||
|
||||
@patch('openedx.features.course_duration_limits.access.PageLevelMessages')
|
||||
@ddt.data(
|
||||
*itertools.product(
|
||||
['en-us', 'es-419'],
|
||||
itertools.product([None, -2, -1, 1, 2], repeat=2),
|
||||
)
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_register_course_expired_message(self, language, offsets, mock_messages):
|
||||
now = timezone.now()
|
||||
schedule_offset, course_offset = offsets
|
||||
|
||||
if schedule_offset is not None:
|
||||
schedule_upgrade_deadline = now + timedelta(days=schedule_offset)
|
||||
else:
|
||||
schedule_upgrade_deadline = None
|
||||
|
||||
if course_offset is not None:
|
||||
course_upgrade_deadline = now + timedelta(days=course_offset)
|
||||
else:
|
||||
course_upgrade_deadline = None
|
||||
|
||||
def format_date(date):
|
||||
if language.startswith('es-'):
|
||||
return strftime_localized(date, '%-d de %b. de %Y').lower()
|
||||
else:
|
||||
return strftime_localized(date, '%b. %-d, %Y')
|
||||
|
||||
patch_lang = patch('openedx.features.course_duration_limits.access.get_language', return_value=language)
|
||||
with patch_lang:
|
||||
enrollment = CourseEnrollmentFactory.create(
|
||||
course__start=datetime(2018, 1, 1, tzinfo=UTC),
|
||||
course__self_paced=True,
|
||||
)
|
||||
CourseModeFactory.create(
|
||||
course_id=enrollment.course.id,
|
||||
mode_slug=CourseMode.VERIFIED,
|
||||
expiration_datetime=course_upgrade_deadline,
|
||||
)
|
||||
CourseModeFactory.create(
|
||||
course_id=enrollment.course.id,
|
||||
mode_slug=CourseMode.AUDIT,
|
||||
)
|
||||
ScheduleFactory.create(
|
||||
enrollment=enrollment,
|
||||
upgrade_deadline=schedule_upgrade_deadline,
|
||||
)
|
||||
request = RequestFactory().get('/courseware')
|
||||
request.user = enrollment.user
|
||||
|
||||
duration_limit_upgrade_deadline = get_user_course_expiration_date(enrollment.user, enrollment.course)
|
||||
self.assertIsNotNone(duration_limit_upgrade_deadline)
|
||||
|
||||
register_course_expired_message(request, enrollment.course)
|
||||
self.assertEqual(
|
||||
mock_messages.register_info_message.call_count,
|
||||
1
|
||||
)
|
||||
|
||||
message = str(mock_messages.register_info_message.call_args[0][1])
|
||||
|
||||
self.assertIn(format_date(duration_limit_upgrade_deadline), message)
|
||||
|
||||
soft_upgradeable = schedule_upgrade_deadline is not None and now < schedule_upgrade_deadline
|
||||
upgradeable = course_upgrade_deadline is None or now < course_upgrade_deadline
|
||||
has_upgrade_deadline = course_upgrade_deadline is not None
|
||||
|
||||
if upgradeable and soft_upgradeable:
|
||||
self.assertIn(format_date(schedule_upgrade_deadline), message)
|
||||
elif upgradeable and has_upgrade_deadline:
|
||||
self.assertIn(format_date(course_upgrade_deadline), message)
|
||||
else:
|
||||
self.assertNotIn("Upgrade by", message)
|
||||
Reference in New Issue
Block a user