diff --git a/enterprise_catalog/apps/api/v1/tests/test_views.py b/enterprise_catalog/apps/api/v1/tests/test_views.py index 671f5ddfb..b7290683d 100644 --- a/enterprise_catalog/apps/api/v1/tests/test_views.py +++ b/enterprise_catalog/apps/api/v1/tests/test_views.py @@ -44,9 +44,6 @@ get_parent_content_key, localized_utcnow, ) -from enterprise_catalog.apps.catalog.waffle import ( - LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG, -) @ddt.ddt @@ -1476,11 +1473,7 @@ def test_get_content_metadata_no_nested_enrollment_urls_exec_ed_2u( metadata = course_runs + [course] self.add_metadata_to_catalog(self.enterprise_catalog, metadata) - with override_waffle_flag( - LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG, - active=is_learner_portal_enabled, - ): - response = self.client.get(self._get_content_metadata_url(self.enterprise_catalog)) + response = self.client.get(self._get_content_metadata_url(self.enterprise_catalog)) self.maxDiff = None self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/enterprise_catalog/apps/api_client/enterprise_cache.py b/enterprise_catalog/apps/api_client/enterprise_cache.py index a8bbaa353..be680b067 100644 --- a/enterprise_catalog/apps/api_client/enterprise_cache.py +++ b/enterprise_catalog/apps/api_client/enterprise_cache.py @@ -52,14 +52,6 @@ def slug(self): """ return self.customer_data.get('slug', '') - @property - def active_catalogs(self): - """ - Return catalogs associated with active coupon code and subscription catalogs for the enterprise customer. - """ - catalogs = self.customer_data.get('coupons_catalogs', []) + self.customer_data.get('subscriptions_catalogs', []) - return list(set(catalogs)) - @property def last_modified_date(self): """ @@ -94,38 +86,6 @@ def _get_enterprise_customer_data(uuid): logger.warning('Received unexpected customer_data for enterprise customer %s', uuid) customer_data = {} - try: - ecommerce_client = EcommerceApiClient() - coupons_overview = ecommerce_client.get_coupons_overview(uuid) - coupons_catalogs = [coupon['enterprise_catalog_uuid'] for coupon in coupons_overview] - except requests.exceptions.RequestException as exc: - logger.error( - 'Failed to fetch coupons overview for %r because %r', - uuid, - exc, - ) - coupons_catalogs = [] - - try: - license_manager_client = LicenseManagerApiClient() - customer_agreement = license_manager_client.get_customer_agreement(uuid) - if customer_agreement: - subscriptions_catalogs = [ - subscription['enterprise_catalog_uuid'] for subscription in customer_agreement['subscriptions'] - ] - else: - subscriptions_catalogs = [] - except requests.exceptions.RequestException as exc: - logger.error( - 'Failed to fetch customer agreement for %r because %r', - uuid, - exc, - ) - subscriptions_catalogs = [] - - customer_data['coupons_catalogs'] = coupons_catalogs - customer_data['subscriptions_catalogs'] = subscriptions_catalogs - cache.set(cache_key, customer_data, settings.ENTERPRISE_CUSTOMER_CACHE_TIMEOUT) return customer_data diff --git a/enterprise_catalog/apps/catalog/models.py b/enterprise_catalog/apps/catalog/models.py index 5b1b7f714..f5f24dcdb 100644 --- a/enterprise_catalog/apps/catalog/models.py +++ b/enterprise_catalog/apps/catalog/models.py @@ -48,9 +48,6 @@ get_parent_content_key, localized_utcnow, ) -from enterprise_catalog.apps.catalog.waffle import ( - use_learner_portal_for_all_subsidies_content_types, -) LOGGER = getLogger(__name__) @@ -398,11 +395,7 @@ def get_content_enrollment_url(self, content_metadata): if self.publish_audit_enrollment_urls: params['audit'] = 'true' - use_learner_portal_for_all = use_learner_portal_for_all_subsidies_content_types() - can_enroll_with_learner_portal = self._can_enroll_via_learner_portal( - content_key, - is_learner_portal_enabled_for_all_subsidies_content_types=use_learner_portal_for_all - ) + can_enroll_with_learner_portal = self._can_enroll_via_learner_portal if content_metadata.is_exec_ed_2u_course: if not self.catalog_query.include_exec_ed_2u_courses: @@ -411,10 +404,9 @@ def get_content_enrollment_url(self, content_metadata): exec_ed_enroll_url, exec_ed_entitlement_sku = self._get_exec_ed_2u_enrollment_url( content_metadata, enterprise_slug=self.enterprise_customer.slug, - use_learner_portal=(can_enroll_with_learner_portal - and use_learner_portal_for_all), + use_learner_portal=can_enroll_with_learner_portal, ) - if can_enroll_with_learner_portal and use_learner_portal_for_all: + if can_enroll_with_learner_portal: return update_query_parameters(exec_ed_enroll_url, params) if not exec_ed_entitlement_sku: @@ -472,52 +464,14 @@ def _get_exec_ed_2u_enrollment_url(self, content_metadata, enterprise_slug, use_ entitlement_sku, ) - def _can_enroll_via_learner_portal(self, content_key, is_learner_portal_enabled_for_all_subsidies_content_types): + @property + def _can_enroll_via_learner_portal(self): """ - Check whether the enterprise customer has the learner portal enabled. Note that enterprise - offers were previously only partially supported by the learner portal (i.e., it did not - support per-learner spend or enrollment limits). As a result, we had to avoid the learner - portal as an enrollment url for enterprise customers who had the learner portal enabled - for other subsidy types like a subscription but with at least one enterprise offer with a - per-learner limit. - - Now, the learner portal does support all enterprise offer configurations so we no longer - need to check against the specific enterprise customer exclusion list via the setting - `INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS`. To bypass the existing behavior during - this transition, the `use_learner_portal_for_all_subsidies_content_types` kwarg may be set - to True (e.g., based on a Waffle flag). - - If `use_learner_portal_for_all_subsidies_content_types` is False, falls back to existing behavior - of checking whether the enterprise customer is in `INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS` - settings list and, if so, check if the enterprise customer has any non-offer related catalogs (e.g., - subscription license) containing the specified content key, in which case the learner portal is - supported. + Check whether the enterprise customer has the learner portal enabled. """ if not self.enterprise_customer.learner_portal_enabled: return False - - # If the waffle flag is active, we want to allow enrollment via the learner portal. - if is_learner_portal_enabled_for_all_subsidies_content_types: - return True - - # Otherwise, the waffle flag is inactive; fall back to current state where we check - # against `settings.INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS`. - is_integrated_customer_with_offer_and_nonoffer_subsidies = ( - str(self.enterprise_uuid) in - settings.INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS - ) - if not is_integrated_customer_with_offer_and_nonoffer_subsidies: - return True - - # Customers in the special `INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS` list - # must have the content_key contained in an active catalog for this method to return True. - active_catalogs = EnterpriseCatalog.objects.filter(uuid__in=self.enterprise_customer.active_catalogs) - for catalog in active_catalogs: - contains_content_items = catalog.contains_content_keys([content_key]) - if contains_content_items: - return True - - return False + return True def get_xapi_activity_id(self, content_resource, content_key): """ diff --git a/enterprise_catalog/apps/catalog/tests/test_models.py b/enterprise_catalog/apps/catalog/tests/test_models.py index 4e693c2fb..1a17241b4 100644 --- a/enterprise_catalog/apps/catalog/tests/test_models.py +++ b/enterprise_catalog/apps/catalog/tests/test_models.py @@ -23,10 +23,6 @@ update_contentmetadata_from_discovery, ) from enterprise_catalog.apps.catalog.tests import factories -from enterprise_catalog.apps.catalog.waffle import ( - LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG, -) - @ddt.ddt class TestModels(TestCase): @@ -324,155 +320,85 @@ def test_contentmetadata_update_from_discovery_ignore_exec_ed(self, mock_client) def _mock_enterprise_customer_cache( self, mock_enterprise_customer_return_value=None, - mock_customer_agreement_return_value=None, - mock_coupon_overview_return_value=None, ): """ Helper to mock out all API client calls that would normally occur when ``EnterpriseCatalog.enterprise_customer`` is accessed. """ path = 'enterprise_catalog.apps.api_client.enterprise_cache.' - with mock.patch(path + 'EnterpriseApiClient') as mock_enterprise_api_client, \ - mock.patch(path + 'LicenseManagerApiClient') as mock_license_manager_client, \ - mock.patch(path + 'EcommerceApiClient') as mock_ecommerce_client: + with mock.patch(path + 'EnterpriseApiClient') as mock_enterprise_api_client: mock_enterprise_api_client.return_value.get_enterprise_customer.return_value = \ mock_enterprise_customer_return_value - mock_ecommerce_client.return_value.get_coupons_overview.return_value = \ - mock_coupon_overview_return_value - mock_license_manager_client.return_value.get_customer_agreement.return_value = \ - mock_customer_agreement_return_value yield @ddt.data( { - 'is_integrated_customer_with_subsidies_and_offer': False, - 'is_course_in_subscriptions_catalog': True, - 'is_course_in_coupons_catalog': True, - 'should_direct_to_lp': True, - 'has_learner_portal_enrollment_flag_enabled': False, - }, - { - 'is_integrated_customer_with_subsidies_and_offer': True, - 'is_course_in_subscriptions_catalog': False, - 'is_course_in_coupons_catalog': False, - 'should_direct_to_lp': False, - 'has_learner_portal_enrollment_flag_enabled': False, - }, - { - 'is_integrated_customer_with_subsidies_and_offer': True, - 'is_course_in_subscriptions_catalog': False, - 'is_course_in_coupons_catalog': False, - 'should_direct_to_lp': True, - 'has_learner_portal_enrollment_flag_enabled': True, + 'is_learner_portal_enabled': True, }, { - 'is_integrated_customer_with_subsidies_and_offer': True, - 'is_course_in_subscriptions_catalog': True, - 'is_course_in_coupons_catalog': False, - 'should_direct_to_lp': True, - 'has_learner_portal_enrollment_flag_enabled': False, + 'is_learner_portal_enabled': False, }, - { - 'is_integrated_customer_with_subsidies_and_offer': True, - 'is_course_in_subscriptions_catalog': False, - 'is_course_in_coupons_catalog': True, - 'should_direct_to_lp': True, - 'has_learner_portal_enrollment_flag_enabled': False, - } ) @ddt.unpack def test_get_content_enrollment_url( self, - is_integrated_customer_with_subsidies_and_offer, - is_course_in_subscriptions_catalog, - is_course_in_coupons_catalog, - should_direct_to_lp, - has_learner_portal_enrollment_flag_enabled, + is_learner_portal_enabled, ): enterprise_uuid = uuid4() enterprise_slug = 'sluggy' content_key = 'course-key' - INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS = [] - if is_integrated_customer_with_subsidies_and_offer: - INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS.append(str(enterprise_uuid)) + enterprise_catalog = factories.EnterpriseCatalogFactory(enterprise_uuid=enterprise_uuid) + content_metadata = factories.ContentMetadataFactory( + content_key=content_key, + content_type=COURSE, + ) + enterprise_catalog.catalog_query.contentmetadata_set.add(*[content_metadata]) + + mock_enterprise_customer_return_value = { + 'slug': enterprise_slug, + 'enable_learner_portal': is_learner_portal_enabled, + } - with self.settings( - INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS=INTEGRATED_CUSTOMERS_WITH_SUBSIDIES_AND_OFFERS - ), override_waffle_flag( - LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG, - active=has_learner_portal_enrollment_flag_enabled + with self._mock_enterprise_customer_cache( + mock_enterprise_customer_return_value, ): - enterprise_catalog = factories.EnterpriseCatalogFactory(enterprise_uuid=enterprise_uuid) - content_metadata = factories.ContentMetadataFactory( - content_key=content_key, - content_type=COURSE, - ) - enterprise_catalog.catalog_query.contentmetadata_set.add(*[content_metadata]) - - mock_enterprise_customer_return_value = { - 'slug': enterprise_slug, - 'enable_learner_portal': True, - } - mock_customer_agreement_return_value = { - 'subscriptions': [{'enterprise_catalog_uuid': enterprise_catalog.uuid}], - } if is_course_in_subscriptions_catalog else None - mock_coupon_overview_return_value = [ - {'enterprise_catalog_uuid': enterprise_catalog.uuid}, - ] if is_course_in_coupons_catalog else [] - - with self._mock_enterprise_customer_cache( - mock_enterprise_customer_return_value, - mock_customer_agreement_return_value, - mock_coupon_overview_return_value, - ): - content_enrollment_url = enterprise_catalog.get_content_enrollment_url(content_metadata) - - if should_direct_to_lp: - assert settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL in content_enrollment_url - else: - assert settings.LMS_BASE_URL in content_enrollment_url + content_enrollment_url = enterprise_catalog.get_content_enrollment_url(content_metadata) + + if is_learner_portal_enabled: + assert settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL in content_enrollment_url + else: + assert settings.LMS_BASE_URL in content_enrollment_url @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.EnterpriseApiClient') - @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.LicenseManagerApiClient') - @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.EcommerceApiClient') @ddt.data( { 'is_learner_portal_enabled': True, - 'is_learner_portal_waffle_flag_enabled': False, 'should_expect_learner_portal_url': False, }, { 'is_learner_portal_enabled': True, - 'is_learner_portal_waffle_flag_enabled': True, 'should_expect_learner_portal_url': True, }, { 'is_learner_portal_enabled': False, - 'is_learner_portal_waffle_flag_enabled': True, 'should_expect_learner_portal_url': False, }, { 'is_learner_portal_enabled': False, - 'is_learner_portal_waffle_flag_enabled': False, - 'should_expect_learner_portal_url': False, + 'should_expect_learner_portal_url': True, }, ) @ddt.unpack def test_enrollment_url_exec_ed( self, - ecommerce_api_client, - license_manager_api_client, mock_enterprise_api_client, is_learner_portal_enabled, - is_learner_portal_waffle_flag_enabled, should_expect_learner_portal_url, ): """ Test that a correct enrollment URL is returned for exec ed. 2U courses. """ - license_manager_api_client.get_customer_agreement.return_value = None - ecommerce_api_client.get_coupons_overview.return_value = [] enterprise_catalog = factories.EnterpriseCatalogFactory() content_metadata = factories.ContentMetadataFactory( content_key='the-content-key', @@ -495,11 +421,7 @@ def test_enrollment_url_exec_ed( mock_enterprise_api_client.return_value.get_enterprise_customer.return_value =\ mock_enterprise_customer_return_value - with override_waffle_flag( - LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG, - active=is_learner_portal_waffle_flag_enabled, - ): - actual_enrollment_url = enterprise_catalog.get_content_enrollment_url(content_metadata) + actual_enrollment_url = enterprise_catalog.get_content_enrollment_url(content_metadata) if should_expect_learner_portal_url: assert settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL in actual_enrollment_url @@ -508,8 +430,6 @@ def test_enrollment_url_exec_ed( assert 'proxy-login' in actual_enrollment_url @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.EnterpriseApiClient') - @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.LicenseManagerApiClient') - @mock.patch('enterprise_catalog.apps.api_client.enterprise_cache.EcommerceApiClient') @ddt.data( {'content_type': COURSE, 'course_type': EXEC_ED_2U_COURSE_TYPE, 'course_mode': 'honor', 'sku': None, 'query_includes_ee_courses': True}, @@ -523,8 +443,6 @@ def test_enrollment_url_exec_ed( @ddt.unpack def test_enrollment_url_exec_ed_is_null( self, - ecommerce_api_client, - license_manager_api_client, mock_enterprise_api_client, content_type, course_type, @@ -539,8 +457,6 @@ def test_enrollment_url_exec_ed_is_null( because the content_type is always "course" and the course_type is always the exec ed 2U course type. """ - license_manager_api_client.get_customer_agreement.return_value = None - ecommerce_api_client.get_coupons_overview.return_value = [] enterprise_slug = 'sluggy' mock_enterprise_customer_return_value = { 'slug': enterprise_slug, diff --git a/enterprise_catalog/apps/catalog/waffle.py b/enterprise_catalog/apps/catalog/waffle.py index 37b4c5fb0..b4def6a0b 100644 --- a/enterprise_catalog/apps/catalog/waffle.py +++ b/enterprise_catalog/apps/catalog/waffle.py @@ -21,22 +21,3 @@ f'{WAFFLE_NAMESPACE}.{DISABLE_MODEL_ADMIN_CHANGES}', module_name=__name__, ) - -# .. toggle_name: catalog.learner_portal_enrollment_all_subsidies_and_content_types -# .. toggle_implementation: WaffleFlag -# .. toggle_default: False -# .. toggle_description: Indicates whether enrollment urls should point to learner portal for all customers, subsidies, and content types for customers with learner portal enabled. -# .. toggle_use_cases: opt_in -# .. toggle_creation_date: 2023-05-15 -LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG = WaffleFlag( - f'{WAFFLE_NAMESPACE}.{LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES}', - module_name=__name__, -) - - -def use_learner_portal_for_all_subsidies_content_types(): - """ - Returns whether enrollments url should point to learner portal for all customers, - subsidies, and content types for customers with learner portal enabled. - """ - return LEARNER_PORTAL_ENROLLMENT_ALL_SUBSIDIES_AND_CONTENT_TYPES_FLAG.is_enabled()