Skip to content

Commit

Permalink
fix: unittests for default realizations, remove errant break
Browse files Browse the repository at this point in the history
  • Loading branch information
iloveagent57 committed Dec 2, 2024
1 parent dadd558 commit 0995768
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 26 deletions.
72 changes: 72 additions & 0 deletions enterprise_access/apps/api/v1/tests/test_bff_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,3 +571,75 @@ def test_dashboard_with_enrollments(
],
})
self.assertEqual(response.json(), expected_response_data)

@mock_dashboard_dependencies
@mock.patch('enterprise_access.apps.api_client.lms_client.LmsApiClient.bulk_enroll_enterprise_learners')
def test_dashboard_with_default_enrollment_realizations(
self,
mock_get_enterprise_customers_for_user,
mock_get_default_enrollment_intentions_learner_status,
mock_get_subscription_licenses_for_learner,
mock_get_enterprise_course_enrollments,
mock_bulk_enroll,
):
"""
Test the dashboard route with enrollments.
"""
self.set_jwt_cookie([{
'system_wide_role': SYSTEM_ENTERPRISE_LEARNER_ROLE,
'context': self.mock_enterprise_customer_uuid,
}])
mock_get_enterprise_customers_for_user.return_value = self.mock_enterprise_learner_response_data

mock_activated_subscription_license = {
**self.mock_subscription_license,
'status': 'activated',
'activation_date': '2024-01-01T00:00:00Z',
}
mock_subscription_licenses_data = {
'customer_agreement': self.mock_customer_agreement,
'results': [mock_activated_subscription_license],
}
mock_get_subscription_licenses_for_learner.return_value = mock_subscription_licenses_data

mock_get_default_enrollment_intentions_learner_status.return_value = {
"lms_user_id": self.mock_user.id,
"user_email": self.mock_user.email,
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enrollment_statuses": {
"needs_enrollment": {
"enrollable": [
{
'applicable_enterprise_catalog_uuids': [self.mock_enterprise_catalog_uuid],
'course_run_key': 'course-run-1',
},
],
"not_enrollable": [],
},
'already_enrolled': [],
},
}
mock_bulk_enroll.return_value = {
'successes': [
{'course_run_key': 'course-run-1'},
],
'failures': [],
}
mock_get_enterprise_course_enrollments.return_value = [self.mock_enterprise_course_enrollment]

query_params = {
'enterprise_customer_slug': self.mock_enterprise_customer_slug,
}
dashboard_url = reverse('api:v1:learner-portal-bff-dashboard')
dashboard_url += f"?{urlencode(query_params)}"

response = self.client.post(dashboard_url)
self.assertEqual(response.status_code, status.HTTP_200_OK)

actual_customer_uuid_arg, actual_payload_arg = mock_bulk_enroll.call_args_list[0][0]
self.assertEqual(actual_customer_uuid_arg, self.mock_enterprise_customer_uuid)
expected_payload = [
{'user_id': self.user.lms_user_id, 'course_run_key': 'course-run-1',
'license_uuid': mock_activated_subscription_license['uuid'], 'is_default_auto_enrollment': True},
]
self.assertEqual(expected_payload, actual_payload_arg)
68 changes: 42 additions & 26 deletions enterprise_access/apps/bffs/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,37 @@ def enroll_in_redeemable_default_enterprise_enrollment_intentions(self):
if subscription_catalog in applicable_catalog_to_enrollment_intention:
course_run_key = enrollment_intention['course_run_key']
license_uuids_by_course_run_key[course_run_key] = self.current_active_license['uuid']
break

response_payload = self._request_default_enrollment_realizations(license_uuids_by_course_run_key)

if failures := response_payload.get('failures'):
self.add_error(
user_message='There were failures realizing default enrollments',
developer_message='Default realization enrollment failures: ' + json.dumps(failures),
)

if not self.context.data.get('default_enterprise_enrollment_realizations'):
self.context.data['default_enterprise_enrollment_realizations'] = []

if response_payload['successes']:
# Invalidate the default enterprise enrollment intentions and enterprise course enrollments cache
# as the previously redeemable enrollment intentions have been processed/enrolled.
self.invalidate_default_enrollment_intentions_cache()
self.invalidate_enrollments_cache()

