feat: reimagine certificate display settings

The course settings `certificate_available_date` (CAD) and
`certificates_display_behavior` (CDB) were previously acting indedependantly
of one another. They now work in tandem. This change:
- limits CDB to a dropdown
- removes "early_with_info" and adds "end_with_date"
- only takes CAD into account if "end_with_date" is selected
- Moves CDB to the main course schedule settings page
- updates CourseOverview to validate these fields and choose sane
defaults if they aren't expected values

Certificates will now show under the following circumstances:
"Immediately upon passing"
certificate_availability_date = null
certificates_display_behavior = "early_no_info"

"End date of course"
certificate_availability_date = null
certificates_display_behavior = "end"

"A date after the course end date"
certificate_availability_date = <date>
certificates_display_behavior = "end_with_date"
This commit is contained in:
Matt Tuchfarber
2021-06-02 15:28:28 -04:00
parent 666dc22bd0
commit 2a7106acfb
34 changed files with 934 additions and 573 deletions

View File

@@ -30,6 +30,7 @@ from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFa
from openedx.core.djangoapps.programs import tasks
from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory, SiteFactory
from openedx.core.djangolib.testing.utils import skip_unless_lms
from xmodule.data import CertificatesDisplayBehaviors
log = logging.getLogger(__name__)
@@ -520,6 +521,7 @@ class AwardCourseCertificatesTestCase(CredentialsApiConfigMixin, TestCase):
self.course = CourseOverviewFactory.create(
self_paced=True, # Any option to allow the certificate to be viewable for the course
certificate_available_date=self.available_date,
certificates_display_behavior=CertificatesDisplayBehaviors.END_WITH_DATE
)
self.student = UserFactory.create(username='test-student')
# Instantiate the Certificate first so that the config doesn't execute issuance

View File

@@ -51,6 +51,7 @@ from openedx.core.djangoapps.site_configuration.tests.factories import SiteFacto
from openedx.core.djangolib.testing.utils import skip_unless_lms
from common.djangoapps.student.tests.factories import AnonymousUserFactory, CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.date_utils import strftime_localized
from xmodule.data import CertificatesDisplayBehaviors
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import (
ModuleStoreTestCase, SharedModuleStoreTestCase, TEST_DATA_SPLIT_MODULESTORE
@@ -499,7 +500,7 @@ class TestProgramProgressMeter(ModuleStoreTestCase):
end=two_days_ago,
self_paced=False,
certificate_available_date=tomorrow,
certificates_display_behavior='end'
certificates_display_behavior=CertificatesDisplayBehaviors.END_WITH_DATE
)
third_course_run_key = str(course3.id)
@@ -607,6 +608,7 @@ class TestProgramProgressMeter(ModuleStoreTestCase):
# 3 certs, all available, program cert in the past/now
course3_overview = CourseOverview.get_from_id(course3.id)
course3_overview.certificate_available_date = yesterday
course3_overview.certificates_display_behavior = CertificatesDisplayBehaviors.END_WITH_DATE
course3_overview.save()
meter = ProgramProgressMeter(self.site, self.user)
self._assert_progress(
@@ -622,7 +624,7 @@ class TestProgramProgressMeter(ModuleStoreTestCase):
def test_old_course_runs(self, mock_get_programs):
"""
Test that old course runs may exist for a program which do not exist in LMS.
In that case, continue considering the course run to've been failed by the learner
In that case, continue considering the course run to have been failed by the learner
"""
course_run = CourseRunFactory.create()
course = CourseFactory.create(course_runs=[course_run])