From 8f5c4cf4082527abc2c1744771ed2592ba23e039 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 16 Oct 2024 17:30:50 -0400 Subject: [PATCH] feat: return serialized subs license in license-activation POST --- .../apps/api/v1/tests/test_api_eventing.py | 2 +- .../v1/tests/test_license_activation_view.py | 46 ++++++++++++++++--- license_manager/apps/api/v1/views.py | 8 ++-- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/license_manager/apps/api/v1/tests/test_api_eventing.py b/license_manager/apps/api/v1/tests/test_api_eventing.py index 7f962c0d..e1038e09 100644 --- a/license_manager/apps/api/v1/tests/test_api_eventing.py +++ b/license_manager/apps/api/v1/tests/test_api_eventing.py @@ -246,7 +246,7 @@ def test_activate_an_assigned_license(self, _): url = reverse('api:v1:license-activation') + '/?' + query_params.urlencode() response = self.api_client.post(url) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code license_to_be_activated.refresh_from_db() assert mock_activated_track_event.call_count == 1 diff --git a/license_manager/apps/api/v1/tests/test_license_activation_view.py b/license_manager/apps/api/v1/tests/test_license_activation_view.py index aeab03a3..9f92cf57 100644 --- a/license_manager/apps/api/v1/tests/test_license_activation_view.py +++ b/license_manager/apps/api/v1/tests/test_license_activation_view.py @@ -4,6 +4,7 @@ import datetime from unittest import mock from uuid import uuid4 +from pytz import UTC import ddt from django.http import QueryDict @@ -145,8 +146,19 @@ def test_activate_an_assigned_license(self, mock_send_post_activation_email_task with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + + # Verify that the response contains activated subscription license. + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_to_be_activated.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + + # Refresh license from the database license_to_be_activated.refresh_from_db() + + # Verify that the license has been activated in the DB assert constants.ACTIVATED == license_to_be_activated.status assert self.lms_user_id == license_to_be_activated.lms_user_id assert self.now == license_to_be_activated.activation_date @@ -159,7 +171,7 @@ def test_activate_an_assigned_license(self, mock_send_post_activation_email_task self.user.email, ) - def test_license_already_activated_returns_204(self): + def test_license_already_activated_returns_200(self): self._assign_learner_roles( jwt_payload_extra={ 'user_id': self.lms_user_id, @@ -174,7 +186,13 @@ def test_license_already_activated_returns_204(self): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(already_activated_license.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + already_activated_license.refresh_from_db() assert constants.ACTIVATED == already_activated_license.status assert self.lms_user_id == already_activated_license.lms_user_id @@ -217,7 +235,12 @@ def test_duplicate_licenses_are_cleaned_up(self, mock_license_clean, mock_email_ with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_b.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date license_b.refresh_from_db() assert constants.ACTIVATED == license_b.status @@ -268,7 +291,12 @@ def test_activated_license_exists_with_duplicates(self, mock_license_clean, mock with freeze_time(self.now): response = self._post_request(str(license_a_activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_b.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date license_b.refresh_from_db() assert constants.ACTIVATED == license_b.status @@ -341,7 +369,13 @@ def test_activating_renewed_assigned_license(self, mock_send_post_activation_ema with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(current_assigned_license.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + current_assigned_license.refresh_from_db() prior_assigned_license.refresh_from_db() assert prior_assigned_license.activation_date != self.now diff --git a/license_manager/apps/api/v1/views.py b/license_manager/apps/api/v1/views.py index 24c99388..d3eaa3d7 100644 --- a/license_manager/apps/api/v1/views.py +++ b/license_manager/apps/api/v1/views.py @@ -716,6 +716,7 @@ def base_queryset(self): return licenses + class BaseLicenseViewSet(PermissionRequiredForListingMixin, viewsets.ReadOnlyModelViewSet): """ Base Viewset for read operations on individual licenses in a given subscription plan. @@ -1779,10 +1780,10 @@ def post(self, request): license's subscription plan. * 404 Not Found - if the email found in the request's JWT and the provided ``activation_key`` do not match those of any existing license in an activate subscription plan. - * 204 No Content - if such a license was found, and if the license is currently ``assigned``, + * 200 OK - if such a license was found, and if the license is currently ``assigned``, it is updated with a status of ``activated``, its ``activation_date`` is set, and its ``lms_user_id`` is updated to the value found in the request's JWT. If the license is already ``activated``, - no update is made to it. + no update is made to it. The activated license is then returned in the response. * 422 Unprocessable Entity - if we find a license, but it's status is not currently ``assigned`` or ``activated``, we do nothing and return a 422 with a message indicating that the license cannot be activated. @@ -1801,7 +1802,8 @@ def post(self, request): # There's an implied logical branch where the license is already activated # in which case we also return as if the activation action was successful. - return Response(status=status.HTTP_204_NO_CONTENT) + serialized_license = serializers.LicenseSerializer(user_license) + return Response(serialized_license.data, status=status.HTTP_200_OK) def _track_and_notify(self, user_license): """