Skip to content

Commit

Permalink
feat: add response builder to the BFF
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Nov 15, 2024
1 parent 9732d12 commit 940cd61
Show file tree
Hide file tree
Showing 9 changed files with 753 additions and 190 deletions.
104 changes: 3 additions & 101 deletions enterprise_access/apps/api_client/tests/test_license_manager_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@

from django.conf import settings
from django.test import RequestFactory, TestCase
from faker import Faker
from requests import Response

from enterprise_access.apps.api_client.constants import LicenseStatuses
from enterprise_access.apps.api_client.license_manager_client import (
LicenseManagerApiClient,
LicenseManagerUserApiClient
)
from enterprise_access.apps.api_client.tests.test_constants import DATE_FORMAT_ISO_8601, DATE_FORMAT_ISO_8601_MS
from enterprise_access.utils import _days_from_now
from enterprise_access.apps.api_client.tests.test_utils import MockLicenseManagerMetadataMixin


class TestLicenseManagerApiClient(TestCase):
Expand Down Expand Up @@ -48,111 +45,16 @@ def test_get_subscription(self, mock_oauth_client):
)


class TestLicenseManagerUserApiClient(TestCase):
class TestLicenseManagerUserApiClient(MockLicenseManagerMetadataMixin):
"""
Test License Manager with BaseUserApiClient.
"""
def setUp(self):
super().setUp()
self.api_base_url = LicenseManagerUserApiClient.api_base_url
self.factory = RequestFactory()
self.faker = Faker()
self.request_id_key = settings.REQUEST_ID_RESPONSE_HEADER

self.mock_enterprise_customer_uuid = self.faker.uuid4()
self.mock_enterprise_customer_slug = "test_slug"
self.mock_enterprise_catalog_uuid = self.faker.uuid4()
self.mock_user_email = self.faker.email()
self.mock_learner_license_uuid = self.faker.uuid4()
self.mock_learner_license_activation_uuid = self.faker.uuid4()
self.mock_license_activation_key = self.faker.uuid4()
self.mock_auto_apply_uuid = self.faker.uuid4()
self.mock_subscription_plan_uuid = self.faker.uuid4()
self.mock_customer_agreement_uuid = self.faker.uuid4()

self.base_paginated_response = {
"next": None,
"previous": None,
"count": 0,
"results": [],
}
self.mock_subscription_plan = {
"title": "mock_title",
"uuid": self.mock_subscription_plan_uuid,
"start_date": _days_from_now(-50, DATE_FORMAT_ISO_8601),
"expiration_date": _days_from_now(50, DATE_FORMAT_ISO_8601),
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enterprise_catalog_uuid": self.mock_enterprise_catalog_uuid,
"is_active": True,
"is_current": True,
"is_revocation_cap_enabled": False,
"days_until_expiration": _days_from_now(50, DATE_FORMAT_ISO_8601),
"days_until_expiration_including_renewals": _days_from_now(50, DATE_FORMAT_ISO_8601),
"is_locked_for_renewal_processing": False,
"should_auto_apply_licenses": False,
"created": _days_from_now(-60, DATE_FORMAT_ISO_8601)
}
self.mock_customer_agreement = {
"uuid": self.mock_customer_agreement_uuid,
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enterprise_customer_slug": "mock_slug",
"default_enterprise_catalog_uuid": self.mock_enterprise_catalog_uuid,
"disable_expiration_notifications": False,
"net_days_until_expiration": _days_from_now(50, DATE_FORMAT_ISO_8601),
"subscription_for_auto_applied_licenses": self.mock_subscription_plan_uuid,
"available_subscription_catalogs": [
self.mock_enterprise_catalog_uuid,
],
"enable_auto_applied_subscriptions_with_universal_link": False,
"has_custom_license_expiration_messaging": False,
"modal_header_text": None,
"expired_subscription_modal_messaging": None,
"button_label_in_modal": None,
"url_for_button_in_modal": None
}
self.mock_learner_license_result_response = {
"uuid": self.mock_learner_license_uuid,
"status": LicenseStatuses.ACTIVATED,
"user_email": self.mock_user_email,
"activation_date": _days_from_now(-10, DATE_FORMAT_ISO_8601_MS),
"last_remind_date": _days_from_now(-5, DATE_FORMAT_ISO_8601_MS),
"subscription_plan_uuid": self.mock_subscription_plan_uuid,
"revoked_date": None,
"activation_key": self.mock_license_activation_key,
"subscription_plan": self.mock_subscription_plan
}
self.mock_learner_license_activation_response = {
"uuid": self.mock_learner_license_activation_uuid,
"status": LicenseStatuses.ACTIVATED,
"user_email": self.mock_user_email,
"activation_date": _days_from_now(-10, DATE_FORMAT_ISO_8601_MS),
"last_remind_date": _days_from_now(-5, DATE_FORMAT_ISO_8601_MS),
"subscription_plan_title": "mock_subscription_plan_title",
"subscription_plan_expiration_date": _days_from_now(50, DATE_FORMAT_ISO_8601),
"activation_link": self.faker.url()
}
self.mock_auto_apply_response = {
"uuid": self.mock_auto_apply_uuid,
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enterprise_customer_slug": self.mock_enterprise_customer_slug,
"default_enterprise_catalog_uuid": self.mock_enterprise_catalog_uuid,
"disable_expiration_notifications": True,
"net_days_until_expiration": _days_from_now(50, DATE_FORMAT_ISO_8601),
"subscription_for_auto_applied_licenses": self.mock_subscription_plan_uuid,
"available_subscription_catalogs": [
self.mock_enterprise_catalog_uuid,
],
"enable_auto_applied_subscriptions_with_universal_link": False,
"has_custom_license_expiration_messaging": False,
"modal_header_text": None,
"expired_subscription_modal_messaging": None,
"button_label_in_modal": None,
"url_for_button_in_modal": None,
"subscriptions": [
self.mock_subscription_plan
]
}

