From ec36d3a9493314dcf073a310fa0e83df77ad42c4 Mon Sep 17 00:00:00 2001 From: Zaman Afzal Date: Thu, 16 Jun 2022 01:59:40 +0500 Subject: [PATCH] fix: revert Add Learner pathway progress update signal (#30598) --- .../certificates/tests/test_signals.py | 87 ------------------- ...rs_for_old_enterprise_course_enrollmnet.py | 33 +++---- .../tests/test_submitting_problems.py | 23 +---- lms/djangoapps/grades/course_grade_factory.py | 11 --- lms/djangoapps/grades/models.py | 11 +-- lms/djangoapps/grades/signals/signals.py | 1 - .../grades/tests/test_course_grade_factory.py | 26 ++---- lms/djangoapps/grades/tests/test_models.py | 20 +---- lms/djangoapps/grades/tests/test_signals.py | 4 - .../instructor/tests/test_spoc_gradebook.py | 16 ---- .../tests/test_tasks_helper.py | 62 +++++++------ .../api/v0/tests/test_views.py | 12 +-- lms/djangoapps/support/tests/test_views.py | 12 +-- .../accounts/tests/test_retirement_views.py | 14 --- .../enterprise_support/tests/test_api.py | 12 +-- .../enterprise_support/tests/test_context.py | 24 ++--- .../tests/test_serializers.py | 24 +---- .../enterprise_support/tests/test_signals.py | 17 +--- requirements/constraints.txt | 6 +- requirements/edx/base.in | 2 +- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/testing.txt | 2 +- 23 files changed, 87 insertions(+), 336 deletions(-) diff --git a/lms/djangoapps/certificates/tests/test_signals.py b/lms/djangoapps/certificates/tests/test_signals.py index 4a85f895d8..6b6ef54c02 100644 --- a/lms/djangoapps/certificates/tests/test_signals.py +++ b/lms/djangoapps/certificates/tests/test_signals.py @@ -56,24 +56,9 @@ class AllowlistGeneratedCertificatesTest(ModuleStoreTestCase): """ Tests for allowlisted student auto-certificate generation """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def setUp(self): super().setUp() self.user = UserFactory.create() - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) # Instructor paced course self.ip_course = CourseFactory.create(self_paced=False) CourseEnrollmentFactory( @@ -118,30 +103,11 @@ class PassingGradeCertsTest(ModuleStoreTestCase): """ Tests for certificate generation task firing on passing grade receipt """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def setUp(self): super().setUp() self.course = CourseFactory.create( self_paced=True, ) - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) - self.signal_mock_course_passed_pathway_progress = self.setup_patch( - 'learner_pathway_progress.signals.update_learner_pathway_progress', - None, - ) self.course_key = self.course.id self.user = UserFactory.create() self.enrollment = CourseEnrollmentFactory( @@ -253,27 +219,12 @@ class FailingGradeCertsTest(ModuleStoreTestCase): and that the signal has no effect on the cert status if the cert has a non-passing status """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def setUp(self): super().setUp() self.course = CourseFactory.create( self_paced=True, ) self.user = UserFactory.create() - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) self.enrollment = CourseEnrollmentFactory( user=self.user, course_id=self.course.id, @@ -349,29 +300,10 @@ class LearnerIdVerificationTest(ModuleStoreTestCase): """ Tests for certificate generation task firing on learner id verification """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def setUp(self): super().setUp() self.course_one = CourseFactory.create(self_paced=True) self.user_one = UserFactory.create() - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) - self.signal_mock_course_passed_pathway_progress = self.setup_patch( - 'learner_pathway_progress.signals.update_learner_pathway_progress', - None, - ) self.enrollment_one = CourseEnrollmentFactory( user=self.user_one, course_id=self.course_one.id, @@ -450,31 +382,12 @@ class EnrollmentModeChangeCertsTest(ModuleStoreTestCase): """ Tests for certificate generation task firing when the user's enrollment mode changes """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def setUp(self): super().setUp() self.user = UserFactory.create() self.verified_course = CourseFactory.create( self_paced=True, ) - self.mock_update_pathway_progress = self.setup_patch( - 'learner_pathway_progress.signals.update_learner_pathway_progress', - None, - ) - self.signal_mock_course_passed_pathway_progress = self.setup_patch( - 'learner_pathway_progress.signals.listen_for_course_grade_upgrade_in_learner_pathway', - None, - ) self.verified_course_key = self.verified_course.id # pylint: disable=no-member self.verified_enrollment = CourseEnrollmentFactory( user=self.user, diff --git a/lms/djangoapps/commerce/management/commands/tests/test_create_orders_for_old_enterprise_course_enrollmnet.py b/lms/djangoapps/commerce/management/commands/tests/test_create_orders_for_old_enterprise_course_enrollmnet.py index 7af3cdcf69..8b2472f214 100644 --- a/lms/djangoapps/commerce/management/commands/tests/test_create_orders_for_old_enterprise_course_enrollmnet.py +++ b/lms/djangoapps/commerce/management/commands/tests/test_create_orders_for_old_enterprise_course_enrollmnet.py @@ -37,31 +37,24 @@ class TestEnterpriseCourseEnrollmentCreateOldOrder(TestCase): """ Creates `count` test enrollments plus 1 invalid and 1 Audit enrollment """ - with patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - return_value=None - ): - for _ in range(count): - user = UserFactory() - course_enrollment = CourseEnrollmentFactory(mode=CourseMode.VERIFIED, user=user) - course = course_enrollment.course - enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=user.id) - EnterpriseCourseEnrollmentFactory( - enterprise_customer_user=enterprise_customer_user, - course_id=course.id - ) - - # creating audit enrollment + for _ in range(count): user = UserFactory() - course_enrollment = CourseEnrollmentFactory(mode=CourseMode.AUDIT, user=user) + course_enrollment = CourseEnrollmentFactory(mode=CourseMode.VERIFIED, user=user) course = course_enrollment.course enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=user.id) EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) - # creating invalid enrollment (with no CourseEnrollment) - user = UserFactory() - enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=user.id) - EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) + # creating audit enrollment + user = UserFactory() + course_enrollment = CourseEnrollmentFactory(mode=CourseMode.AUDIT, user=user) + course = course_enrollment.course + enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=user.id) + EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) + + # creating invalid enrollment (with no CourseEnrollment) + user = UserFactory() + enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=user.id) + EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) @patch('lms.djangoapps.commerce.management.commands.create_orders_for_old_enterprise_course_enrollment' '.Command._create_manual_enrollment_orders') diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 3ab728bb8e..fa9f381160 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -9,7 +9,7 @@ import json import os from datetime import datetime from textwrap import dedent -from unittest.mock import patch, MagicMock +from unittest.mock import patch import ddt import pytz @@ -345,27 +345,6 @@ class TestCourseGrader(TestSubmittingProblems): """ Suite of tests for the course grader. """ - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = MagicMock(return_value=return_value) - new_patch = patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - - def setUp(self): - super().setUp() - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) - self.signal_mock_course_passed_pathway_progress = self.setup_patch( - 'learner_pathway_progress.signals.update_learner_pathway_progress', - None, - ) - # Tell Django to clean out all databases, not just default databases = set(connections) diff --git a/lms/djangoapps/grades/course_grade_factory.py b/lms/djangoapps/grades/course_grade_factory.py index a68331860b..4b310e4de0 100644 --- a/lms/djangoapps/grades/course_grade_factory.py +++ b/lms/djangoapps/grades/course_grade_factory.py @@ -9,11 +9,6 @@ from openedx.core.djangoapps.signals.signals import ( COURSE_GRADE_NOW_FAILED, COURSE_GRADE_NOW_PASSED ) - -from lms.djangoapps.grades.signals.signals import ( - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY, -) - from .config import assume_zero_if_absent, should_persist_grades from .course_data import CourseData from .course_grade import CourseGrade, ZeroCourseGrade @@ -175,7 +170,6 @@ class CourseGradeFactory: COURSE_GRADE_CHANGED signal to listeners and COURSE_GRADE_NOW_PASSED if learner has passed course or COURSE_GRADE_NOW_FAILED if learner is now failing course - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY if learner has passed course """ should_persist = should_persist_grades(course_data.course_key) if should_persist and force_update_subsections: @@ -216,11 +210,6 @@ class CourseGradeFactory: user=user, course_id=course_data.course_key, ) - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send( - sender=CourseGradeFactory, - user_id=user.id, - course_id=course_data.course_key, - ) else: COURSE_GRADE_NOW_FAILED.send( sender=CourseGradeFactory, diff --git a/lms/djangoapps/grades/models.py b/lms/djangoapps/grades/models.py index 76b2e37cb0..0d87873f20 100644 --- a/lms/djangoapps/grades/models.py +++ b/lms/djangoapps/grades/models.py @@ -27,11 +27,7 @@ from simple_history.models import HistoricalRecords from lms.djangoapps.courseware.fields import UnsignedBigIntAutoField from lms.djangoapps.grades import events # lint-amnesty, pylint: disable=unused-import from openedx.core.lib.cache_utils import get_cache -from lms.djangoapps.grades.signals.signals import ( - COURSE_GRADE_PASSED_FIRST_TIME, - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY -) - +from lms.djangoapps.grades.signals.signals import COURSE_GRADE_PASSED_FIRST_TIME log = logging.getLogger(__name__) @@ -654,11 +650,6 @@ class PersistentCourseGrade(TimeStampedModel): course_id=course_id, user_id=user_id ) - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send( - sender=None, - user_id=user_id, - course_id=course_id, - ) grade.passed_timestamp = now() grade.save() diff --git a/lms/djangoapps/grades/signals/signals.py b/lms/djangoapps/grades/signals/signals.py index 73a31f937c..0edd48b4d5 100644 --- a/lms/djangoapps/grades/signals/signals.py +++ b/lms/djangoapps/grades/signals/signals.py @@ -111,4 +111,3 @@ SUBSECTION_OVERRIDE_CHANGED = Signal() # 'user_id', # User object id # ] COURSE_GRADE_PASSED_FIRST_TIME = Signal() -COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY = Signal() diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py index 080caf3ff8..39b2cfb60c 100644 --- a/lms/djangoapps/grades/tests/test_course_grade_factory.py +++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py @@ -13,7 +13,6 @@ from common.djangoapps.student.tests.factories import UserFactory from lms.djangoapps.certificates.config import AUTO_CERTIFICATE_GENERATION from lms.djangoapps.courseware.access import has_access from lms.djangoapps.grades.config.tests.utils import persistent_grades_feature_flags -from lms.djangoapps.grades.signals.signals import COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY from openedx.core.djangoapps.content.block_structure.factory import BlockStructureFactory from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order @@ -96,25 +95,16 @@ class TestCourseGradeFactory(GradeTestBase): course_id=self.course.id, enabled_for_course=False ): - with patch( - 'lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - return_value=None - ) as mock_course_passed_pathway: - with override_waffle_switch(AUTO_CERTIFICATE_GENERATION, active=True), mock_get_score(2, 2): - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.connect(handler) - COURSE_GRADE_NOW_PASSED.connect(handler) - try: - CourseGradeFactory().update(self.request.user, self.course) - except RecursionError: - pytest.fail("The COURSE_GRADE_NOW_PASSED signal fired recursively.") + with override_waffle_switch(AUTO_CERTIFICATE_GENERATION, active=True), mock_get_score(2, 2): + COURSE_GRADE_NOW_PASSED.connect(handler) + try: + CourseGradeFactory().update(self.request.user, self.course) + except RecursionError: + pytest.fail("The COURSE_GRADE_NOW_PASSED signal fired recursively.") - mock_course_passed_pathway.assert_called_once() self.mock_process_signal.assert_called_once() - COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.disconnect(handler) COURSE_GRADE_NOW_PASSED.disconnect(handler) - @patch('lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - Mock(return_value=None)) def test_read_and_update(self): grade_factory = CourseGradeFactory() @@ -180,8 +170,6 @@ class TestCourseGradeFactory(GradeTestBase): else: assert course_grade is None - @patch('lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - Mock(return_value=None)) def test_read_optimization(self): grade_factory = CourseGradeFactory() with patch('lms.djangoapps.grades.course_data.get_course_blocks') as mocked_course_blocks: @@ -200,8 +188,6 @@ class TestCourseGradeFactory(GradeTestBase): assert not mocked_course_blocks.called # no user-specific transformer calculation - @patch('lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - Mock(return_value=None)) def test_subsection_grade(self): grade_factory = CourseGradeFactory() with mock_get_score(1, 2): diff --git a/lms/djangoapps/grades/tests/test_models.py b/lms/djangoapps/grades/tests/test_models.py index 3ea25b178f..5405b03e94 100644 --- a/lms/djangoapps/grades/tests/test_models.py +++ b/lms/djangoapps/grades/tests/test_models.py @@ -8,7 +8,7 @@ from base64 import b64encode from collections import OrderedDict from datetime import datetime from hashlib import sha1 -from unittest.mock import patch, MagicMock +from unittest.mock import patch import ddt import pytest @@ -373,20 +373,6 @@ class PersistentCourseGradesTest(GradesModelTestCase): "letter_grade": "Great job", "passed": True, } - self.signal_mock_pathway_progress = self.setup_patch( - 'lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - None, - ) - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - mock = MagicMock(return_value=return_value) - new_patch = patch(function_name, new=mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return mock def test_update(self): created_grade = PersistentCourseGrade.update_or_create(**self.params) @@ -439,14 +425,12 @@ class PersistentCourseGradesTest(GradesModelTestCase): assert grade.letter_grade == '' assert grade.passed_timestamp == passed_timestamp - @patch('lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send') @patch('lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_FIRST_TIME.send') - def test_passed_timestamp_is_now(self, mock, mock_grade_update_in_learner_pathway): + def test_passed_timestamp_is_now(self, mock): with freeze_time(now()): grade = PersistentCourseGrade.update_or_create(**self.params) assert now() == grade.passed_timestamp self.assertEqual(mock.call_count, 1) - self.assertEqual(mock_grade_update_in_learner_pathway.call_count, 1) def test_create_and_read_grade(self): created_grade = PersistentCourseGrade.update_or_create(**self.params) diff --git a/lms/djangoapps/grades/tests/test_signals.py b/lms/djangoapps/grades/tests/test_signals.py index 4e16c0bdbf..8c161d86ac 100644 --- a/lms/djangoapps/grades/tests/test_signals.py +++ b/lms/djangoapps/grades/tests/test_signals.py @@ -285,10 +285,6 @@ class CourseEventsSignalsTest(ModuleStoreTestCase): Configure mocks for all the dependencies of the render method """ super().setUp() - self.signal_mock_pathway_progress = self.setup_patch( - 'lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - None, - ) self.user_mock = MagicMock() self.user_mock.id = 42 self.get_user_mock = self.setup_patch( diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py index d063c056e2..5b62e67641 100644 --- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py +++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py @@ -1,8 +1,6 @@ """ Tests of the instructor dashboard spoc gradebook """ -from unittest.mock import patch, MagicMock - from django.urls import reverse from capa.tests.response_xml_factory import StringResponseXMLFactory @@ -23,16 +21,6 @@ class TestGradebook(SharedModuleStoreTestCase): """ grading_policy = None - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - mock = MagicMock(return_value=return_value) - new_patch = patch(function_name, new=mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return mock - @classmethod def setUpClass(cls): super().setUpClass() @@ -70,10 +58,6 @@ class TestGradebook(SharedModuleStoreTestCase): instructor = AdminFactory.create() self.client.login(username=instructor.username, password='test') self.users = [UserFactory.create() for _ in range(USER_COUNT)] - self.signal_mock_pathway_progress = self.setup_patch( - 'lms.djangoapps.grades.signals.signals.COURSE_GRADE_PASSED_UPDATE_IN_LEARNER_PATHWAY.send', - None, - ) for user in self.users: CourseEnrollmentFactory.create(user=user, course_id=self.course.id) diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 14d49fb24f..1807a8af96 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -338,40 +338,36 @@ class TestInstructorGradeReport(InstructorGradeReportTestCase): audit_user = CourseEnrollment.enroll(UserFactory.create(), course.id) self._verify_cell_data_for_user(audit_user.username, course.id, 'Certificate Eligible', 'N', num_rows=1) grading_policy_hash = GradesTransformer.grading_policy_hash(course) - with patch( - 'learner_pathway_progress.signals.update_learner_pathway_progress', - return_value=None - ): - PersistentCourseGrade.update_or_create( - user_id=audit_user.user_id, - course_id=course.id, - passed=False, - percent_grade=0.0, - grading_policy_hash=grading_policy_hash, - ) - self._verify_cell_data_for_user(audit_user.username, course.id, 'Certificate Eligible', 'N', num_rows=1) - PersistentCourseGrade.update_or_create( - user_id=audit_user.user_id, - course_id=course.id, - passed=True, - percent_grade=0.8, - letter_grade="pass", - grading_policy_hash=grading_policy_hash, - ) - # verifies that audit passing learner is not eligible for certificate - self._verify_cell_data_for_user(audit_user.username, course.id, 'Certificate Eligible', 'N', num_rows=1) + PersistentCourseGrade.update_or_create( + user_id=audit_user.user_id, + course_id=course.id, + passed=False, + percent_grade=0.0, + grading_policy_hash=grading_policy_hash, + ) + self._verify_cell_data_for_user(audit_user.username, course.id, 'Certificate Eligible', 'N', num_rows=1) + PersistentCourseGrade.update_or_create( + user_id=audit_user.user_id, + course_id=course.id, + passed=True, + percent_grade=0.8, + letter_grade="pass", + grading_policy_hash=grading_policy_hash, + ) + # verifies that audit passing learner is not eligible for certificate + self._verify_cell_data_for_user(audit_user.username, course.id, 'Certificate Eligible', 'N', num_rows=1) - verified_user = CourseEnrollment.enroll(UserFactory.create(), course.id, 'verified') - PersistentCourseGrade.update_or_create( - user_id=verified_user.user_id, - course_id=course.id, - passed=True, - percent_grade=0.8, - letter_grade="pass", - grading_policy_hash=grading_policy_hash, - ) - # verifies that verified passing learner is eligible for certificate - self._verify_cell_data_for_user(verified_user.username, course.id, 'Certificate Eligible', 'Y', num_rows=2) + verified_user = CourseEnrollment.enroll(UserFactory.create(), course.id, 'verified') + PersistentCourseGrade.update_or_create( + user_id=verified_user.user_id, + course_id=course.id, + passed=True, + percent_grade=0.8, + letter_grade="pass", + grading_policy_hash=grading_policy_hash, + ) + # verifies that verified passing learner is eligible for certificate + self._verify_cell_data_for_user(verified_user.username, course.id, 'Certificate Eligible', 'Y', num_rows=2) @ddt.data( (ModuleStoreEnum.Type.mongo, 4, 47), diff --git a/lms/djangoapps/learner_dashboard/api/v0/tests/test_views.py b/lms/djangoapps/learner_dashboard/api/v0/tests/test_views.py index eb985f058e..7072235ef1 100644 --- a/lms/djangoapps/learner_dashboard/api/v0/tests/test_views.py +++ b/lms/djangoapps/learner_dashboard/api/v0/tests/test_views.py @@ -155,14 +155,10 @@ class TestProgramsView(SharedModuleStoreTestCase, ProgramCacheMixin): course_id=modulestore_course.id, user=cls.user ) - with mock.patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - return_value=None - ): - EnterpriseCourseEnrollmentFactory( - course_id=modulestore_course.id, - enterprise_customer_user=enterprise_customer_user - ) + EnterpriseCourseEnrollmentFactory( + course_id=modulestore_course.id, + enterprise_customer_user=enterprise_customer_user + ) cls.program = ProgramFactory( uuid=cls.program_uuid, diff --git a/lms/djangoapps/support/tests/test_views.py b/lms/djangoapps/support/tests/test_views.py index f6b4206aa6..3aa56a0a76 100644 --- a/lms/djangoapps/support/tests/test_views.py +++ b/lms/djangoapps/support/tests/test_views.py @@ -343,14 +343,10 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=self.student.id ) - with patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - return_value=None - ): - enterprise_course_enrollment = EnterpriseCourseEnrollmentFactory( - course_id=self.course.id, - enterprise_customer_user=enterprise_customer_user - ) + enterprise_course_enrollment = EnterpriseCourseEnrollmentFactory( + course_id=self.course.id, + enterprise_customer_user=enterprise_customer_user + ) data_sharing_consent = DataSharingConsent( course_id=self.course.id, enterprise_customer=enterprise_customer_user.enterprise_customer, diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py index c416b7a4c2..c1ee73a970 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py @@ -1310,10 +1310,6 @@ class TestAccountRetirementPost(RetirementTestCase): self.cache_key = UserProfile.country_cache_key_name(self.test_user.id) cache.set(self.cache_key, 'Timor-leste') - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) # Enterprise model setup self.course_id = 'course-v1:edX+DemoX.1+2T2017' @@ -1375,16 +1371,6 @@ class TestAccountRetirementPost(RetirementTestCase): self.headers['content_type'] = "application/json" self.url = reverse('accounts_retire') - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - magic_mock = mock.MagicMock(return_value=return_value) - new_patch = mock.patch(function_name, new=magic_mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return magic_mock - def post_and_assert_status(self, data, expected_status=status.HTTP_204_NO_CONTENT): """ Helper function for making a request to the retire subscriptions endpoint, and asserting the status. diff --git a/openedx/features/enterprise_support/tests/test_api.py b/openedx/features/enterprise_support/tests/test_api.py index cd1958353e..3731e81a1b 100644 --- a/openedx/features/enterprise_support/tests/test_api.py +++ b/openedx/features/enterprise_support/tests/test_api.py @@ -447,14 +447,10 @@ class TestEnterpriseApi(EnterpriseServiceMockMixin, CacheIsolationTestCase): if not is_enterprise_enabled: assert get_enterprise_course_enrollments(self.user) == [] else: - with mock.patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - return_value=None - ): - ece = EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user) - enterprise_course_enrollments = get_enterprise_course_enrollments(self.user) - assert len(enterprise_course_enrollments) == 1 - assert enterprise_course_enrollments[0].id == ece.id + ece = EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user) + enterprise_course_enrollments = get_enterprise_course_enrollments(self.user) + assert len(enterprise_course_enrollments) == 1 + assert enterprise_course_enrollments[0].id == ece.id @httpretty.activate @mock.patch('openedx.features.enterprise_support.api.get_enterprise_learner_data_from_db') diff --git a/openedx/features/enterprise_support/tests/test_context.py b/openedx/features/enterprise_support/tests/test_context.py index 6a671bd9a2..d775859b1b 100644 --- a/openedx/features/enterprise_support/tests/test_context.py +++ b/openedx/features/enterprise_support/tests/test_context.py @@ -1,8 +1,6 @@ """ Test the enterprise support APIs. """ -from unittest.mock import patch - from django.conf import settings from django.test.utils import override_settings @@ -35,16 +33,12 @@ class TestEnterpriseContext(EnterpriseServiceMockMixin, CacheIsolationTestCase): super().setUpTestData() def test_get_enterprise_event_context(self): - with patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - return_value=None - ): - course_enrollment = CourseEnrollmentFactory(user=self.user) - course = course_enrollment.course - enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=self.user.id) - EnterpriseCourseEnrollmentFactory( - enterprise_customer_user=enterprise_customer_user, - course_id=course.id - ) - assert get_enterprise_event_context(course_id=course.id, user_id=self.user.id) == \ - {'enterprise_uuid': str(enterprise_customer_user.enterprise_customer_id)} + course_enrollment = CourseEnrollmentFactory(user=self.user) + course = course_enrollment.course + enterprise_customer_user = EnterpriseCustomerUserFactory(user_id=self.user.id) + EnterpriseCourseEnrollmentFactory( + enterprise_customer_user=enterprise_customer_user, + course_id=course.id + ) + assert get_enterprise_event_context(course_id=course.id, user_id=self.user.id) == \ + {'enterprise_uuid': str(enterprise_customer_user.enterprise_customer_id)} diff --git a/openedx/features/enterprise_support/tests/test_serializers.py b/openedx/features/enterprise_support/tests/test_serializers.py index 876bf3e348..1f1b73bae6 100644 --- a/openedx/features/enterprise_support/tests/test_serializers.py +++ b/openedx/features/enterprise_support/tests/test_serializers.py @@ -1,7 +1,6 @@ """ Tests for custom enterprise_support Serializers. """ -from unittest.mock import patch, MagicMock from uuid import uuid4 from django.test import TestCase @@ -19,29 +18,14 @@ class EnterpriseCourseEnrollmentSerializerTests(TestCase): Tests for EnterpriseCourseEnrollmentSerializer. """ - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - mock = MagicMock(return_value=return_value) - new_patch = patch(function_name, new=mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return mock - - def setUp(self): - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) + @classmethod + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called enterprise_customer_user = EnterpriseCustomerUserFactory() enterprise_course_enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=enterprise_customer_user ) - self.enterprise_customer_user = enterprise_customer_user - self.enterprise_course_enrollment = enterprise_course_enrollment - - super().setUp() + cls.enterprise_customer_user = enterprise_customer_user + cls.enterprise_course_enrollment = enterprise_course_enrollment def test_data_with_license(self): """ Verify the correct fields are serialized when the enrollment is licensed. """ diff --git a/openedx/features/enterprise_support/tests/test_signals.py b/openedx/features/enterprise_support/tests/test_signals.py index a4545dff70..d1b6f9390f 100644 --- a/openedx/features/enterprise_support/tests/test_signals.py +++ b/openedx/features/enterprise_support/tests/test_signals.py @@ -3,7 +3,7 @@ import logging from datetime import timedelta -from unittest.mock import patch, MagicMock +from unittest.mock import patch import ddt from django.test.utils import override_settings @@ -45,27 +45,12 @@ class EnterpriseSupportSignals(SharedModuleStoreTestCase): """ Tests for the enterprise support signals. """ - - def setup_patch(self, function_name, return_value): - """ - Patch a function with a given return value, and return the mock - """ - mock = MagicMock(return_value=return_value) - new_patch = patch(function_name, new=mock) - new_patch.start() - self.addCleanup(new_patch.stop) - return mock - def setUp(self): UserFactory.create(username=TEST_ECOMMERCE_WORKER) self.user = UserFactory.create(username='test', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() self.enterprise_customer_uuid = str(self.enterprise_customer.uuid) - self.mock_pathways_with_course = self.setup_patch( - 'learner_pathway_progress.signals.get_learner_pathways_associated_with_course', - None, - ) super().setUp() @staticmethod diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 7d551136b7..f86d03e6ec 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -75,4 +75,8 @@ scipy<1.8.0 mistune<2.0.0 # breaking change on openedx-events==0.10.0 -openedx-events==0.9.1 \ No newline at end of file +openedx-events==0.9.1 +# The team that owns this package will manually bump this package rather than having it pulled in automatically. +# This is to allow them to better control its deployment and to do it in a process that works better +# for them. +learner-pathway-progress==1.0.1 diff --git a/requirements/edx/base.in b/requirements/edx/base.in index 5acb033d18..aa9097138e 100644 --- a/requirements/edx/base.in +++ b/requirements/edx/base.in @@ -109,7 +109,7 @@ ipaddress # Ip network support for Embargo feature jsonfield # Django model field for validated JSON; used in several apps laboratory # Library for testing that code refactors/infrastructure changes produce identical results lxml # XML parser -learner-pathway-progress # A plugin for lms to track learners progress in pathays +learner-pathway-progress==1.0.1 # A plugin for lms to track learners progress in pathays lti-consumer-xblock>=4.1.1 mailsnake # Needed for mailchimp (mailing djangoapp) mako # Primary template language used for server-side page rendering diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 3194349e5c..d12e3889a1 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -640,7 +640,7 @@ lazy==1.4 # acid-xblock # lti-consumer-xblock # ora2 -learner-pathway-progress==1.2.0 +learner-pathway-progress==1.0.1 # via -r requirements/edx/base.in libsass==0.10.0 # via diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index d04b7071d4..ee87c79cee 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -841,7 +841,7 @@ lazy-object-proxy==1.7.1 # via # -r requirements/edx/testing.txt # astroid -learner-pathway-progress==1.2.0 +learner-pathway-progress==1.0.1 # via -r requirements/edx/testing.txt libsass==0.10.0 # via diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 82d61bfc45..7dcf8d9c8e 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -802,7 +802,7 @@ lazy==1.4 # ora2 lazy-object-proxy==1.7.1 # via astroid -learner-pathway-progress==1.2.0 +learner-pathway-progress==1.0.1 # via -r requirements/edx/base.txt libsass==0.10.0 # via