From 1dd38453839b0a971b3d093df1031694bd90cd8a Mon Sep 17 00:00:00 2001 From: Emily Aquin Date: Tue, 25 Jul 2023 16:22:17 +0000 Subject: [PATCH 1/2] chore: use lms_update_or_create_enrollment without feature flag --- enterprise/utils.py | 34 +- tests/test_enterprise/api/test_views.py | 356 +++++++-------- tests/test_enterprise/test_utils.py | 549 +++++++++++------------- 3 files changed, 421 insertions(+), 518 deletions(-) diff --git a/enterprise/utils.py b/enterprise/utils.py index 2ca8e4ffa5..c278f9a4fa 100644 --- a/enterprise/utils.py +++ b/enterprise/utils.py @@ -46,12 +46,8 @@ from enterprise.logging import getEnterpriseLogger try: - from openedx.features.enterprise_support.enrollments.utils import ( - lms_enroll_user_in_course, - lms_update_or_create_enrollment, - ) + from openedx.features.enterprise_support.enrollments.utils import lms_update_or_create_enrollment except ImportError: - lms_enroll_user_in_course = None lms_update_or_create_enrollment = None try: @@ -1824,30 +1820,16 @@ def customer_admin_enroll_user_with_status( succeeded = False new_enrollment = False enterprise_fulfillment_source_uuid = None - emet_enable_auto_upgrade_enrollment_mode = getattr( - settings, - 'ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE', - False, - ) try: # enrolls a user in a course per LMS flow, but this method doesn't create enterprise records # yet so we need to create it immediately after calling lms_update_or_create_enrollment. - if emet_enable_auto_upgrade_enrollment_mode: - new_enrollment = lms_update_or_create_enrollment( - user.username, - course_id, - course_mode, - is_active=True, - enterprise_uuid=enterprise_customer.uuid, - ) - else: - new_enrollment = lms_enroll_user_in_course( - user.username, - course_id, - course_mode, - enterprise_customer.uuid, - is_active=True, - ) + new_enrollment = lms_update_or_create_enrollment( + user.username, + course_id, + course_mode, + is_active=True, + enterprise_uuid=enterprise_customer.uuid, + ) succeeded = True LOGGER.info("Successfully enrolled user %s in course %s", user.id, course_id) except (CourseEnrollmentError, CourseUserGroup.DoesNotExist) as error: diff --git a/tests/test_enterprise/api/test_views.py b/tests/test_enterprise/api/test_views.py index 7d0a10bcb7..5de69468b6 100644 --- a/tests/test_enterprise/api/test_views.py +++ b/tests/test_enterprise/api/test_views.py @@ -4458,12 +4458,8 @@ def test_bulk_enrollment_in_bulk_courses_pending_licenses( @mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment') @mock.patch('enterprise.models.EnterpriseCustomer.notify_enrolled_learners') @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_bulk_enrollment_in_bulk_courses_existing_users( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, mock_notify_task, mock_track_enroll, @@ -4474,84 +4470,76 @@ def test_bulk_enrollment_in_bulk_courses_existing_users( This tests the case where existing users are supplied, so the enrollments are fulfilled rather than pending. """ - if setting_value: - mock_customer_admin_enroll_user = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user = mock_enroll_user_in_course + mock_update_or_create_enrollment.return_value = True - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - mock_customer_admin_enroll_user.return_value = True + user_one = factories.UserFactory(is_active=True) + user_two = factories.UserFactory(is_active=True) - user_one = factories.UserFactory(is_active=True) - user_two = factories.UserFactory(is_active=True) + factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) - factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) + permission = Permission.objects.get(name='Can add Enterprise Customer') + self.user.user_permissions.add(permission) + mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE - permission = Permission.objects.get(name='Can add Enterprise Customer') - self.user.user_permissions.add(permission) - mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE + self.assertEqual(len(PendingEnrollment.objects.all()), 0) + body = { + 'enrollments_info': [ + { + 'user_id': user_one.id, + 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', + 'license_uuid': '5a88bdcade7c4ecb838f8111b68e18ac' + }, + { + 'email': user_two.email, + 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', + 'license_uuid': '2c58acdade7c4ede838f7111b42e18ac' + }, + ] + } + response = self.client.post( + settings.TEST_SERVER + ENTERPRISE_CUSTOMER_BULK_ENROLL_LEARNERS_IN_COURSES_ENDPOINT, + data=json.dumps(body), + content_type='application/json', + ) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response_json = response.json() + self.assertEqual({ + 'successes': [ + { + 'user_id': user_one.id, + 'email': user_one.email, + 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': str(EnterpriseCourseEnrollment.objects.filter( + enterprise_customer_user__user_id=user_one.id + ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid) + }, + { + 'user_id': user_two.id, + 'email': user_two.email, + 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': str(EnterpriseCourseEnrollment.objects.filter( + enterprise_customer_user__user_id=user_two.id + ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid) + }, + ], + 'pending': [], + 'failures': [], + }, response_json) + self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 2) + # no notifications to be sent unless 'notify' specifically asked for in payload + mock_notify_task.assert_not_called() + mock_track_enroll.assert_has_calls([ + mock.call(PATHWAY_CUSTOMER_ADMIN_ENROLLMENT, 1, 'course-v1:edX+DemoX+Demo_Course'), + ]) - self.assertEqual(len(PendingEnrollment.objects.all()), 0) - body = { - 'enrollments_info': [ - { - 'user_id': user_one.id, - 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', - 'license_uuid': '5a88bdcade7c4ecb838f8111b68e18ac' - }, - { - 'email': user_two.email, - 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', - 'license_uuid': '2c58acdade7c4ede838f7111b42e18ac' - }, - ] - } - response = self.client.post( - settings.TEST_SERVER + ENTERPRISE_CUSTOMER_BULK_ENROLL_LEARNERS_IN_COURSES_ENDPOINT, - data=json.dumps(body), - content_type='application/json', - ) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response_json = response.json() - self.assertEqual({ - 'successes': [ - { - 'user_id': user_one.id, - 'email': user_one.email, - 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': str(EnterpriseCourseEnrollment.objects.filter( - enterprise_customer_user__user_id=user_one.id - ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid) - }, - { - 'user_id': user_two.id, - 'email': user_two.email, - 'course_run_key': 'course-v1:edX+DemoX+Demo_Course', - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': str(EnterpriseCourseEnrollment.objects.filter( - enterprise_customer_user__user_id=user_two.id - ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid) - }, - ], - 'pending': [], - 'failures': [], - }, response_json) - self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 2) - # no notifications to be sent unless 'notify' specifically asked for in payload - mock_notify_task.assert_not_called() - mock_track_enroll.assert_has_calls([ - mock.call(PATHWAY_CUSTOMER_ADMIN_ENROLLMENT, 1, 'course-v1:edX+DemoX+Demo_Course'), - ]) - if setting_value: - assert mock_update_or_create_enrollment.call_count == 2 - else: - assert mock_enroll_user_in_course.call_count == 2 + assert mock_update_or_create_enrollment.call_count == 2 @mock.patch('enterprise.api.v1.views.enterprise_customer.get_best_mode_from_course_key') @mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment') @@ -4618,12 +4606,10 @@ def test_bulk_enrollment_in_bulk_courses_nonexisting_user_id( { 'old_transaction_id': FAKE_UUIDS[4], 'new_transaction_id': FAKE_UUIDS[4], - 'setting_value': True, }, { 'old_transaction_id': str(uuid.uuid4()), 'new_transaction_id': str(uuid.uuid4()), - 'setting_value': False, }, ) @ddt.unpack @@ -4632,100 +4618,92 @@ def test_bulk_enrollment_in_bulk_courses_nonexisting_user_id( 'enterprise.api.v1.views.enterprise_customer.get_best_mode_from_course_key' ) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') def test_bulk_enrollment_enroll_after_cancel( self, mock_platform_enrollment, mock_get_course_mode, mock_update_or_create_enrollment, - mock_enroll_user_in_course, old_transaction_id, new_transaction_id, - setting_value, ): """ Test that even after a cancelled enterprise enrollment, an attempt to re-enroll the same learner in content results in expected state and payload. """ - if setting_value: - mock_enrollment_api = mock_update_or_create_enrollment - else: - mock_enrollment_api = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - mock_platform_enrollment.return_value = True - mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE - # Needed for the cancel endpoint: - mock_enrollment_api.update_enrollment.return_value = mock.Mock() - - user, enterprise_user, enterprise_customer = \ - self._create_user_and_enterprise_customer('abc@test.com', 'test_password') - permission = Permission.objects.get(name='Can add Enterprise Customer') - user.user_permissions.add(permission) - - course_id = 'course-v1:edX+DemoX+Demo_Course' - enterprise_course_enrollment = factories.EnterpriseCourseEnrollmentFactory( - enterprise_customer_user=enterprise_user, - course_id=course_id, - ) - learner_credit_course_enrollment = factories.LearnerCreditEnterpriseCourseEnrollmentFactory( - enterprise_course_enrollment=enterprise_course_enrollment, - transaction_id=old_transaction_id, - ) - learner_credit_fulfillment_url = reverse( - 'enterprise-subsidy-fulfillment', - kwargs={'fulfillment_source_uuid': str(learner_credit_course_enrollment.uuid)} - ) - cancel_url = learner_credit_fulfillment_url + '/cancel-fulfillment' - enrollment_url = reverse( - 'enterprise-customer-enroll-learners-in-courses', - (str(enterprise_customer.uuid),) + mock_platform_enrollment.return_value = True + mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE + # Needed for the cancel endpoint: + mock_update_or_create_enrollment.update_enrollment.return_value = mock.Mock() + + user, enterprise_user, enterprise_customer = \ + self._create_user_and_enterprise_customer('abc@test.com', 'test_password') + permission = Permission.objects.get(name='Can add Enterprise Customer') + user.user_permissions.add(permission) + + course_id = 'course-v1:edX+DemoX+Demo_Course' + enterprise_course_enrollment = factories.EnterpriseCourseEnrollmentFactory( + enterprise_customer_user=enterprise_user, + course_id=course_id, + ) + learner_credit_course_enrollment = factories.LearnerCreditEnterpriseCourseEnrollmentFactory( + enterprise_course_enrollment=enterprise_course_enrollment, + transaction_id=old_transaction_id, + ) + learner_credit_fulfillment_url = reverse( + 'enterprise-subsidy-fulfillment', + kwargs={'fulfillment_source_uuid': str(learner_credit_course_enrollment.uuid)} + ) + cancel_url = learner_credit_fulfillment_url + '/cancel-fulfillment' + enrollment_url = reverse( + 'enterprise-customer-enroll-learners-in-courses', + (str(enterprise_customer.uuid),) + ) + enroll_body = { + 'notify': 'true', + 'enrollments_info': [ + { + 'email': user.email, + 'course_run_key': course_id, + 'transaction_id': new_transaction_id, + }, + ] + } + with mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment'): + with mock.patch("enterprise.models.EnterpriseCustomer.notify_enrolled_learners"): + cancel_response = self.client.post(settings.TEST_SERVER + cancel_url) + with LogCapture(level=logging.WARNING) as warn_logs: + second_enroll_response = self.client.post( + settings.TEST_SERVER + enrollment_url, + data=json.dumps(enroll_body), + content_type='application/json', + ) + + assert cancel_response.status_code == status.HTTP_200_OK + assert second_enroll_response.status_code == status.HTTP_201_CREATED + + if old_transaction_id == new_transaction_id: + assert any( + 'using the same transaction_id as before' + in log_record.getMessage() for log_record in warn_logs.records ) - enroll_body = { - 'notify': 'true', - 'enrollments_info': [ - { - 'email': user.email, - 'course_run_key': course_id, - 'transaction_id': new_transaction_id, - }, - ] - } - with mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment'): - with mock.patch("enterprise.models.EnterpriseCustomer.notify_enrolled_learners"): - cancel_response = self.client.post(settings.TEST_SERVER + cancel_url) - with LogCapture(level=logging.WARNING) as warn_logs: - second_enroll_response = self.client.post( - settings.TEST_SERVER + enrollment_url, - data=json.dumps(enroll_body), - content_type='application/json', - ) - - assert cancel_response.status_code == status.HTTP_200_OK - assert second_enroll_response.status_code == status.HTTP_201_CREATED - - if old_transaction_id == new_transaction_id: - assert any( - 'using the same transaction_id as before' - in log_record.getMessage() for log_record in warn_logs.records - ) - # First, check that the bulk enrollment response looks good: - response_json = second_enroll_response.json() - assert len(response_json.get('successes')) == 1 - assert response_json['successes'][0]['user_id'] == user.id - assert response_json['successes'][0]['email'] == user.email - assert response_json['successes'][0]['course_run_key'] == course_id - assert response_json['successes'][0]['created'] is True - assert uuid.UUID(response_json['successes'][0]['enterprise_fulfillment_source_uuid']) == \ - learner_credit_course_enrollment.uuid - - # Then, check that the db records related to the enrollment look good: - enterprise_course_enrollment.refresh_from_db() - learner_credit_course_enrollment.refresh_from_db() - assert enterprise_course_enrollment.unenrolled_at is None - assert enterprise_course_enrollment.saved_for_later is False - assert learner_credit_course_enrollment.is_revoked is False - assert learner_credit_course_enrollment.transaction_id == uuid.UUID(new_transaction_id) + # First, check that the bulk enrollment response looks good: + response_json = second_enroll_response.json() + assert len(response_json.get('successes')) == 1 + assert response_json['successes'][0]['user_id'] == user.id + assert response_json['successes'][0]['email'] == user.email + assert response_json['successes'][0]['course_run_key'] == course_id + assert response_json['successes'][0]['created'] is True + assert uuid.UUID(response_json['successes'][0]['enterprise_fulfillment_source_uuid']) == \ + learner_credit_course_enrollment.uuid + + # Then, check that the db records related to the enrollment look good: + enterprise_course_enrollment.refresh_from_db() + learner_credit_course_enrollment.refresh_from_db() + assert enterprise_course_enrollment.unenrolled_at is None + assert enterprise_course_enrollment.saved_for_later is False + assert learner_credit_course_enrollment.is_revoked is False + assert learner_credit_course_enrollment.transaction_id == uuid.UUID(new_transaction_id) @ddt.data( { @@ -4740,7 +4718,6 @@ def test_bulk_enrollment_enroll_after_cancel( ] }, 'fulfillment_source': LearnerCreditEnterpriseCourseEnrollment, - 'setting_value': True, }, { 'body': { @@ -4754,19 +4731,15 @@ def test_bulk_enrollment_enroll_after_cancel( ] }, 'fulfillment_source': LicensedEnterpriseCourseEnrollment, - 'setting_value': False, }, ) @ddt.unpack @mock.patch('enterprise.api.v1.views.enterprise_customer.get_best_mode_from_course_key') @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') def test_bulk_enrollment_includes_fulfillment_source_uuid( self, mock_get_course_mode, mock_update_or_create_enrollment, - mock_enroll_user_in_course, - setting_value, body, fulfillment_source, ): @@ -4774,41 +4747,36 @@ def test_bulk_enrollment_includes_fulfillment_source_uuid( Test that a successful bulk enrollment call to generate subsidy based enrollment records will return the newly generated subsidized enrollment uuid value as part of the response payload. """ - if setting_value: - mock_platform_enrollment = mock_update_or_create_enrollment - else: - mock_platform_enrollment = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - mock_platform_enrollment.return_value = True + mock_update_or_create_enrollment.return_value = True - user, _, enterprise_customer = self._create_user_and_enterprise_customer( - body.get('enrollments_info')[0].get('email'), 'test_password' - ) + user, _, enterprise_customer = self._create_user_and_enterprise_customer( + body.get('enrollments_info')[0].get('email'), 'test_password' + ) - permission = Permission.objects.get(name='Can add Enterprise Customer') - user.user_permissions.add(permission) - mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE + permission = Permission.objects.get(name='Can add Enterprise Customer') + user.user_permissions.add(permission) + mock_get_course_mode.return_value = VERIFIED_SUBSCRIPTION_COURSE_MODE - enrollment_url = reverse( - 'enterprise-customer-enroll-learners-in-courses', - (str(enterprise_customer.uuid),) - ) - with mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment'): - with mock.patch("enterprise.models.EnterpriseCustomer.notify_enrolled_learners"): - response = self.client.post( - settings.TEST_SERVER + enrollment_url, - data=json.dumps(body), - content_type='application/json', - ) + enrollment_url = reverse( + 'enterprise-customer-enroll-learners-in-courses', + (str(enterprise_customer.uuid),) + ) + with mock.patch('enterprise.api.v1.views.enterprise_customer.track_enrollment'): + with mock.patch("enterprise.models.EnterpriseCustomer.notify_enrolled_learners"): + response = self.client.post( + settings.TEST_SERVER + enrollment_url, + data=json.dumps(body), + content_type='application/json', + ) - self.assertEqual(response.status_code, 201) + self.assertEqual(response.status_code, 201) - response_json = response.json() - self.assertEqual(len(response_json.get('successes')), 1) - self.assertEqual( - str(fulfillment_source.objects.first().uuid), - response_json.get('successes')[0].get('enterprise_fulfillment_source_uuid') - ) + response_json = response.json() + self.assertEqual(len(response_json.get('successes')), 1) + self.assertEqual( + str(fulfillment_source.objects.first().uuid), + response_json.get('successes')[0].get('enterprise_fulfillment_source_uuid') + ) @ddt.data( { diff --git a/tests/test_enterprise/test_utils.py b/tests/test_enterprise/test_utils.py index 21ddfe0c34..d98921e6c0 100644 --- a/tests/test_enterprise/test_utils.py +++ b/tests/test_enterprise/test_utils.py @@ -11,7 +11,6 @@ from django.conf import settings from django.forms.models import model_to_dict -from django.test import override_settings from enterprise.models import EnterpriseCourseEnrollment, LicensedEnterpriseCourseEnrollment from enterprise.utils import ( @@ -101,12 +100,8 @@ def test_get_platform_logo_url(self, logo_url, expected_logo_url, mock_get_logo_ @mock.patch('enterprise.utils.CourseEnrollmentError', new_callable=lambda: StubException) @mock.patch('enterprise.utils.CourseUserGroup', new_callable=lambda: StubModel) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_enroll_subsidy_users_in_courses_fails( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, mock_model, mock_error, @@ -115,50 +110,40 @@ def test_enroll_subsidy_users_in_courses_fails( Test that `enroll_subsidy_users_in_courses` properly handles failure cases where something goes wrong with the user enrollment. """ - if setting_value: - mock_customer_admin_enroll_user_with_status = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user_with_status = mock_enroll_user_in_course - - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - self.create_user() - ent_customer = factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) - mock_model.DoesNotExist = Exception - mock_customer_admin_enroll_user_with_status.side_effect = [mock_error('mocked error')] - licensed_users_info = [{ - 'email': self.user.email, - 'course_run_key': 'course-key-v1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' - }] - result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) - self.assertEqual( - { - "successes": [], - "failures": [ - { - "user_id": self.user.id, - "email": self.user.email, - "course_run_key": "course-key-v1", - } - ], - "pending": [], - }, - result, - ) + self.create_user() + ent_customer = factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) + mock_model.DoesNotExist = Exception + mock_update_or_create_enrollment.side_effect = [mock_error('mocked error')] + licensed_users_info = [{ + 'email': self.user.email, + 'course_run_key': 'course-key-v1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' + }] + result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) + self.assertEqual( + { + "successes": [], + "failures": [ + { + "user_id": self.user.id, + "email": self.user.email, + "course_run_key": "course-key-v1", + } + ], + "pending": [], + }, + result, + ) @mock.patch('enterprise.utils.CourseEnrollmentError', new_callable=lambda: StubException) @mock.patch('enterprise.utils.CourseUserGroup', new_callable=lambda: StubModel) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_enroll_subsidy_users_in_courses_partially_fails( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, mock_model, mock_error, @@ -167,294 +152,262 @@ def test_enroll_subsidy_users_in_courses_partially_fails( Test that `enroll_subsidy_users_in_courses` properly handles partial failure states and still creates enrollments for the users that succeed. """ - if setting_value: - mock_customer_admin_enroll_user_with_status = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user_with_status = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - self.create_user() - failure_user = factories.UserFactory() - - ent_customer = factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) - factories.EnterpriseCustomerUserFactory( - user_id=self.user.id, - enterprise_customer=ent_customer, - ) - - licensed_users_info = [ - { + self.create_user() + failure_user = factories.UserFactory() + + ent_customer = factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) + factories.EnterpriseCustomerUserFactory( + user_id=self.user.id, + enterprise_customer=ent_customer, + ) + + licensed_users_info = [ + { + 'email': self.user.email, + 'course_run_key': 'course-key-v1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' + }, + { + 'email': failure_user.email, + 'course_run_key': 'course-key-v1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' + } + ] + mock_model.DoesNotExist = Exception + mock_update_or_create_enrollment.side_effect = [True, mock_error('mocked error'), None] + result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) + self.assertEqual( + { + 'pending': [], + 'successes': [{ + 'user_id': self.user.id, 'email': self.user.email, 'course_run_key': 'course-key-v1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' - }, - { + 'user': self.user, + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': LicensedEnterpriseCourseEnrollment.objects.first().uuid, + }], + 'failures': [{ + 'user_id': failure_user.id, 'email': failure_user.email, 'course_run_key': 'course-key-v1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' - } - ] - mock_model.DoesNotExist = Exception - mock_customer_admin_enroll_user_with_status.side_effect = [True, mock_error('mocked error'), None] - result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) - self.assertEqual( - { - 'pending': [], - 'successes': [{ - 'user_id': self.user.id, - 'email': self.user.email, - 'course_run_key': 'course-key-v1', - 'user': self.user, - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': LicensedEnterpriseCourseEnrollment.objects.first().uuid, - }], - 'failures': [{ - 'user_id': failure_user.id, - 'email': failure_user.email, - 'course_run_key': 'course-key-v1', - }], - }, - result - ) - self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 1) + }], + }, + result + ) + self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 1) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_enroll_subsidy_users_in_courses_succeeds( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, ): """ Test that users that already exist are enrolled by enroll_subsidy_users_in_courses and returned under the `succeeded` field. """ - if setting_value: - mock_customer_admin_enroll_user = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - self.create_user() - - ent_customer = factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) - factories.EnterpriseCustomerUserFactory( - user_id=self.user.id, - enterprise_customer=ent_customer, - ) - licensed_users_info = [{ - 'email': self.user.email, - 'course_run_key': 'course-key-v1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' - }] - - mock_customer_admin_enroll_user.return_value = True - result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) - self.assertEqual( - { - 'pending': [], - 'successes': [{ - 'user_id': self.user.id, - 'email': self.user.email, - 'course_run_key': 'course-key-v1', - 'user': self.user, - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': LicensedEnterpriseCourseEnrollment.objects.first().uuid, - }], - 'failures': [] - }, - result - ) - self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 1) + self.create_user() + + ent_customer = factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) + factories.EnterpriseCustomerUserFactory( + user_id=self.user.id, + enterprise_customer=ent_customer, + ) + licensed_users_info = [{ + 'email': self.user.email, + 'course_run_key': 'course-key-v1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae' + }] + + mock_update_or_create_enrollment.return_value = True + result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) + self.assertEqual( + { + 'pending': [], + 'successes': [{ + 'user_id': self.user.id, + 'email': self.user.email, + 'course_run_key': 'course-key-v1', + 'user': self.user, + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': LicensedEnterpriseCourseEnrollment.objects.first().uuid, + }], + 'failures': [] + }, + result + ) + self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 1) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_enroll_subsidy_users_in_courses_with_user_id_succeeds( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, ): """ Test that users that already exist are enrolled by enroll_subsidy_users_in_courses and returned under the ``succeeded`` field. Specifically test when a ``user_id`` is supplied. """ - if setting_value: - mock_customer_admin_enroll_user = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - self.create_user() - another_user = factories.UserFactory(is_active=True) - - ent_customer = factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) - factories.EnterpriseCustomerUserFactory( - user_id=self.user.id, - enterprise_customer=ent_customer, - ) - licensed_users_info = [ - { - # Should succeed with only a user_id supplied. - 'user_id': self.user.id, - 'course_run_key': 'course-key-1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - { - # Should succeed even with both a user_id and email supplied. - 'user_id': another_user.id, - 'email': another_user.email, - 'course_run_key': 'course-key-2', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - ] - - mock_customer_admin_enroll_user.return_value = True - - result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) - self.assertEqual( - { - 'pending': [], - 'successes': [ - { - 'user_id': self.user.id, - 'email': self.user.email, - 'course_run_key': 'course-key-1', - 'user': self.user, - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': EnterpriseCourseEnrollment.objects.filter( - enterprise_customer_user__user_id=self.user.id - ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid, - }, - { - 'user_id': another_user.id, - 'email': another_user.email, - 'course_run_key': 'course-key-2', - 'user': another_user, - 'created': True, - 'activation_link': None, - 'enterprise_fulfillment_source_uuid': EnterpriseCourseEnrollment.objects.filter( - enterprise_customer_user__user_id=another_user.id - ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid, - } - ], - 'failures': [], - }, - result - ) - self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 2) + self.create_user() + another_user = factories.UserFactory(is_active=True) + + ent_customer = factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) + factories.EnterpriseCustomerUserFactory( + user_id=self.user.id, + enterprise_customer=ent_customer, + ) + licensed_users_info = [ + { + # Should succeed with only a user_id supplied. + 'user_id': self.user.id, + 'course_run_key': 'course-key-1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + { + # Should succeed even with both a user_id and email supplied. + 'user_id': another_user.id, + 'email': another_user.email, + 'course_run_key': 'course-key-2', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + ] + + mock_update_or_create_enrollment.return_value = True + + result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) + self.assertEqual( + { + 'pending': [], + 'successes': [ + { + 'user_id': self.user.id, + 'email': self.user.email, + 'course_run_key': 'course-key-1', + 'user': self.user, + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': EnterpriseCourseEnrollment.objects.filter( + enterprise_customer_user__user_id=self.user.id + ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid, + }, + { + 'user_id': another_user.id, + 'email': another_user.email, + 'course_run_key': 'course-key-2', + 'user': another_user, + 'created': True, + 'activation_link': None, + 'enterprise_fulfillment_source_uuid': EnterpriseCourseEnrollment.objects.filter( + enterprise_customer_user__user_id=another_user.id + ).first().licensedenterprisecourseenrollment_enrollment_fulfillment.uuid, + } + ], + 'failures': [], + }, + result + ) + self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 2) @mock.patch('enterprise.utils.lms_update_or_create_enrollment') - @mock.patch('enterprise.utils.lms_enroll_user_in_course') - @ddt.data(True, False) def test_enroll_subsidy_users_in_courses_user_identifier_failures( self, - setting_value, - mock_enroll_user_in_course, mock_update_or_create_enrollment, ): """ """ - if setting_value: - mock_customer_admin_enroll_user = mock_update_or_create_enrollment - else: - mock_customer_admin_enroll_user = mock_enroll_user_in_course - with override_settings(ENABLE_ENTERPRISE_BACKEND_EMET_AUTO_UPGRADE_ENROLLMENT_MODE=setting_value): - self.create_user() - another_user = factories.UserFactory(is_active=True) - - ent_customer = factories.EnterpriseCustomerFactory( - uuid=FAKE_UUIDS[0], - name="test_enterprise" - ) - factories.EnterpriseCustomerUserFactory( - user_id=self.user.id, - enterprise_customer=ent_customer, - ) - licensed_users_info = [ - { - # Should fail due to the user_id not matching the email of the same user. - 'user_id': self.user.id, - 'email': another_user.email, - 'course_run_key': 'course-key-1', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - { - # Should fail due to the user_id not matching the email of the same user. Special case where the - # user_id does not exist. - 'user_id': self.user.id + 1000, - 'email': self.user.email, - 'course_run_key': 'course-key-2', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - { - # Should fail due to the user_id not matching the email of the same user. Special case where the - # email does not exist. - 'user_id': self.user.id, - 'email': 'wrong+' + self.user.email, - 'course_run_key': 'course-key-3', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - { - # Should fail due to providing neither `user_id` nor `email`. - 'course_run_key': 'course-key-4', - 'course_mode': 'verified', - 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', - }, - ] - - mock_customer_admin_enroll_user.return_value = True - - result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) - self.assertEqual( - { - 'pending': [], - 'successes': [], - 'failures': [ - { - 'user_id': self.user.id, - 'email': another_user.email, - 'course_run_key': 'course-key-1', - }, - { - 'user_id': self.user.id + 1000, - 'email': self.user.email, - 'course_run_key': 'course-key-2', - }, - { - 'user_id': self.user.id, - 'email': 'wrong+' + self.user.email, - 'course_run_key': 'course-key-3', - }, - { - 'course_run_key': 'course-key-4', - }, - ], - }, - result - ) - self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 0) + self.create_user() + another_user = factories.UserFactory(is_active=True) + + ent_customer = factories.EnterpriseCustomerFactory( + uuid=FAKE_UUIDS[0], + name="test_enterprise" + ) + factories.EnterpriseCustomerUserFactory( + user_id=self.user.id, + enterprise_customer=ent_customer, + ) + licensed_users_info = [ + { + # Should fail due to the user_id not matching the email of the same user. + 'user_id': self.user.id, + 'email': another_user.email, + 'course_run_key': 'course-key-1', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + { + # Should fail due to the user_id not matching the email of the same user. Special case where the + # user_id does not exist. + 'user_id': self.user.id + 1000, + 'email': self.user.email, + 'course_run_key': 'course-key-2', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + { + # Should fail due to the user_id not matching the email of the same user. Special case where the + # email does not exist. + 'user_id': self.user.id, + 'email': 'wrong+' + self.user.email, + 'course_run_key': 'course-key-3', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + { + # Should fail due to providing neither `user_id` nor `email`. + 'course_run_key': 'course-key-4', + 'course_mode': 'verified', + 'license_uuid': '5b77bdbade7b4fcb838f8111b68e18ae', + }, + ] + + mock_update_or_create_enrollment.return_value = True + + result = enroll_subsidy_users_in_courses(ent_customer, licensed_users_info) + self.assertEqual( + { + 'pending': [], + 'successes': [], + 'failures': [ + { + 'user_id': self.user.id, + 'email': another_user.email, + 'course_run_key': 'course-key-1', + }, + { + 'user_id': self.user.id + 1000, + 'email': self.user.email, + 'course_run_key': 'course-key-2', + }, + { + 'user_id': self.user.id, + 'email': 'wrong+' + self.user.email, + 'course_run_key': 'course-key-3', + }, + { + 'course_run_key': 'course-key-4', + }, + ], + }, + result + ) + self.assertEqual(len(EnterpriseCourseEnrollment.objects.all()), 0) def test_enroll_pending_licensed_users_in_courses_succeeds(self): """ From cfc757cf0511d2bea2724e4e44b6efdedc2167d6 Mon Sep 17 00:00:00 2001 From: Emily Aquin Date: Thu, 21 Sep 2023 15:55:35 +0000 Subject: [PATCH 2/2] chore: bump version --- CHANGELOG.rst | 4 ++++ enterprise/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ba624dcb8f..18e791ccbf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,10 @@ Change Log Unreleased ---------- +[4.3.1] +-------- +chore: use lms_update_or_create_enrollment without feature flag + [4.3.0] -------- feat: Added the ``enable_career_engagement_network_on_learner_portal`` field for EnterpriseCustomer diff --git a/enterprise/__init__.py b/enterprise/__init__.py index ce723d5ecb..27abfebdc4 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.3.0" +__version__ = "4.3.1"