diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index c49ff9c03e..9407f83fd9 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -820,6 +820,22 @@ class TestSupplementProgramData(ProgramsApiConfigMixin, ModuleStoreTestCase): enrollment_open_date=enrollment_open_date, ) + def test_no_enrollment_start_date(self): + """Verify that a closed course with no explicit enrollment start date doesn't cause an error. + + Regression test for ECOM-4973. + """ + self.course.enrollment_end = timezone.now() - datetime.timedelta(days=1) + self.course = self.update_course(self.course, self.user.id) # pylint: disable=no-member + + data = utils.supplement_program_data(self.program, self.user) + + self._assert_supplemented( + data, + is_enrollment_open=False, + enrollment_open_date=strftime_localized(utils.DEFAULT_ENROLLMENT_START_DATE, 'SHORT_DATE'), + ) + @ddt.data(True, False) @mock.patch(UTILS_MODULE + '.certificate_api.certificate_downloadable_status') @mock.patch(CERTIFICATES_API_MODULE + '.has_html_certificates_enabled') diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py index 3f9b8d9a7a..48b51dfdcb 100644 --- a/openedx/core/djangoapps/programs/utils.py +++ b/openedx/core/djangoapps/programs/utils.py @@ -25,6 +25,9 @@ from xmodule.course_metadata_utils import DEFAULT_START_DATE log = logging.getLogger(__name__) +# The datetime module's strftime() methods require a year >= 1900. +DEFAULT_ENROLLMENT_START_DATE = datetime.datetime(1900, 1, 1, tzinfo=pytz.UTC) + def get_programs(user, program_id=None): """Given a user, get programs from the Programs service. @@ -356,7 +359,7 @@ def supplement_program_data(program_data, user): is_enrolled = CourseEnrollment.is_enrolled(user, course_key) - enrollment_start = course_overview.enrollment_start or datetime.datetime.min.replace(tzinfo=pytz.UTC) + enrollment_start = course_overview.enrollment_start or DEFAULT_ENROLLMENT_START_DATE enrollment_end = course_overview.enrollment_end or datetime.datetime.max.replace(tzinfo=pytz.UTC) is_enrollment_open = enrollment_start <= timezone.now() < enrollment_end