diff --git a/openedx/features/course_duration_limits/access.py b/openedx/features/course_duration_limits/access.py index 6dfd476157..8f69656b5a 100644 --- a/openedx/features/course_duration_limits/access.py +++ b/openedx/features/course_duration_limits/access.py @@ -118,6 +118,11 @@ def get_user_course_expiration_date(user, course): if (content_availability_date.date() == course.start.date() and course.start < enrollment.created < timezone.now()): content_availability_date = enrollment.created + # If course teams change the course start date, set the content_availability_date + # to max of enrollment or course start date + elif (content_availability_date.date() < course.start.date() and + content_availability_date.date() < enrollment.created.date()): + content_availability_date = max(enrollment.created, course.start) except CourseEnrollment.schedule.RelatedObjectDoesNotExist: content_availability_date = max(enrollment.created, course.start) diff --git a/openedx/features/course_duration_limits/tests/test_access.py b/openedx/features/course_duration_limits/tests/test_access.py index 167962d85c..3aff5f7629 100644 --- a/openedx/features/course_duration_limits/tests/test_access.py +++ b/openedx/features/course_duration_limits/tests/test_access.py @@ -5,21 +5,22 @@ import itertools from datetime import datetime, timedelta import ddt -from django.utils import timezone -from pytz import UTC - from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory +from django.utils import timezone +from pytz import UTC +from student.tests.factories import CourseEnrollmentFactory +from util.date_utils import strftime_localized + from lms.djangoapps.courseware.models import DynamicUpgradeDeadlineConfiguration 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 ( generate_course_expired_message, + get_user_course_duration, get_user_course_expiration_date ) from openedx.features.course_duration_limits.models import CourseDurationLimitConfig -from student.tests.factories import CourseEnrollmentFactory -from util.date_utils import strftime_localized @ddt.ddt @@ -89,3 +90,34 @@ class TestAccess(CacheIsolationTestCase): self.assertIn(format_date(course_upgrade_deadline), message) else: self.assertNotIn("Upgrade by", message) + + def test_schedule_start_date_in_past(self): + """ + Test that when schedule start date is before course start or + enrollment date, content_availability_date is set to max of course start + or enrollment date + """ + 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, + ) + CourseModeFactory.create( + course_id=enrollment.course.id, + mode_slug=CourseMode.AUDIT, + ) + ScheduleFactory.create( + enrollment=enrollment, + start_date=datetime(2017, 1, 1, tzinfo=UTC), + ) + + content_availability_date = max(enrollment.created, enrollment.course.start) + access_duration = get_user_course_duration(enrollment.user, enrollment.course) + expected_course_expiration_date = content_availability_date + access_duration + + duration_limit_upgrade_deadline = get_user_course_expiration_date(enrollment.user, enrollment.course) + self.assertIsNotNone(duration_limit_upgrade_deadline) + self.assertEqual(duration_limit_upgrade_deadline, expected_course_expiration_date)