for enrollment in response_payload['successes']:
course_run_key = enrollment.get('course_run_key')
self.context.data['default_enterprise_enrollment_realizations'].append({
'course_key': course_run_key,
'enrollment_status': 'enrolled',
'subscription_license_uuid': license_uuids_by_course_run_key.get(course_run_key),
})

def _request_default_enrollment_realizations(self, license_uuids_by_course_run_key):
"""
Sends the request to bulk enroll into default enrollment intentions via the LMS
API client.
"""
bulk_enrollment_payload = []
for course_run_key, license_uuid in license_uuids_by_course_run_key.items():
bulk_enrollment_payload.append({
Expand All @@ -470,34 +499,21 @@ def enroll_in_redeemable_default_enterprise_enrollment_intentions(self):
user_message='There was an exception realizing default enrollments',
developer_message=f'Default realization enrollment exception: {exc}',
)
response_payload = {}

if failures := response_payload.get('failures'):
self.add_error(
user_message='There were failures realizing default enrollments',
developer_message='Default realization enrollment failures: ' + json.dumps(failures),
)

if not self.context.data.get('default_enterprise_enrollment_realizations'):
self.context.data['default_enterprise_enrollment_realizations'] = []
return response_payload

for enrollment in response_payload['successes']:
course_run_key = enrollment.get('course_run_key')
self.context.data['default_enterprise_enrollment_realizations'].append({
'course_key': course_run_key,
'enrollment_status': 'enrolled',
'subscription_license_uuid': license_uuids_by_course_run_key.get(course_run_key),
})
def invalidate_default_enrollment_intentions_cache(self):
invalidate_default_enterprise_enrollment_intentions_learner_status_cache(
enterprise_customer_uuid=self.context.enterprise_customer_uuid,
lms_user_id=self.context.lms_user_id,
)

# Invalidate the default enterprise enrollment intentions and enterprise course enrollments cache
# as the previously redeemable enrollment intentions have been processed/enrolled.
invalidate_default_enterprise_enrollment_intentions_learner_status_cache(
enterprise_customer_uuid=self.context.enterprise_customer_uuid,
lms_user_id=self.context.lms_user_id,
)
invalidate_enterprise_course_enrollments_cache(
enterprise_customer_uuid=self.context.enterprise_customer_uuid,
lms_user_id=self.context.lms_user_id,
)
def invalidate_enrollments_cache(self):
invalidate_enterprise_course_enrollments_cache(
enterprise_customer_uuid=self.context.enterprise_customer_uuid,
lms_user_id=self.context.lms_user_id,
)


class DashboardHandler(BaseLearnerPortalHandler):
Expand Down
148 changes: 148 additions & 0 deletions enterprise_access/apps/bffs/tests/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,154 @@ def test_load_and_process_staff_enterprise_customer(
expected_staff_enterprise_customer = self.expected_enterprise_customer
self.assertEqual(actual_staff_enterprise_customer, expected_staff_enterprise_customer)

@mock.patch('enterprise_access.apps.api_client.lms_client.LmsUserApiClient.get_enterprise_customers_for_user')
@mock.patch('enterprise_access.apps.api_client.lms_client.LmsApiClient.bulk_enroll_enterprise_learners')
def test_request_default_enrollment_realizations(self, mock_bulk_enroll, mock_get_customers):
mock_get_customers.return_value = {
**self.mock_enterprise_learner_response_data,
'results': [],
}
license_uuids_by_course_run_key = {
'course-run-1': 'license-1',
'course-run-2': 'license-2',
}
context = HandlerContext(self.request)
handler = BaseLearnerPortalHandler(context)

response = handler._request_default_enrollment_realizations(license_uuids_by_course_run_key)

self.assertEqual(response, mock_bulk_enroll.return_value)
actual_customer_uuid_arg, actual_payload_arg = mock_bulk_enroll.call_args_list[0][0]
self.assertEqual(actual_customer_uuid_arg, context.enterprise_customer_uuid)
expected_payload = [
{'user_id': context.lms_user_id, 'course_run_key': 'course-run-1',
'license_uuid': 'license-1', 'is_default_auto_enrollment': True},
{'user_id': context.lms_user_id, 'course_run_key': 'course-run-2',
'license_uuid': 'license-2', 'is_default_auto_enrollment': True},
]
self.assertCountEqual(expected_payload, actual_payload_arg)
self.assertEqual(context.errors, [])

@mock.patch('enterprise_access.apps.api_client.lms_client.LmsUserApiClient.get_enterprise_customers_for_user')
@mock.patch('enterprise_access.apps.api_client.lms_client.LmsApiClient.bulk_enroll_enterprise_learners')
def test_request_default_enrollment_realizations_exception(self, mock_bulk_enroll, mock_get_customers):
mock_get_customers.return_value = {
**self.mock_enterprise_learner_response_data,
'results': [],
}
license_uuids_by_course_run_key = {
'course-run-1': 'license-1',
'course-run-2': 'license-2',
}
context = HandlerContext(self.request)
handler = BaseLearnerPortalHandler(context)
mock_bulk_enroll.side_effect = Exception('foobar')

response = handler._request_default_enrollment_realizations(license_uuids_by_course_run_key)

self.assertEqual(response, {})
self.assertEqual(
context.errors,
[{
'developer_message': 'Default realization enrollment exception: foobar',
'user_message': 'There was an exception realizing default enrollments',
}],
)

@mock.patch(
'enterprise_access.apps.api_client.lms_client.LmsUserApiClient'
'.get_enterprise_customers_for_user')
@mock.patch(
'enterprise_access.apps.api_client.lms_client.LmsApiClient'
'.bulk_enroll_enterprise_learners')
@mock.patch(
'enterprise_access.apps.api_client.lms_client.LmsUserApiClient'
'.get_default_enterprise_enrollment_intentions_learner_status'
)
def test_realize_default_enrollments(
self, mock_get_intentions, mock_bulk_enroll, mock_get_customers
):
mock_get_customers.return_value = {
**self.mock_enterprise_learner_response_data,
'results': [],
}
mock_get_intentions.return_value = {
"lms_user_id": self.mock_user.id,
"user_email": self.mock_user.email,
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enrollment_statuses": {
"needs_enrollment": {
"enrollable": [
{
'applicable_enterprise_catalog_uuids': ['catalog-55', 'catalog-1'],
'course_run_key': 'course-run-1',
},
{
'applicable_enterprise_catalog_uuids': ['catalog-88', 'catalog-1'],
'course_run_key': 'course-run-2',
},
],
"not_enrollable": [],
},
'already_enrolled': [],
},
}
mock_bulk_enroll.return_value = {
'successes': [
{'course_run_key': 'course-run-1'},
],
'failures': [
{'course_run_key': 'course-run-2'},
],
}

context = HandlerContext(self.request)
context.data['enterprise_customer_user_subsidies'] = {
'subscriptions': {
'subscription_licenses_by_status': {
'activated': [{
'uuid': 'license-1',
'subscription_plan': {
'is_current': True,
'uuid': 'subscription-plan-1',
'enterprise_catalog_uuid': 'catalog-1',
},
}]
}
}
}
handler = BaseLearnerPortalHandler(context)

handler.load_default_enterprise_enrollment_intentions()
handler.enroll_in_redeemable_default_enterprise_enrollment_intentions()

actual_customer_uuid_arg, actual_payload_arg = mock_bulk_enroll.call_args_list[0][0]
self.assertEqual(actual_customer_uuid_arg, context.enterprise_customer_uuid)
expected_payload = [
{'user_id': context.lms_user_id, 'course_run_key': 'course-run-1',
'license_uuid': 'license-1', 'is_default_auto_enrollment': True},
{'user_id': context.lms_user_id, 'course_run_key': 'course-run-2',
'license_uuid': 'license-1', 'is_default_auto_enrollment': True},
]
self.assertCountEqual(expected_payload, actual_payload_arg)
self.assertEqual(
handler.context.data['default_enterprise_enrollment_realizations'],
[{
'course_key': 'course-run-1',
'enrollment_status': 'enrolled',
'subscription_license_uuid': 'license-1',
}],
)
self.assertEqual(
handler.context.errors,
[{
'developer_message': (
'Default realization enrollment failures: [{"course_run_key": "course-run-2"}]'
),
'user_message': 'There were failures realizing default enrollments',
}],
)


class TestDashboardHandler(TestHandlerContextMixin):
"""
Expand Down

0 comments on commit 0995768

Please sign in to comment.