From cee09542748623af397ec16da1c61720a5e9f6b0 Mon Sep 17 00:00:00 2001 From: hamzawaleed01 Date: Tue, 11 Jun 2024 16:59:09 +0500 Subject: [PATCH 1/2] feat: add list endpoint for SubscriptionPlan --- .../apps/api/v1/tests/test_views.py | 62 +++++++++++++++++++ license_manager/apps/api/v1/views.py | 1 + 2 files changed, 63 insertions(+) diff --git a/license_manager/apps/api/v1/tests/test_views.py b/license_manager/apps/api/v1/tests/test_views.py index 5c034236..0559573b 100644 --- a/license_manager/apps/api/v1/tests/test_views.py +++ b/license_manager/apps/api/v1/tests/test_views.py @@ -254,6 +254,16 @@ def _provision_license_create_request(api_client, user, params): url = '/api/v1/provisioning-admins/subscriptions' return api_client.post(url, params) +def _provision_license_list_request(api_client, user): + """ + Helper method that creates a SubscriptionPlan. + """ + if user: + api_client.force_authenticate(user=user) + + url = '/api/v1/provisioning-admins/subscriptions' + return api_client.get(url) + def _subscription_get_request(api_client, user, subscription_uuid): """ @@ -908,6 +918,58 @@ def test_subscription_plan_create_staff_user_403(api_client, staff_user, boolean assert status.HTTP_403_FORBIDDEN == response.status_code +@pytest.mark.django_db +def test_subscription_plan_list_staff_user_403(api_client, staff_user, boolean_toggle): + """ + Verify that the subcription POST endpoint is accessible to authorised users only + """ + enterprise_customer_uuid = uuid4() + ProductFactory.create_batch(1) + _assign_role_via_jwt_or_db( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid, assign_via_jwt=boolean_toggle) + + response = _provision_license_list_request( + api_client, staff_user) + assert status.HTTP_403_FORBIDDEN == response.status_code + + +@pytest.mark.django_db +def test_subscription_plan_provisioning_admins_list_staff_user_200(api_client, staff_user, boolean_toggle): + """ + Verify that the subcription POST endpoint is accessible to authorised users only + """ + enterprise_customer_uuid = uuid4() + customer_agreement = CustomerAgreementFactory.create( + enterprise_customer_uuid=enterprise_customer_uuid) + ProductFactory.create_batch(1) + allowed_group = Group.objects.create(name=PROVISIONING_ADMINS_GROUP) + staff_user.groups.add(allowed_group) + _assign_role_via_jwt_or_db( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid, assign_via_jwt=boolean_toggle) + + params = _prepare_subscription_plan_payload(customer_agreement) + + _provision_license_create_request( + api_client, staff_user, params=params) + + response = _provision_license_list_request( + api_client, staff_user) + + expected_keys = {'count', 'next', 'previous', 'results'} + assert expected_keys.issubset(response.json().keys()) + expected_result_keys = { + 'title', 'uuid', 'start_date', 'expiration_date', + 'enterprise_customer_uuid', 'enterprise_catalog_uuid', + 'is_active', 'is_revocation_cap_enabled', 'days_until_expiration', + 'days_until_expiration_including_renewals', + 'is_locked_for_renewal_processing', 'should_auto_apply_licenses', + 'licenses', 'revocations', 'prior_renewals' + } + for result in response.json()['results']: + assert expected_result_keys.issubset(result.keys()) + assert status.HTTP_200_OK == response.status_code + + @pytest.mark.django_db def test_subscription_plan_update_staff_user_403(api_client, staff_user, boolean_toggle): """ diff --git a/license_manager/apps/api/v1/views.py b/license_manager/apps/api/v1/views.py index 99376be9..e00b3b4f 100644 --- a/license_manager/apps/api/v1/views.py +++ b/license_manager/apps/api/v1/views.py @@ -426,6 +426,7 @@ def base_queryset(self): class SubscriptionPlanProvisioningAdminViewset( mixins.CreateModelMixin, + mixins.ListModelMixin, viewsets.GenericViewSet ): """ Viewset for Provisioning Admins write operations.""" From b52133611d7b1cd9cfe5fa63691a453e9ca53ac6 Mon Sep 17 00:00:00 2001 From: hamzawaleed01 Date: Wed, 12 Jun 2024 13:03:39 +0500 Subject: [PATCH 2/2] feat: take enterprise_customer_uuid in list query params and to filter --- .../apps/api/v1/tests/test_views.py | 53 ++++++++++++++++++- license_manager/apps/api/v1/views.py | 21 ++++++-- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/license_manager/apps/api/v1/tests/test_views.py b/license_manager/apps/api/v1/tests/test_views.py index 3ea52d65..a00aa38f 100644 --- a/license_manager/apps/api/v1/tests/test_views.py +++ b/license_manager/apps/api/v1/tests/test_views.py @@ -254,7 +254,8 @@ def _provision_license_create_request(api_client, user, params): url = '/api/v1/provisioning-admins/subscriptions' return api_client.post(url, params) -def _provision_license_list_request(api_client, user): + +def _provision_license_list_request(api_client, user, enterprise_customer_uuid=None): """ Helper method that creates a SubscriptionPlan. """ @@ -262,6 +263,8 @@ def _provision_license_list_request(api_client, user): api_client.force_authenticate(user=user) url = '/api/v1/provisioning-admins/subscriptions' + if enterprise_customer_uuid: + url += f'?enterprise_customer_uuid={enterprise_customer_uuid}' return api_client.get(url) @@ -968,6 +971,7 @@ def test_subscription_plan_list_staff_user_403(api_client, staff_user, boolean_t def test_subscription_plan_provisioning_admins_list_staff_user_200(api_client, staff_user, boolean_toggle): """ Verify that the subcription POST endpoint is accessible to authorised users only + and returns valid data """ enterprise_customer_uuid = uuid4() customer_agreement = CustomerAgreementFactory.create( @@ -1001,6 +1005,53 @@ def test_subscription_plan_provisioning_admins_list_staff_user_200(api_client, s assert status.HTTP_200_OK == response.status_code +@pytest.mark.django_db +def test_subscription_plan_pa_list_staff_user_customer_uuid_200(api_client, staff_user, boolean_toggle): + """ + Verify that the subcription POST endpoint applies enterprise_customer_uuid if passed + in query params + """ + # first create a subscription plan against a enterprise customer + # then query it and test that customer uuid that's passed in query params + # and the one received from `list` response are same. + # We'll have to create two subscription plans to confirm it. + + enterprise_customer_uuid_one = uuid4() + enterprise_customer_uuid_two = uuid4() + customer_agreement_one = CustomerAgreementFactory.create( + enterprise_customer_uuid=enterprise_customer_uuid_one) + customer_agreement_two = CustomerAgreementFactory.create( + enterprise_customer_uuid=enterprise_customer_uuid_two) + ProductFactory.create_batch(1) + allowed_group = Group.objects.create(name=PROVISIONING_ADMINS_GROUP) + staff_user.groups.add(allowed_group) + _assign_role_via_jwt_or_db( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid_one, assign_via_jwt=boolean_toggle) + + params_one = _prepare_subscription_plan_payload(customer_agreement_one) + params_two = _prepare_subscription_plan_payload(customer_agreement_two) + + _provision_license_create_request( + api_client, staff_user, params=params_one) + + response_one = _provision_license_list_request( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid_one) + assert status.HTTP_200_OK == response_one.status_code + assert response_one.json()['results'][0]['enterprise_customer_uuid'] == str( + enterprise_customer_uuid_one) + _assign_role_via_jwt_or_db( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid_two, assign_via_jwt=boolean_toggle) + + _provision_license_create_request( + api_client, staff_user, params=params_two) + response_two = _provision_license_list_request( + api_client, staff_user, enterprise_customer_uuid=enterprise_customer_uuid_two) + + assert status.HTTP_200_OK == response_two.status_code + assert response_two.json()['results'][0]['enterprise_customer_uuid'] == str( + enterprise_customer_uuid_two) + + @pytest.mark.django_db def test_subscription_plan_update_staff_user_403(api_client, staff_user, boolean_toggle): """ diff --git a/license_manager/apps/api/v1/views.py b/license_manager/apps/api/v1/views.py index 736bb56d..b656b35d 100644 --- a/license_manager/apps/api/v1/views.py +++ b/license_manager/apps/api/v1/views.py @@ -443,6 +443,13 @@ def base_queryset(self): return queryset.order_by('-start_date') +@extend_schema_view( + list=extend_schema( + summary='List all SubscriptionPlans', + description='List all SubscriptionPlans or for a given enterprise_customer_uuid', + parameters=[serializers.SubscriptionPlanQueryParamsSerializer], + ), +) class SubscriptionPlanProvisioningAdminViewset( mixins.CreateModelMixin, mixins.ListModelMixin, @@ -463,14 +470,22 @@ def get_serializer_class(self): return serializers.SubscriptionPlanSerializer def get_queryset(self): - return SubscriptionPlan.objects.filter( - is_active=True - ).order_by('-start_date') + """ + Appends enterprise_customer_uuid in queryset if found in query params + """ + model_filters = {'is_active': True} + if self.requested_enterprise_uuid: + model_filters['customer_agreement__enterprise_customer_uuid'] = self.requested_enterprise_uuid + return SubscriptionPlan.objects.filter(**model_filters).order_by('-start_date') @property def requested_subscription_uuid(self): return self.kwargs.get('subscription_uuid') + @property + def requested_enterprise_uuid(self): + return utils.get_requested_enterprise_uuid(self.request) + def create(self, request, *args, **kwargs): """ Creates a new SubscriptionPlan record