From d3aeaaff10b68134f760be070c6c7106d274f06e Mon Sep 17 00:00:00 2001 From: Alexander J Sheehan Date: Mon, 11 Mar 2024 16:06:54 +0000 Subject: [PATCH] feat: adding group associations to subsidy access policy api serializers --- .../api/serializers/subsidy_access_policy.py | 10 ++++++++++ .../tests/test_subsidy_access_policy_views.py | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/enterprise_access/apps/api/serializers/subsidy_access_policy.py b/enterprise_access/apps/api/serializers/subsidy_access_policy.py index 5090f4d6..b0efd92f 100644 --- a/enterprise_access/apps/api/serializers/subsidy_access_policy.py +++ b/enterprise_access/apps/api/serializers/subsidy_access_policy.py @@ -152,6 +152,7 @@ class SubsidyAccessPolicyResponseSerializer(serializers.ModelSerializer): assignment_configuration = AssignmentConfigurationResponseSerializer( help_text='AssignmentConfiguration object for this policy.', ) + group_associations = serializers.SerializerMethodField() class Meta: model = SubsidyAccessPolicy @@ -174,9 +175,13 @@ class Meta: 'is_subsidy_active', 'aggregates', 'assignment_configuration', + 'group_associations', ] read_only_fields = fields + def get_group_associations(self, obj): + return obj.groups.values_list("enterprise_group_uuid", flat=True) + class SubsidyAccessPolicyCRUDSerializer(serializers.ModelSerializer): """ @@ -186,6 +191,7 @@ class SubsidyAccessPolicyCRUDSerializer(serializers.ModelSerializer): # Since the upstream model field has editable=False, we must redefine the field here because editable fields are # automatically skipped by validation, but we do actually want it to be validated. policy_type = serializers.ChoiceField(choices=PolicyTypes.CHOICES) + group_associations = serializers.SerializerMethodField() class Meta: model = SubsidyAccessPolicy @@ -206,6 +212,7 @@ class Meta: 'subsidy_active_datetime', 'subsidy_expiration_datetime', 'is_subsidy_active', + 'group_associations', ] read_only_fields = ['uuid'] extra_kwargs = { @@ -267,6 +274,9 @@ def calling_view(self): """ return self.context['view'] + def get_group_associations(self, obj): + return obj.groups.values_list("enterprise_group_uuid", flat=True) + def create(self, validated_data): policy_type = validated_data.get('policy_type') policy_model = apps.get_model(app_label='subsidy_access_policy', model_name=policy_type) diff --git a/enterprise_access/apps/api/v1/tests/test_subsidy_access_policy_views.py b/enterprise_access/apps/api/v1/tests/test_subsidy_access_policy_views.py index a4259608..d2cea0dd 100644 --- a/enterprise_access/apps/api/v1/tests/test_subsidy_access_policy_views.py +++ b/enterprise_access/apps/api/v1/tests/test_subsidy_access_policy_views.py @@ -41,7 +41,8 @@ from enterprise_access.apps.subsidy_access_policy.tests.factories import ( AssignedLearnerCreditAccessPolicyFactory, PerLearnerEnrollmentCapLearnerCreditAccessPolicyFactory, - PerLearnerSpendCapLearnerCreditAccessPolicyFactory + PerLearnerSpendCapLearnerCreditAccessPolicyFactory, + PolicyGroupAssociationFactory ) from enterprise_access.apps.subsidy_access_policy.utils import create_idempotency_key_for_transaction from test_utils import TEST_USER_RECORD, APITestWithMocks @@ -268,6 +269,12 @@ def test_detail_view(self, role_context_dict): request_kwargs = {'uuid': str(self.redeemable_policy.uuid)} + enterprise_group_uuid = uuid4() + PolicyGroupAssociationFactory( + enterprise_group_uuid=enterprise_group_uuid, + subsidy_access_policy=self.redeemable_policy, + ) + # Test the retrieve endpoint response = self.client.get(reverse('api:v1:subsidy-access-policies-detail', kwargs=request_kwargs)) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -297,6 +304,7 @@ def test_detail_view(self, role_context_dict): 'spend_available_usd': 0.02, }, 'assignment_configuration': None, + 'group_associations': [str(enterprise_group_uuid)], }, response.json()) @ddt.data( @@ -389,6 +397,7 @@ def test_list_view(self, role_context_dict): 'spend_available_usd': 0.00, }, 'assignment_configuration': None, + 'group_associations': [], }, { 'access_method': 'direct', @@ -416,6 +425,7 @@ def test_list_view(self, role_context_dict): 'spend_available_usd': 0.02, }, 'assignment_configuration': None, + 'group_associations': [], }, ] @@ -446,7 +456,7 @@ def test_list_view(self, role_context_dict): call( subsidy_uuid=self.non_redeemable_policy.subsidy_uuid, subsidy_access_policy_uuid=self.non_redeemable_policy.uuid, - ) + ), ]) @ddt.data( @@ -510,6 +520,7 @@ def test_destroy_view(self, request_payload, expected_change_reason): 'spend_available_usd': 0.02, }, 'assignment_configuration': None, + 'group_associations': [], } self.assertEqual(expected_response, response.json()) @@ -621,6 +632,7 @@ def test_update_views(self, is_patch, request_payload): 'spend_available_usd': 0.04, }, 'assignment_configuration': None, + 'group_associations': [], } expected_response.update(request_payload) self.assertEqual(expected_response, response.json()) @@ -828,6 +840,7 @@ def test_create_view(self, policy_type, extra_fields, expected_response_code, ex 'subsidy_active_datetime': self.yesterday.isoformat(), 'subsidy_expiration_datetime': self.tomorrow.isoformat(), 'is_subsidy_active': True, + 'group_associations': [], } payload.update(extra_fields) response = self.client.post(SUBSIDY_ACCESS_POLICY_LIST_ENDPOINT, payload) @@ -884,6 +897,7 @@ def test_idempotent_create_view(self, policy_type, extra_fields, expected_respon 'subsidy_active_datetime': self.yesterday.isoformat(), 'subsidy_expiration_datetime': self.tomorrow.isoformat(), 'is_subsidy_active': True, + 'group_associations': [], } payload.update(extra_fields) response = self.client.post(SUBSIDY_ACCESS_POLICY_LIST_ENDPOINT, payload)