@mock.patch('requests.Session.send')
@mock.patch('crum.get_current_request')
def test_get_subscription_licenses_for_learner(self, mock_crum_get_current_request, mock_send):
Expand All @@ -163,7 +65,7 @@ def test_get_subscription_licenses_for_learner(self, mock_crum_get_current_reque
"current_page": 1,
"start": 0,
"results": [
self.mock_learner_license_result_response,
self.mock_subscription_license,
],
"customer_agreement": self.mock_customer_agreement,
}
Expand Down
109 changes: 107 additions & 2 deletions enterprise_access/apps/api_client/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
"""
Helper utilities for api_client tests.
"""
import requests
from django.test import TestCase
from faker import Faker
from requests import Response

from enterprise_access.apps.api_client.constants import LicenseStatuses
from enterprise_access.apps.api_client.tests.test_constants import DATE_FORMAT_ISO_8601, DATE_FORMAT_ISO_8601_MS
from enterprise_access.apps.core.tests.factories import UserFactory
from enterprise_access.utils import _days_from_now

class MockResponse(requests.Response):

class MockResponse(Response):
"""
Useful for mocking HTTP responses, especially for code that relies on raise_for_status().
"""
Expand All @@ -15,3 +22,101 @@ def __init__(self, json_data, status_code):

def json(self): # pylint: disable=arguments-differ
return self.json_data


class MockEnterpriseMetadata(TestCase):
"""
Mock enterprise metadata
"""
def setUp(self):
super().setUp()
self.faker = Faker()

self.mock_enterprise_customer_uuid = self.faker.uuid4()
self.mock_enterprise_customer_slug = "test_slug"
self.mock_enterprise_catalog_uuid = self.faker.uuid4()
self.mock_user = UserFactory()
self.mock_user_email = self.mock_user.email


class MockLicenseManagerMetadataMixin(MockEnterpriseMetadata):
"""
Mixin for the TestLicenseManagerUserApiClient
"""
def setUp(self):
super().setUp()
self.faker = Faker()

self.mock_learner_license_uuid = self.faker.uuid4()
self.mock_learner_license_activation_uuid = self.faker.uuid4()
self.mock_license_activation_key = self.faker.uuid4()
self.mock_auto_apply_uuid = self.faker.uuid4()
self.mock_subscription_plan_uuid = self.faker.uuid4()
self.mock_customer_agreement_uuid = self.faker.uuid4()

