diff --git a/lms/djangoapps/certificates/docs/decisions/001-allowlist-cert-requirements.rst b/lms/djangoapps/certificates/docs/decisions/001-allowlist-cert-requirements.rst index 38961278cd..59cb951406 100644 --- a/lms/djangoapps/certificates/docs/decisions/001-allowlist-cert-requirements.rst +++ b/lms/djangoapps/certificates/docs/decisions/001-allowlist-cert-requirements.rst @@ -31,7 +31,6 @@ the time the certificate is generated: * The user must have an approved, unexpired, ID verification * The user must not have an invalidated certificate for the course run (see the *CertificateInvalidation* model) -* Automatic certificate generation must be globally enabled * HTML (web) certificates must be globally enabled, and also enabled for the course run * The user must be on the allowlist for the course run (see the *CertificateWhitelist* model) diff --git a/lms/djangoapps/certificates/docs/decisions/002-cert-requirements.rst b/lms/djangoapps/certificates/docs/decisions/002-cert-requirements.rst index bf9e32695b..c828f5825c 100644 --- a/lms/djangoapps/certificates/docs/decisions/002-cert-requirements.rst +++ b/lms/djangoapps/certificates/docs/decisions/002-cert-requirements.rst @@ -26,7 +26,6 @@ be true at the time the certificate is generated: * The user must have an approved, unexpired, ID verification * The user must not have an invalidated certificate for the course run (see the *CertificateInvalidation* model) -* Automatic certificate generation must be globally enabled * HTML (web) certificates must be globally enabled, and also enabled for the course run * The user must have passed the course run * The user must not be a beta tester in the course run diff --git a/lms/djangoapps/certificates/generation_handler.py b/lms/djangoapps/certificates/generation_handler.py index 1c7042478b..6710e92b4a 100644 --- a/lms/djangoapps/certificates/generation_handler.py +++ b/lms/djangoapps/certificates/generation_handler.py @@ -24,7 +24,6 @@ from lms.djangoapps.certificates.utils import emit_certificate_event, has_html_c from lms.djangoapps.grades.api import CourseGradeFactory from lms.djangoapps.instructor.access import list_with_level from lms.djangoapps.verify_student.services import IDVerificationService -from openedx.core.djangoapps.certificates.api import auto_certificate_generation_enabled from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag from xmodule.modulestore.django import modulestore @@ -209,12 +208,6 @@ def _can_generate_certificate_common(user, course_key): This method contains checks that are common to both allowlist and V2 regular course certificates. """ - if not auto_certificate_generation_enabled(): - # Automatic certificate generation is globally disabled - log.info(f'Automatic certificate generation is globally disabled. Certificate cannot be generated for ' - f'{user.id} : {course_key}.') - return False - if CertificateInvalidation.has_certificate_invalidation(user, course_key): # The invalidation list prevents certificate generation log.info(f'{user.id} : {course_key} is on the certificate invalidation list. Certificate cannot be generated.') diff --git a/lms/djangoapps/certificates/management/commands/tests/test_cert_generation.py b/lms/djangoapps/certificates/management/commands/tests/test_cert_generation.py index 9e09cbd585..ed79bce2af 100644 --- a/lms/djangoapps/certificates/management/commands/tests/test_cert_generation.py +++ b/lms/djangoapps/certificates/management/commands/tests/test_cert_generation.py @@ -9,12 +9,11 @@ from django.core.management import CommandError, call_command from waffle.testutils import override_switch from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory -from lms.djangoapps.certificates.tests.test_generation_handler import AUTO_GENERATION_SWITCH_NAME, ID_VERIFIED_METHOD +from lms.djangoapps.certificates.tests.test_generation_handler import ID_VERIFIED_METHOD from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory -@override_switch(AUTO_GENERATION_SWITCH_NAME, active=True) @mock.patch(ID_VERIFIED_METHOD, mock.Mock(return_value=True)) class CertGenerationTests(ModuleStoreTestCase): """ diff --git a/lms/djangoapps/certificates/signals.py b/lms/djangoapps/certificates/signals.py index fb1e93e8aa..19cfabcbc9 100644 --- a/lms/djangoapps/certificates/signals.py +++ b/lms/djangoapps/certificates/signals.py @@ -57,14 +57,14 @@ def _listen_for_certificate_whitelist_append(sender, instance, **kwargs): # pyl """ Listen for a user being added to or modified on the whitelist (allowlist) """ + if not auto_certificate_generation_enabled(): + return + if is_using_certificate_allowlist_and_is_on_allowlist(instance.user, instance.course_id): log.info(f'{instance.course_id} is using allowlist certificates, and the user {instance.user.id} is now on ' f'its allowlist. Attempt will be made to generate an allowlist certificate.') return generate_allowlist_certificate_task(instance.user, instance.course_id) - if not auto_certificate_generation_enabled(): - return - if _fire_ungenerated_certificate_task(instance.user, instance.course_id): log.info('Certificate generation task initiated for {user} : {course} via whitelist'.format( user=instance.user.id, @@ -78,14 +78,14 @@ def listen_for_passing_grade(sender, user, course_id, **kwargs): # pylint: disa Listen for a learner passing a course, send cert generation task, downstream signal from COURSE_GRADE_CHANGED """ + if not auto_certificate_generation_enabled(): + return + if can_generate_certificate_task(user, course_id): log.info(f'{course_id} is using V2 certificates. Attempt will be made to generate a V2 certificate for ' f'{user.id} as a passing grade was received.') return generate_certificate_task(user, course_id) - if not auto_certificate_generation_enabled(): - return - if _fire_ungenerated_certificate_task(user, course_id): log.info('Certificate generation task initiated for {user} : {course} via passing grade'.format( user=user.id, diff --git a/lms/djangoapps/certificates/tests/test_generation_handler.py b/lms/djangoapps/certificates/tests/test_generation_handler.py index 4868f056fc..818e060396 100644 --- a/lms/djangoapps/certificates/tests/test_generation_handler.py +++ b/lms/djangoapps/certificates/tests/test_generation_handler.py @@ -5,9 +5,7 @@ import logging from unittest import mock import ddt -from edx_toggles.toggles import LegacyWaffleSwitch -from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch -from waffle.testutils import override_switch +from edx_toggles.toggles.testutils import override_waffle_flag from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory from lms.djangoapps.certificates.generation_handler import ( @@ -30,7 +28,6 @@ from lms.djangoapps.certificates.tests.factories import ( CertificateWhitelistFactory, GeneratedCertificateFactory ) -from openedx.core.djangoapps.certificates.config import waffle from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -41,13 +38,8 @@ CCX_COURSE_METHOD = 'lms.djangoapps.certificates.generation_handler._is_ccx_cour ID_VERIFIED_METHOD = 'lms.djangoapps.verify_student.services.IDVerificationService.user_is_verified' PASSING_GRADE_METHOD = 'lms.djangoapps.certificates.generation_handler._has_passing_grade' WEB_CERTS_METHOD = 'lms.djangoapps.certificates.generation_handler.has_html_certificates_enabled' -AUTO_GENERATION_NAMESPACE = waffle.WAFFLE_NAMESPACE -AUTO_GENERATION_NAME = waffle.AUTO_CERTIFICATE_GENERATION -AUTO_GENERATION_SWITCH_NAME = f'{AUTO_GENERATION_NAMESPACE}.{AUTO_GENERATION_NAME}' -AUTO_GENERATION_SWITCH = LegacyWaffleSwitch(AUTO_GENERATION_NAMESPACE, AUTO_GENERATION_NAME) -@override_switch(AUTO_GENERATION_SWITCH_NAME, active=True) @override_waffle_flag(CERTIFICATES_USE_ALLOWLIST, active=True) @mock.patch(ID_VERIFIED_METHOD, mock.Mock(return_value=True)) @mock.patch(WEB_CERTS_METHOD, mock.Mock(return_value=True)) @@ -176,13 +168,6 @@ class AllowlistTests(ModuleStoreTestCase): assert can_generate_certificate_task(self.user, self.course_run_key) assert generate_certificate_task(self.user, self.course_run_key) - def test_can_generate_auto_disabled(self): - """ - Test handling when automatic generation is disabled - """ - with override_waffle_switch(AUTO_GENERATION_SWITCH, active=False): - assert not _can_generate_allowlist_certificate(self.user, self.course_run_key) - def test_can_generate_not_verified(self): """ Test handling when the user's id is not verified @@ -268,7 +253,6 @@ class AllowlistTests(ModuleStoreTestCase): assert not _can_generate_allowlist_certificate(self.user, self.course_run_key) -@override_switch(AUTO_GENERATION_SWITCH_NAME, active=True) @override_waffle_flag(CERTIFICATES_USE_UPDATED, active=True) @mock.patch(ID_VERIFIED_METHOD, mock.Mock(return_value=True)) @mock.patch(CCX_COURSE_METHOD, mock.Mock(return_value=False)) @@ -372,13 +356,6 @@ class CertificateTests(ModuleStoreTestCase): """ assert _can_generate_certificate_for_status(None, None) - def test_can_generate_auto_disabled(self): - """ - Test handling when automatic generation is disabled - """ - with override_waffle_switch(AUTO_GENERATION_SWITCH, active=False): - assert not _can_generate_v2_certificate(self.user, self.course_run_key) - def test_can_generate_not_verified(self): """ Test handling when the user's id is not verified diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py index 2fd8fbdfd2..64939cbb35 100644 --- a/lms/djangoapps/grades/tests/test_course_grade_factory.py +++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py @@ -98,7 +98,7 @@ class TestCourseGradeFactory(GradeTestBase): with self.assertNumQueries(3), mock_get_score(1, 2): _assert_read(expected_pass=False, expected_percent=0) # start off with grade of 0 - num_queries = 46 + num_queries = 42 with self.assertNumQueries(num_queries), mock_get_score(1, 2): grade_factory.update(self.request.user, self.course, force_update_subsections=True) @@ -119,7 +119,7 @@ class TestCourseGradeFactory(GradeTestBase): with self.assertNumQueries(3): _assert_read(expected_pass=True, expected_percent=1.0) # updated to grade of 1.0 - num_queries = 28 + num_queries = 30 with self.assertNumQueries(num_queries), mock_get_score(0, 0): # the subsection now is worth zero grade_factory.update(self.request.user, self.course, force_update_subsections=True) diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index c437071c17..4d5b37c91e 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -2021,7 +2021,7 @@ class TestCertificateGeneration(InstructorTaskModuleTestCase): 'failed': 0, 'skipped': 2 } - with self.assertNumQueries(169): + with self.assertNumQueries(170): self.assertCertificatesGenerated(task_input, expected_results) expected_results = {