feat: return the certificate available date if it is configured (#36790)

This commit is contained in:
Diana Olarte
2025-07-11 01:16:26 +10:00
committed by GitHub
parent 33f239d8fc
commit 5657e751bb
3 changed files with 45 additions and 8 deletions

View File

@@ -299,6 +299,15 @@ def certificate_downloadable_status(student, course_key):
response_data["earned_but_not_available"] = True
response_data["certificate_available_date"] = course_overview.certificate_available_date
if (
not certificates_viewable_for_course(course_overview)
and not CertificateStatuses.is_passing_status(current_status["status"])
and display_behavior_is_valid
and course_overview.certificate_available_date
):
response_data["not_earned_but_available_date"] = True
response_data["certificate_available_date"] = course_overview.certificate_available_date
may_view_certificate = _should_certificate_be_visible(
course_overview.certificates_display_behavior,
course_overview.certificates_show_before_end,

View File

@@ -210,13 +210,14 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes
}
@ddt.data(
(True, timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, True, None),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.EARLY_NO_INFO, True, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.EARLY_NO_INFO, True, None),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.END, True, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.END, False, True),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, True, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, False, True),
(True, timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, True, None, None),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.EARLY_NO_INFO, True, None, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.EARLY_NO_INFO, True, None, None),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.END, True, None, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.END, False, True, None),
(False, -timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, True, None, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, False, True, None),
(False, timedelta(days=2), CertificatesDisplayBehaviors.END_WITH_DATE, False, None, True),
)
@ddt.unpack
@patch.dict(settings.FEATURES, {"CERTIFICATES_HTML_VIEW": True})
@@ -227,6 +228,7 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes
certificates_display_behavior,
cert_downloadable_status,
earned_but_not_available,
no_earned_but_available_date,
):
"""
Test 'downloadable status'
@@ -239,7 +241,14 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes
self._setup_course_certificate()
downloadable_status = certificate_downloadable_status(self.student, self.course.id)
if no_earned_but_available_date:
downloadable_status = certificate_downloadable_status(self.student_no_cert, self.course.id)
assert downloadable_status.get("not_earned_but_available_date") == no_earned_but_available_date
assert downloadable_status.get("certificate_available_date") is not None
else:
downloadable_status = certificate_downloadable_status(self.student, self.course.id)
assert downloadable_status["is_downloadable"] == cert_downloadable_status
assert downloadable_status.get("earned_but_not_available") == earned_but_not_available

View File

@@ -170,6 +170,8 @@ CertData = namedtuple(
)
EARNED_BUT_NOT_AVAILABLE_CERT_STATUS = 'earned_but_not_available'
NOT_EARNED_BUT_AVAILABLE_DATE_CERT_STATUS = 'not_earned_but_available_date'
AUDIT_PASSING_CERT_DATA = CertData(
CertificateStatuses.audit_passing,
_('Your enrollment: Audit track'),
@@ -235,6 +237,17 @@ def _earned_but_not_available_cert_data(cert_downloadable_status):
)
def _not_earned_but_available_date_cert_data(cert_downloadable_status):
return CertData(
NOT_EARNED_BUT_AVAILABLE_DATE_CERT_STATUS,
_('Your certificate will be available after the indicated date'),
_('After this course officially ends, you will receive an email notification with your certificate.'),
download_url=None,
cert_web_view_url=None,
certificate_available_date=cert_downloadable_status.get('certificate_available_date')
)
def _downloadable_cert_data(download_url=None, cert_web_view_url=None):
return CertData(
CertificateStatuses.downloadable,
@@ -1092,6 +1105,9 @@ def _certificate_message(student, course, enrollment_mode): # lint-amnesty, pyl
if cert_downloadable_status.get('earned_but_not_available'):
return _earned_but_not_available_cert_data(cert_downloadable_status)
if cert_downloadable_status.get('not_earned_but_available_date'):
return _not_earned_but_available_date_cert_data(cert_downloadable_status)
if cert_downloadable_status['is_generating']:
return GENERATING_CERT_DATA
@@ -1121,6 +1137,9 @@ def get_cert_data(student, course, enrollment_mode, course_grade=None):
if cert_data.cert_status == EARNED_BUT_NOT_AVAILABLE_CERT_STATUS:
return cert_data
if cert_data.cert_status == NOT_EARNED_BUT_AVAILABLE_DATE_CERT_STATUS:
return cert_data
certificates_enabled_for_course = certs_api.has_self_generated_certificates_enabled(course.id)
if course_grade is None:
course_grade = CourseGradeFactory().read(student, course)