self.base_paginated_response = {
"next": None,
"previous": None,
"count": 0,
"results": [],
}
self.mock_subscription_plan = {
"title": "mock_title",
"uuid": self.mock_subscription_plan_uuid,
"start_date": _days_from_now(-50, DATE_FORMAT_ISO_8601),
"expiration_date": _days_from_now(50, DATE_FORMAT_ISO_8601),
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enterprise_catalog_uuid": self.mock_enterprise_catalog_uuid,
"is_active": True,
"is_current": True,
"is_revocation_cap_enabled": False,
"days_until_expiration": _days_from_now(50, DATE_FORMAT_ISO_8601),
"days_until_expiration_including_renewals": _days_from_now(50, DATE_FORMAT_ISO_8601),
"is_locked_for_renewal_processing": False,
"should_auto_apply_licenses": False,
"created": _days_from_now(-60, DATE_FORMAT_ISO_8601)
}
self.mock_customer_agreement = {
"uuid": self.mock_customer_agreement_uuid,
"enterprise_customer_uuid": self.mock_enterprise_customer_uuid,
"enterprise_customer_slug": self.mock_enterprise_customer_slug,
"default_enterprise_catalog_uuid": self.mock_enterprise_catalog_uuid,
"disable_expiration_notifications": False,
"net_days_until_expiration": _days_from_now(50, DATE_FORMAT_ISO_8601),
"subscription_for_auto_applied_licenses": self.mock_subscription_plan_uuid,
"available_subscription_catalogs": [
self.mock_enterprise_catalog_uuid,
],
"enable_auto_applied_subscriptions_with_universal_link": False,
"has_custom_license_expiration_messaging": False,
"modal_header_text": None,
"expired_subscription_modal_messaging": None,
"button_label_in_modal": None,
"url_for_button_in_modal": None
}
self.mock_learner_license_activation_response = {
"uuid": self.mock_learner_license_activation_uuid,
"status": LicenseStatuses.ACTIVATED,
"user_email": self.mock_user_email,
"activation_date": _days_from_now(-10, DATE_FORMAT_ISO_8601_MS),
"last_remind_date": _days_from_now(-5, DATE_FORMAT_ISO_8601_MS),
}
self.mock_subscription_license = {
**self.mock_learner_license_activation_response,
"subscription_plan_uuid": self.mock_subscription_plan_uuid,
"revoked_date": None,
"activation_key": self.mock_license_activation_key,
"subscription_plan": self.mock_subscription_plan
}
self.mock_learner_license_activation_response = {
"uuid": self.mock_learner_license_activation_uuid,
"status": LicenseStatuses.ACTIVATED,
"user_email": self.mock_user_email,
"activation_date": _days_from_now(-10, DATE_FORMAT_ISO_8601_MS),
"last_remind_date": _days_from_now(-5, DATE_FORMAT_ISO_8601_MS),
}
self.mock_auto_apply_response = {
**self.mock_subscription_license,
'customer-agreement': self.mock_customer_agreement,
'subscription_plan': self.mock_subscription_plan,
}
38 changes: 30 additions & 8 deletions enterprise_access/apps/bffs/handlers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""""
Handlers for bffs app.
BFF Handlers for bffs app.
"""

import logging
Expand Down Expand Up @@ -72,7 +72,9 @@ def load_and_process(self):
# Retrieve and process subscription licenses. Handles activation and auto-apply logic.
# TODO: retrieve enterprise customer metadata,ENT-9629
# self.load_enterprise_customer()
self.load_and_process_subscription_licenses()
# load and process subsidies
# calls load_and_process_subscription_licenses
self.load_and_process_subsidies()

# Retrieve default enterprise courses and enroll in the redeemable ones
self.load_default_enterprise_courses()
Expand All @@ -84,14 +86,35 @@ def load_and_process(self):
developer_message=f"Error: {e}",
)

def load_and_process_subsidies(self):
"""
Load subsidy metadata for learners
"""
self.context.data['enterprise_customer_user_subsidies'] = {
'subscriptions': {
'customer_agreement': None,
'subscription_licenses': [],
'subscription_licenses_by_status': []
}
}
self.load_and_process_subscription_licenses()

def load_subscription_licenses(self):
"""
Load subscription licenses for the learner.
"""
subscriptions_result = self.license_manager_client.get_subscription_licenses_for_learner(
enterprise_customer_uuid=self.context.enterprise_customer_uuid
)
self.transform_subscriptions_result(subscriptions_result)
try:
subscriptions_result = self.license_manager_client.get_subscription_licenses_for_learner(
enterprise_customer_uuid=self.context.enterprise_customer_uuid
)
subscriptions_data = self.transform_subscriptions_result(subscriptions_result)
self.context.data['subscriptions'] = subscriptions_data
except Exception as e: # pylint: disable=broad-exception-caught
logger.exception("Error loading subscription licenses")
self.add_error(
user_message="An error occurred while loading subscription licenses.",
developer_message=f"Error: {e}",
)

def get_subscription_licenses(self):
"""
Expand Down Expand Up @@ -139,12 +162,11 @@ def transform_subscriptions_result(self, subscriptions_result):

subscription_licenses_by_status[status].append(subscription_license)

subscriptions_data = {
return {
'customer_agreement': subscriptions_result.get('customer_agreement', {}),
'subscription_licenses': transformed_licenses,
'subscription_licenses_by_status': subscription_licenses_by_status,
}
self.context.data['subscriptions'] = subscriptions_data

def check_has_activated_license(self):
"""
Expand Down
Loading

0 comments on commit 940cd61

Please sign in to comment.