feat: update date selection logic when rendering course certs (#36447)

Fixes: https://github.com/openedx/platform-roadmap/issues/423

This PR updates the logic for determining the issued date shown on course certificates. For courses with a display behavior set to 'end date of the course', certificates earned by learners will now show the course run’s end date as the issued date.
This commit is contained in:
Justin Hynes
2025-03-27 08:41:38 -04:00
committed by GitHub
parent 215cfb5731
commit f99b89c8c5
2 changed files with 49 additions and 3 deletions

View File

@@ -858,7 +858,14 @@ def available_date_for_certificate(course, certificate) -> datetime:
def display_date_for_certificate(course, certificate):
"""
Returns the display date that a certificate should display.
Returns the date that should be displayed on a certificate when rendered.
If the certificate has a certificate date override associated with it, display the override date.
Otherwise, if the course has a display behavior of "END_WITH_DATE", display the associated certificate available
date. If the course has a display behavior of "END", we should display the end date of the course. Lastly, when the
display behavior is "EARLY_NO_INFO" or when the course run is self-paced, we display the modified date of the
certificate instance.
Arguments:
course (CourseOverview or course block): The course we're getting the date for
@@ -873,8 +880,10 @@ def display_date_for_certificate(course, certificate):
if _course_uses_available_date(course) and course.certificate_available_date < datetime.now(UTC):
return course.certificate_available_date
return certificate.modified_date
elif course.certificates_display_behavior == CertificatesDisplayBehaviors.END and course.end:
return course.end
else:
return certificate.modified_date
def is_valid_pdf_certificate(cert_data):

View File

@@ -1135,6 +1135,43 @@ class CertificatesApiTestCase(TestCase):
assert date == display_date_for_certificate(self.course, self.certificate)
assert maybe_avail == available_date_for_certificate(self.course, self.certificate)
def test_display_date_for_certificate_cdb_early_no_info(self):
"""
Test to verify that the "earned date" displayed on a course certificate is the last modified date of a
certificate instance when the display behavior is set to EARLY_NO_INFO.
"""
with configure_waffle_namespace(True):
self.course.certificates_display_behavior = CertificatesDisplayBehaviors.EARLY_NO_INFO
assert display_date_for_certificate(self.course, self.certificate) == self.certificate.modified_date
def test_display_date_for_certificate_cdb_end_with_date(self):
"""
Test to verify that the "earned date" displayed on a course certificate is the certificate available date
associated with the course when the display behavior is set to END_WITH_DATE.
"""
with configure_waffle_namespace(True):
self.course.certificates_display_behavior = CertificatesDisplayBehaviors.END_WITH_DATE
self.course.certificate_available_date = datetime(2017, 2, 1, tzinfo=pytz.UTC)
assert display_date_for_certificate(self.course, self.certificate) == self.course.certificate_available_date
def test_display_date_for_certificate_cdb_end(self):
"""
Test to verify that the "earned date" displayed on a course certificate is the end date of the course run
when the display behavior is set to END.
"""
with configure_waffle_namespace(True):
self.course.certificates_display_behavior = CertificatesDisplayBehaviors.END
assert display_date_for_certificate(self.course, self.certificate) == self.course.end
def test_display_date_for_certificate_date_override(self):
"""
Test to verify that the "earned date" displayed on a course certificate is the certificate override date
if-and-only-if date override associated with the certificate instance.
"""
with configure_waffle_namespace(True):
self.certificate.date_override = datetime(2016, 1, 1, tzinfo=pytz.UTC)
assert display_date_for_certificate(self.course, self.certificate) == self.certificate.date_override.date
@ddt.ddt
class CertificatesMessagingTestCase(ModuleStoreTestCase):