From e5aa30b0303ea89513926e243e6fa7233c4e4cd8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 17 Dec 2024 10:00:24 -0500 Subject: [PATCH] feat: expose enterprise.learner_bff_enabled Waffle flag (#2306) --- CHANGELOG.rst | 8 +++- enterprise/__init__.py | 2 +- enterprise/toggles.py | 20 +++++++++ tests/test_enterprise/api/test_filters.py | 1 + tests/test_enterprise/api/test_views.py | 49 ++++++++++++++--------- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a474efecb..58c97197b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,17 +17,21 @@ Unreleased ---------- * nothing unreleased +[5.5.0] +------- +* feat: introduce Waffle flag for enabling the Learner Portal BFF API. + [5.4.2] -------- * feat: Added a management command to update the Social Auth UID's for an enterprise. [5.4.1] --------- +------- * fix: The default enrollment ``learner_status`` view now considers intended courses from which the requested user has unenrolled as no-longer realizable. [5.4.0] --------- +------- * chore: Update python requirements. [5.3.1] diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 4202621e2..961aea59c 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "5.4.2" +__version__ = "5.5.0" diff --git a/enterprise/toggles.py b/enterprise/toggles.py index 003e5618b..23ff16102 100644 --- a/enterprise/toggles.py +++ b/enterprise/toggles.py @@ -67,6 +67,18 @@ ENTERPRISE_LOG_PREFIX, ) +# .. toggle_name: enterprise.enterprise_learner_bff_enabled +# .. toggle_implementation: WaffleFlag +# .. toggle_default: False +# .. toggle_description: Enables the enterprise learner BFF +# .. toggle_use_cases: open_edx +# .. toggle_creation_date: 2024-12-16 +ENTERPRISE_LEARNER_BFF_ENABLED = WaffleFlag( + f'{ENTERPRISE_NAMESPACE}.learner_bff_enabled', + __name__, + ENTERPRISE_LOG_PREFIX, +) + def top_down_assignment_real_time_lcm(): """ @@ -103,6 +115,13 @@ def enterprise_customer_support_tool(): return ENTERPRISE_CUSTOMER_SUPPORT_TOOL.is_enabled() +def enterprise_learner_bff_enabled(): + """ + Returns whether the enterprise learner BFF is enabled. + """ + return ENTERPRISE_LEARNER_BFF_ENABLED.is_enabled() + + def enterprise_features(): """ Returns a dict of enterprise Waffle-based feature flags. @@ -113,4 +132,5 @@ def enterprise_features(): 'enterprise_groups_v1': enterprise_groups_v1(), 'enterprise_customer_support_tool': enterprise_customer_support_tool(), 'enterprise_groups_v2': enterprise_groups_v2(), + 'enterprise_learner_bff_enabled': enterprise_learner_bff_enabled(), } diff --git a/tests/test_enterprise/api/test_filters.py b/tests/test_enterprise/api/test_filters.py index f4b68efe3..6ab8484b0 100644 --- a/tests/test_enterprise/api/test_filters.py +++ b/tests/test_enterprise/api/test_filters.py @@ -305,6 +305,7 @@ def test_filter(self, is_staff, is_linked_to_enterprise, has_access): 'enterprise_groups_v1': False, 'enterprise_customer_support_tool': False, 'enterprise_groups_v2': False, + 'enterprise_learner_bff_enabled': False, } } assert response == mock_empty_200_success_response diff --git a/tests/test_enterprise/api/test_views.py b/tests/test_enterprise/api/test_views.py index be30cac5d..87e501024 100644 --- a/tests/test_enterprise/api/test_views.py +++ b/tests/test_enterprise/api/test_views.py @@ -73,6 +73,7 @@ ENTERPRISE_CUSTOMER_SUPPORT_TOOL, ENTERPRISE_GROUPS_V1, ENTERPRISE_GROUPS_V2, + ENTERPRISE_LEARNER_BFF_ENABLED, FEATURE_PREQUERY_SEARCH_SUGGESTIONS, TOP_DOWN_ASSIGNMENT_REAL_TIME_LCM, ) @@ -2018,63 +2019,64 @@ def test_enterprise_customer_support_tool( @ddt.data( # Request missing required permissions query param. (True, False, [], {}, False, {'detail': 'User is not allowed to access the view.'}, - False, False, False, False, False), + False, False, False, False, False, False), # Staff user that does not have the specified group permission. (True, False, [], {'permissions': ['enterprise_enrollment_api_access']}, False, - {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False), + {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False, False), # Staff user that does have the specified group permission. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access']}, - True, None, False, False, False, False, False), + True, None, False, False, False, False, False, False), # Non staff user that is not linked to the enterprise, nor do they have the group permission. (False, False, [], {'permissions': ['enterprise_enrollment_api_access']}, False, - {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False), + {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False, False), # Non staff user that is not linked to the enterprise, but does have the group permission. (False, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access']}, - False, None, False, False, False, False, False), + False, None, False, False, False, False, False, False), # Non staff user that is linked to the enterprise, but does not have the group permission. (False, True, [], {'permissions': ['enterprise_enrollment_api_access']}, False, - {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False), + {'detail': 'User is not allowed to access the view.'}, False, False, False, False, False, False), # Non staff user that is linked to the enterprise and does have the group permission (False, True, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access']}, - True, None, False, False, False, False, False), + True, None, False, False, False, False, False, False), # Non staff user that is linked to the enterprise and has group permission and the request has passed # multiple groups to check. (False, True, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access', 'enterprise_data_api_access']}, True, None, False, - False, False, False, False), + False, False, False, False, False), # Staff user with group permission filtering on non existent enterprise id. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'enterprise_id': FAKE_UUIDS[1]}, False, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permission filtering on enterprise id successfully. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'enterprise_id': FAKE_UUIDS[0]}, True, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permission filtering on search param with no results. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'search': 'blah'}, False, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permission filtering on search param with results. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'search': 'test'}, True, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permission filtering on slug with results. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'slug': TEST_SLUG}, True, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permissions filtering on slug with no results. (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'slug': 'blah'}, False, - None, False, False, False, False, False), + None, False, False, False, False, False, False), # Staff user with group permission filtering on slug with results, with # top down assignment & real-time LCM feature enabled, # prequery search results enabled and # enterprise groups v1 feature enabled # enterprise groups v2 feature enabled # enterprise customer support tool enabled + # enterprise learner bff enabled (True, False, ['enterprise_enrollment_api_access'], {'permissions': ['enterprise_enrollment_api_access'], 'slug': TEST_SLUG}, True, - None, True, True, True, True, True), + None, True, True, True, True, True, True), ) @ddt.unpack @mock.patch('enterprise.utils.get_logo_url') @@ -2090,7 +2092,8 @@ def test_enterprise_customer_with_access_to( feature_prequery_search_suggestions_enabled, enterprise_groups_v1_enabled, enterprise_groups_v2_enabled, - enterprise_customer_support_tool, + enterprise_customer_support_tool_enabled, + enterprise_learner_bff_enabled, mock_get_logo_url, ): """ @@ -2156,7 +2159,6 @@ def test_enterprise_customer_with_access_to( ENTERPRISE_GROUPS_V1, active=enterprise_groups_v1_enabled ): - response = client.get( f"{settings.TEST_SERVER}{ENTERPRISE_CUSTOMER_WITH_ACCESS_TO_ENDPOINT}?{urlencode(query_params, True)}" ) @@ -2169,9 +2171,15 @@ def test_enterprise_customer_with_access_to( ) with override_waffle_flag( ENTERPRISE_CUSTOMER_SUPPORT_TOOL, - active=enterprise_customer_support_tool + active=enterprise_customer_support_tool_enabled + ): + response = client.get( + f"{settings.TEST_SERVER}{ENTERPRISE_CUSTOMER_WITH_ACCESS_TO_ENDPOINT}?{urlencode(query_params, True)}" + ) + with override_waffle_flag( + ENTERPRISE_LEARNER_BFF_ENABLED, + active=enterprise_learner_bff_enabled ): - response = client.get( f"{settings.TEST_SERVER}{ENTERPRISE_CUSTOMER_WITH_ACCESS_TO_ENDPOINT}?{urlencode(query_params, True)}" ) @@ -2243,8 +2251,9 @@ def test_enterprise_customer_with_access_to( 'top_down_assignment_real_time_lcm': is_top_down_assignment_real_time_lcm_enabled, 'feature_prequery_search_suggestions': feature_prequery_search_suggestions_enabled, 'enterprise_groups_v1': enterprise_groups_v1_enabled, - 'enterprise_customer_support_tool': enterprise_customer_support_tool, + 'enterprise_customer_support_tool': enterprise_customer_support_tool_enabled, 'enterprise_groups_v2': enterprise_groups_v2_enabled, + 'enterprise_learner_bff_enabled': enterprise_learner_bff_enabled, } } assert response in (expected_error, mock_empty_200_success_response)