From 291534c4c59fe0ca09defc642d50e3fca13ab34d Mon Sep 17 00:00:00 2001 From: Hamzah Ullah Date: Thu, 23 Jan 2025 20:58:19 +0000 Subject: [PATCH] feat: incorporate enterprise customer logic into BFF --- .../apps/api/v1/tests/test_bff_views.py | 37 +++++++++++++++++-- .../apps/api_client/lms_client.py | 23 ++++++------ enterprise_access/apps/bffs/api.py | 30 +++++++++------ enterprise_access/apps/bffs/context.py | 15 ++++++-- .../apps/bffs/response_builder.py | 7 +++- enterprise_access/apps/bffs/serializers.py | 14 +++++++ .../apps/bffs/tests/test_context.py | 3 ++ .../apps/bffs/tests/test_response_builders.py | 27 ++++++++++++++ enterprise_access/apps/bffs/tests/utils.py | 37 ++++++++++++++++++- 9 files changed, 161 insertions(+), 32 deletions(-) diff --git a/enterprise_access/apps/api/v1/tests/test_bff_views.py b/enterprise_access/apps/api/v1/tests/test_bff_views.py index 4d112fce..0b8d6a6c 100644 --- a/enterprise_access/apps/api/v1/tests/test_bff_views.py +++ b/enterprise_access/apps/api/v1/tests/test_bff_views.py @@ -137,6 +137,27 @@ def setUp(self): # Mock base response data self.mock_common_response_data = { 'enterprise_customer': self.expected_enterprise_customer, + 'all_linked_enterprise_customer_users': [ + { + 'id': 1, + 'active': True, + 'enterprise_customer': self.expected_enterprise_customer, + 'user_id': 3, + }, + { + 'id': 2, + 'active': False, + 'enterprise_customer': { + **self.mock_enterprise_customer_2, + 'disable_search': False, + 'show_integration_warning': True, + }, + 'user_id': 6, + }, + ], + 'active_enterprise_customer': self.expected_enterprise_customer, + 'staff_enterprise_customer': None, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, 'enterprise_customer_user_subsidies': { 'subscriptions': { 'customer_agreement': None, @@ -242,7 +263,6 @@ def test_dashboard_empty_state_with_permissions( expected_response_data = { 'detail': f'Missing: {BFF_READ_PERMISSION}', } - self.assertEqual(response.status_code, expected_status_code) self.assertEqual(response.json(), expected_response_data) @@ -533,7 +553,6 @@ def test_dashboard_with_subscriptions_license_auto_apply( 'system_wide_role': SYSTEM_ENTERPRISE_LEARNER_ROLE, 'context': self.mock_enterprise_customer_uuid, }]) - if is_staff_request_user: # Set the request user as a staff user and mock the enterprise customer response data. self.user.is_staff = True @@ -552,16 +571,24 @@ def test_dashboard_with_subscriptions_license_auto_apply( else [] ) mock_enterprise_customer_with_auto_apply = { - **self.mock_enterprise_customer, + **self.expected_enterprise_customer, 'identity_provider': mock_identity_provider, 'identity_providers': mock_identity_providers, + 'show_integration_warning': bool(identity_provider) } + staff_enterprise_customer = None + active_enterprise_customer = mock_enterprise_customer_with_auto_apply + if is_staff_request_user: + staff_enterprise_customer = mock_enterprise_customer_with_auto_apply + active_enterprise_customer = None mock_linked_enterprise_customer_users = ( [] if is_staff_request_user else [{ + 'id': 1, 'active': True, 'enterprise_customer': mock_enterprise_customer_with_auto_apply, + 'user_id': 3, }] ) mock_enterprise_learner_response_data = { @@ -658,6 +685,10 @@ def test_dashboard_with_subscriptions_license_auto_apply( 'identity_providers': mock_identity_providers, 'show_integration_warning': expected_show_integration_warning, }, + 'all_linked_enterprise_customer_users': mock_linked_enterprise_customer_users, + 'staff_enterprise_customer': staff_enterprise_customer, + 'active_enterprise_customer': active_enterprise_customer, + 'should_update_active_enterprise_customer_user': False, 'enterprise_customer_user_subsidies': { 'subscriptions': { 'customer_agreement': expected_customer_agreement, diff --git a/enterprise_access/apps/api_client/lms_client.py b/enterprise_access/apps/api_client/lms_client.py index 5c54eff8..cfbf5e22 100755 --- a/enterprise_access/apps/api_client/lms_client.py +++ b/enterprise_access/apps/api_client/lms_client.py @@ -45,12 +45,13 @@ class LmsApiClient(BaseOAuthClient): """ API client for calls to the LMS service. """ - enterprise_api_base_url = settings.LMS_URL + '/enterprise/api/v1/' - enterprise_learner_endpoint = enterprise_api_base_url + 'enterprise-learner/' - enterprise_customer_endpoint = enterprise_api_base_url + 'enterprise-customer/' - pending_enterprise_learner_endpoint = enterprise_api_base_url + 'pending-enterprise-learner/' - enterprise_group_membership_endpoint = enterprise_api_base_url + 'enterprise-group/' - pending_enterprise_admin_endpoint = enterprise_api_base_url + 'pending-enterprise-admin/' + enterprise_base_url = settings.LMS_URL + '/enterprise/' + enterprise_api_v1_base_url = enterprise_base_url + 'api/v1/' + enterprise_learner_endpoint = enterprise_api_v1_base_url + 'enterprise-learner/' + enterprise_customer_endpoint = enterprise_api_v1_base_url + 'enterprise-customer/' + pending_enterprise_learner_endpoint = enterprise_api_v1_base_url + 'pending-enterprise-learner/' + enterprise_group_membership_endpoint = enterprise_api_v1_base_url + 'enterprise-group/' + pending_enterprise_admin_endpoint = enterprise_api_v1_base_url + 'pending-enterprise-admin/' def enterprise_customer_url(self, enterprise_customer_uuid): return os.path.join( @@ -60,7 +61,7 @@ def enterprise_customer_url(self, enterprise_customer_uuid): def enterprise_group_endpoint(self, group_uuid): return os.path.join( - self.enterprise_api_base_url + 'enterprise-group/', + self.enterprise_api_v1_base_url + 'enterprise-group/', f"{group_uuid}/", ) @@ -553,12 +554,12 @@ class LmsUserApiClient(BaseUserApiClient): """ API client for user-specific calls to the LMS service. """ - enterprise_api_base_url = f"{settings.LMS_URL}/enterprise/api/v1/" + enterprise_base_url = settings.LMS_URL + "/enterprise/" + enterprise_api_v1_base_url = enterprise_base_url + "api/v1/" enterprise_learner_portal_api_base_url = f"{settings.LMS_URL}/enterprise_learner_portal/api/v1/" - - enterprise_learner_endpoint = f"{enterprise_api_base_url}enterprise-learner/" + enterprise_learner_endpoint = f"{enterprise_api_v1_base_url}enterprise-learner/" default_enterprise_enrollment_intentions_learner_status_endpoint = ( - f'{enterprise_api_base_url}default-enterprise-enrollment-intentions/learner-status/' + f'{enterprise_api_v1_base_url}default-enterprise-enrollment-intentions/learner-status/' ) enterprise_course_enrollments_endpoint = ( f'{enterprise_learner_portal_api_base_url}enterprise_course_enrollments/' diff --git a/enterprise_access/apps/bffs/api.py b/enterprise_access/apps/bffs/api.py index 69263403..463b17c8 100644 --- a/enterprise_access/apps/bffs/api.py +++ b/enterprise_access/apps/bffs/api.py @@ -8,7 +8,7 @@ from enterprise_access.apps.api_client.license_manager_client import LicenseManagerUserApiClient from enterprise_access.apps.api_client.lms_client import LmsApiClient, LmsUserApiClient -from enterprise_access.cache_utils import versioned_cache_key +from enterprise_access.cache_utils import request_cache, versioned_cache_key logger = logging.getLogger(__name__) @@ -41,13 +41,13 @@ def enterprise_course_enrollments_cache_key(enterprise_customer_uuid, lms_user_i return versioned_cache_key('get_enterprise_course_enrollments', enterprise_customer_uuid, lms_user_id) -def get_and_cache_enterprise_customer_users(request, timeout=settings.ENTERPRISE_USER_RECORD_CACHE_TIMEOUT, **kwargs): +def get_and_cache_enterprise_customer_users(request, **kwargs): """ Retrieves and caches enterprise learner data. """ username = request.user.username cache_key = enterprise_customer_users_cache_key(username) - cached_response = TieredCache.get_cached_response(cache_key) + cached_response = request_cache(namespace=REQUEST_CACHE_NAMESPACE).get_cached_response(cache_key) if cached_response.is_found: logger.info( f'enterprise_customer_users cache hit for username {username}' @@ -59,7 +59,11 @@ def get_and_cache_enterprise_customer_users(request, timeout=settings.ENTERPRISE username=username, **kwargs, ) - TieredCache.set_all_tiers(cache_key, response_payload, timeout) + logger.info( + 'Fetched enterprise customer user for username %s', + username, + ) + request_cache(namespace=REQUEST_CACHE_NAMESPACE).set(cache_key, response_payload) return response_payload @@ -258,30 +262,33 @@ def _determine_enterprise_customer_for_display( Determine the enterprise customer user for display. Returns: - The enterprise customer user for display. + tuple(Dict, boolean): The enterprise customer user for display, and a boolean to determine + whether to update the active enterprise customer to the return value. """ + if not enterprise_customer_slug and not enterprise_customer_uuid: # No enterprise customer specified in the request, so return the active enterprise customer - return active_enterprise_customer + return active_enterprise_customer, False # If the requested enterprise does not match the active enterprise customer user's slug/uuid # and there is a linked enterprise customer user for the requested enterprise, return the - # linked enterprise customer. + # linked enterprise customer. By returning true, we are updating the current active enterprise + # customer to the requested_enterprise_customer request_matches_active_enterprise_customer = _request_matches_active_enterprise_customer( active_enterprise_customer=active_enterprise_customer, enterprise_customer_slug=enterprise_customer_slug, enterprise_customer_uuid=enterprise_customer_uuid, ) if not request_matches_active_enterprise_customer and requested_enterprise_customer: - return requested_enterprise_customer + return requested_enterprise_customer, True # If the request user is staff and the requested enterprise does not match the active enterprise # customer user's slug/uuid, return the staff-enterprise customer. if staff_enterprise_customer: - return staff_enterprise_customer + return staff_enterprise_customer, False # Otherwise, return the active enterprise customer. - return active_enterprise_customer + return active_enterprise_customer, False def _request_matches_active_enterprise_customer( @@ -360,7 +367,7 @@ def transform_enterprise_customer_users_data(data, request, enterprise_customer_ enterprise_customer_user_for_requested_customer.get('enterprise_customer') if enterprise_customer_user_for_requested_customer else None ) - enterprise_customer = _determine_enterprise_customer_for_display( + enterprise_customer, should_update_active_enterprise_customer_user = _determine_enterprise_customer_for_display( enterprise_customer_slug=enterprise_customer_slug, enterprise_customer_uuid=enterprise_customer_uuid, active_enterprise_customer=active_enterprise_customer, @@ -373,4 +380,5 @@ def transform_enterprise_customer_users_data(data, request, enterprise_customer_ 'active_enterprise_customer': active_enterprise_customer, 'all_linked_enterprise_customer_users': enterprise_customer_users, 'staff_enterprise_customer': staff_enterprise_customer, + 'should_update_active_enterprise_customer_user': should_update_active_enterprise_customer_user, } diff --git a/enterprise_access/apps/bffs/context.py b/enterprise_access/apps/bffs/context.py index 529ad4e0..8864ecc6 100644 --- a/enterprise_access/apps/bffs/context.py +++ b/enterprise_access/apps/bffs/context.py @@ -102,10 +102,18 @@ def enterprise_customer(self): def active_enterprise_customer(self): return self.data.get('active_enterprise_customer') + @property + def staff_enterprise_customer(self): + return self.data.get('staff_enterprise_customer') + @property def all_linked_enterprise_customer_users(self): return self.data.get('all_linked_enterprise_customer_users') + @property + def should_update_active_enterprise_customer_user(self): + return self.data.get('should_update_active_enterprise_customer_user') + @property def is_request_user_linked_to_enterprise_customer(self): """ @@ -122,10 +130,6 @@ def is_request_user_linked_to_enterprise_customer(self): for enterprise_customer_user in self.all_linked_enterprise_customer_users ) - @property - def staff_enterprise_customer(self): - return self.data.get('staff_enterprise_customer') - def set_status_code(self, status_code): """ Sets the status code for the response. @@ -229,6 +233,9 @@ def _initialize_enterprise_customer_users(self): 'active_enterprise_customer': transformed_data.get('active_enterprise_customer'), 'all_linked_enterprise_customer_users': transformed_data.get('all_linked_enterprise_customer_users', []), 'staff_enterprise_customer': transformed_data.get('staff_enterprise_customer'), + 'should_update_active_enterprise_customer_user': transformed_data.get( + 'should_update_active_enterprise_customer_user', False + ) }) def add_error(self, status_code=None, **kwargs): diff --git a/enterprise_access/apps/bffs/response_builder.py b/enterprise_access/apps/bffs/response_builder.py index eba5fc72..b35b3ddb 100644 --- a/enterprise_access/apps/bffs/response_builder.py +++ b/enterprise_access/apps/bffs/response_builder.py @@ -44,6 +44,12 @@ def build(self): dict: A dictionary containing the response data. """ self.response_data['enterprise_customer'] = self.context.enterprise_customer + self.response_data['all_linked_enterprise_customer_users'] = self.context.all_linked_enterprise_customer_users + self.response_data['active_enterprise_customer'] = self.context.active_enterprise_customer + self.response_data['staff_enterprise_customer'] = self.context.staff_enterprise_customer + self.response_data['should_update_active_enterprise_customer_user'] = ( + self.context.should_update_active_enterprise_customer_user + ) self.response_data['enterprise_features'] = self.context.enterprise_features return self.response_data, self.status_code @@ -121,7 +127,6 @@ def build(self): 'enterprise_course_enrollments': self.enterprise_course_enrollments, 'all_enrollments_by_status': self.all_enrollments_by_status, }) - # Serialize and validate the response try: serializer = LearnerDashboardResponseSerializer(data=self.response_data) diff --git a/enterprise_access/apps/bffs/serializers.py b/enterprise_access/apps/bffs/serializers.py index dc6e3262..1dd54b14 100644 --- a/enterprise_access/apps/bffs/serializers.py +++ b/enterprise_access/apps/bffs/serializers.py @@ -152,12 +152,26 @@ class EnterpriseCustomerSerializer(BaseBffSerializer): show_integration_warning = serializers.BooleanField() +class EnterpriseCustomerUserSerializer(BaseBffSerializer): + """ + Serializer for all linked enterprise customer users + """ + id = serializers.IntegerField() + user_id = serializers.IntegerField() + enterprise_customer = EnterpriseCustomerSerializer() + active = serializers.BooleanField() + + class BaseResponseSerializer(BaseBffSerializer): """ Serializer for base response. """ enterprise_customer = EnterpriseCustomerSerializer(required=False, allow_null=True) + all_linked_enterprise_customer_users = EnterpriseCustomerUserSerializer(many=True, allow_empty=True, default=list) + active_enterprise_customer = EnterpriseCustomerSerializer(required=False, allow_null=True) + staff_enterprise_customer = EnterpriseCustomerSerializer(required=False, allow_null=True) + should_update_active_enterprise_customer_user = serializers.BooleanField() errors = ErrorSerializer(many=True, required=False, default=list) warnings = WarningSerializer(many=True, required=False, default=list) enterprise_features = serializers.DictField(required=False, default=dict) diff --git a/enterprise_access/apps/bffs/tests/test_context.py b/enterprise_access/apps/bffs/tests/test_context.py index dc6e6e88..33b63473 100644 --- a/enterprise_access/apps/bffs/tests/test_context.py +++ b/enterprise_access/apps/bffs/tests/test_context.py @@ -51,6 +51,7 @@ def test_handler_context_init(self, mock_get_enterprise_customers_for_user, rais 'enterprise_customer': self.mock_enterprise_customer_2, } ], + 'should_update_active_enterprise_customer_user': False, } self.assertEqual(context.data, expected_data) @@ -125,11 +126,13 @@ def test_handler_context_init_staff_user_unlinked( 'active_enterprise_customer': None, 'staff_enterprise_customer': self.mock_enterprise_customer, 'all_linked_enterprise_customer_users': [], + 'should_update_active_enterprise_customer_user': False, } if raises_exception: expected_data.update({ 'enterprise_customer': None, 'staff_enterprise_customer': None, + 'should_update_active_enterprise_customer_user': False, }) self.assertEqual(context.data, expected_data) expected_errors = ( diff --git a/enterprise_access/apps/bffs/tests/test_response_builders.py b/enterprise_access/apps/bffs/tests/test_response_builders.py index a61590d9..863aae36 100644 --- a/enterprise_access/apps/bffs/tests/test_response_builders.py +++ b/enterprise_access/apps/bffs/tests/test_response_builders.py @@ -1,4 +1,5 @@ from unittest import mock +from unittest.mock import MagicMock import ddt from rest_framework import status @@ -22,6 +23,10 @@ class TestBaseResponseBuilder(TestHandlerContextMixin): def test_base_build_error(self, mock_handler_context): mock_context_data = { 'enterprise_customer': self.mock_enterprise_customer, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, } mock_handler_context.return_value = self.get_mock_handler_context( data=mock_context_data, @@ -32,6 +37,10 @@ def test_base_build_error(self, mock_handler_context): expected_response_data = { 'enterprise_customer': self.mock_enterprise_customer, 'enterprise_features': {'feature_flag': True}, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, } self.assertEqual(response_data, expected_response_data) self.assertEqual(status_code, status.HTTP_200_OK) @@ -59,6 +68,10 @@ def test_base_build_error(self, mock_handler_context): def test_add_errors_warnings_to_response(self, mock_handler_context, errors, warnings): mock_context_data = { 'enterprise_customer': self.mock_enterprise_customer, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, } mock_handler_context.return_value = self.get_mock_handler_context( data=mock_context_data, @@ -68,6 +81,10 @@ def test_add_errors_warnings_to_response(self, mock_handler_context, errors, war expected_output = { 'enterprise_customer': self.mock_enterprise_customer, 'enterprise_features': {'feature_flag': True}, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, 'errors': [], 'warnings': [], } @@ -80,6 +97,8 @@ def test_add_errors_warnings_to_response(self, mock_handler_context, errors, war expected_output['warnings'] = [self.mock_warning] base_response_builder.add_errors_warnings_to_response() response_data, _ = base_response_builder.build() + # Usage in test: + differences = find_dict_differences(response_data, expected_output) self.assertEqual(response_data, expected_output) # TODO Revisit this function in ENT-9633 to determine if 200 is ok for a nested errored response @@ -129,6 +148,10 @@ def setUp(self): def test_build(self, mock_handler_context, has_subscriptions_data): mock_context_data = { 'enterprise_customer': self.mock_enterprise_customer, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, } mock_handler_context.return_value = self.get_mock_handler_context( data=mock_context_data, @@ -165,6 +188,10 @@ def test_build(self, mock_handler_context, has_subscriptions_data): 'enterprise_customer_user_subsidies': { 'subscriptions': mock_subscriptions_data, }, + 'staff_enterprise_customer': self.mock_staff_enterprise_customer, + 'active_enterprise_customer': self.mock_active_enterprise_customer, + 'all_linked_enterprise_customer_users': self.mock_all_linked_enterprise_customer_users, + 'should_update_active_enterprise_customer_user': self.mock_should_update_active_enterprise_customer_user, 'errors': [], 'warnings': [], } diff --git a/enterprise_access/apps/bffs/tests/utils.py b/enterprise_access/apps/bffs/tests/utils.py index 551b2484..366398e5 100644 --- a/enterprise_access/apps/bffs/tests/utils.py +++ b/enterprise_access/apps/bffs/tests/utils.py @@ -7,8 +7,10 @@ from faker import Faker from rest_framework import status +from enterprise_access.apps.api_client.tests.test_constants import DATE_FORMAT_ISO_8601, DATE_FORMAT_ISO_8601_MS from enterprise_access.apps.content_assignments.tests.test_utils import mock_course_run_1 from enterprise_access.apps.core.tests.factories import UserFactory +from enterprise_access.utils import _days_from_now class TestHandlerContextMixin(TestCase): @@ -108,6 +110,19 @@ def setUp(self): 'reply_to': None, 'sender_alias': None, } + self.mock_active_enterprise_customer = { + **self.mock_enterprise_customer + } + self.mock_all_linked_enterprise_customer_users = [{ + 'id': 1, + 'user_id': 3, + 'enterprise_customer': self.mock_enterprise_customer, + 'active': self.mock_enterprise_customer.get('active'), + }] + self.mock_staff_enterprise_customer = { + **self.mock_enterprise_customer, + } + self.mock_should_update_active_enterprise_customer_user = False self.mock_enterprise_customer_2 = { **self.mock_enterprise_customer, 'uuid': self.mock_enterprise_customer_uuid_2, @@ -117,12 +132,16 @@ def setUp(self): self.mock_enterprise_learner_response_data = { 'results': [ { + 'id': 1, 'active': True, 'enterprise_customer': self.mock_enterprise_customer, + 'user_id': 3, }, { + 'id': 2, 'active': False, 'enterprise_customer': self.mock_enterprise_customer_2, + 'user_id': 6, }, ], 'enterprise_features': {'feature_flag': True} @@ -162,6 +181,18 @@ def get_mock_handler_context(self, **kwargs): # Define a dictionary of private attributes to property names mock_property_enterprise_customer = getattr(mock_handler_context, 'data').get('enterprise_customer') + mock_linked_enterprise_customer_users = getattr(mock_handler_context, 'data').get( + 'all_linked_enterprise_customer_users' + ) + mock_staff_enterprise_customer = getattr(mock_handler_context, 'data').get( + 'staff_enterprise_customer' + ) + mock_active_enterprise_customer = getattr(mock_handler_context, 'data').get( + 'active_enterprise_customer' + ) + mock_should_update_active_enterprise_customer_user = getattr(mock_handler_context, 'data').get( + 'should_update_active_enterprise_customer_user' + ) property_mocks = { 'request': getattr(mock_handler_context, '_request'), 'status_code': getattr(mock_handler_context, '_status_code'), @@ -170,10 +201,12 @@ def get_mock_handler_context(self, **kwargs): 'enterprise_customer_uuid': getattr(mock_handler_context, '_enterprise_customer_uuid'), 'enterprise_customer_slug': getattr(mock_handler_context, '_enterprise_customer_slug'), 'enterprise_customer': mock_property_enterprise_customer, - 'active_enterprise_customer': mock_property_enterprise_customer, - 'staff_enterprise_customer': None, + 'active_enterprise_customer': mock_active_enterprise_customer, + 'staff_enterprise_customer': mock_staff_enterprise_customer, 'lms_user_id': getattr(mock_handler_context, '_lms_user_id'), 'enterprise_features': getattr(mock_handler_context, '_enterprise_features'), + 'all_linked_enterprise_customer_users': mock_linked_enterprise_customer_users, + 'should_update_active_enterprise_customer_user': mock_should_update_active_enterprise_customer_user, } # Override the property getters