Skip to content

Commit

Permalink
fix: compute price more defensively
Browse files Browse the repository at this point in the history
ENT-8786
  • Loading branch information
iloveagent57 committed Aug 22, 2024
1 parent 23f6954 commit da60313
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 34 deletions.
13 changes: 0 additions & 13 deletions enterprise_subsidy/apps/api/v1/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1739,19 +1739,6 @@ class ContentMetadataViewSetTests(APITestBase):
mock_http_error_url = 'foobar.com'

@ddt.data(
{
'expected_content_title': content_title,
'expected_content_uuid': content_uuid_1,
'expected_content_key': content_key_1,
'expected_course_run_uuid': None,
'expected_course_run_key': None,
'expected_content_price': 14900.0,
'mock_metadata': edx_course_metadata,
'expected_source': 'edX',
'expected_mode': 'verified',
'expected_geag_variant_id': None,
'expected_enroll_by_date': None,
},
{
'expected_content_title': content_title,
'expected_content_uuid': content_uuid_3,
Expand Down
19 changes: 10 additions & 9 deletions enterprise_subsidy/apps/content_metadata/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from enterprise_subsidy.apps.core.utils import versioned_cache_key
from enterprise_subsidy.apps.subsidy.constants import CENTS_PER_DOLLAR

from .constants import CourseModes, ProductSources
from .constants import DEFAULT_CONTENT_PRICE, CourseModes, ProductSources

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -62,23 +62,24 @@ def price_for_content(self, content_data, course_run_data):
those values to USD cents as an integer.
"""
content_price = None
if course_run_data.get('first_enrollable_paid_seat_price'):
content_price = course_run_data['first_enrollable_paid_seat_price']

if not content_price:
product_source = self.product_source_for_content(content_data)
if product_source == ProductSources.TWOU.value:
enrollment_mode_for_content = self.mode_for_content(content_data)
for entitlement in content_data.get('entitlements', []):
if entitlement.get('mode') == enrollment_mode_for_content:
content_price = entitlement.get('price')

if content_price:
return int(Decimal(content_price) * CENTS_PER_DOLLAR)
else:
content_price = course_run_data.get('first_enrollable_paid_seat_price')

if not content_price:
logger.info(
f"Could not determine price for content key {content_data.get('key')} "
f"and course run key {course_run_data.get('key')}"
f"and course run key {course_run_data.get('key')}, setting to default."
)
return None
content_price = DEFAULT_CONTENT_PRICE

return int(Decimal(content_price) * CENTS_PER_DOLLAR)

def mode_for_content(self, content_data):
"""
Expand Down
3 changes: 3 additions & 0 deletions enterprise_subsidy/apps/content_metadata/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ class CourseModes(Enum):
"""
EDX_VERIFIED = "verified" # e.g. edX Verified Courses
EXECUTIVE_EDUCATION = "paid-executive-education" # e.g. ExecEd courses


DEFAULT_CONTENT_PRICE = 0.0
36 changes: 24 additions & 12 deletions enterprise_subsidy/apps/content_metadata/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
from django.test import TestCase
from edx_django_utils.cache import TieredCache

from enterprise_subsidy.apps.subsidy.constants import CENTS_PER_DOLLAR

from ..api import ContentMetadataApi, content_metadata_cache_key, content_metadata_for_customer_cache_key
from ..constants import CourseModes, ProductSources
from ..constants import DEFAULT_CONTENT_PRICE, CourseModes, ProductSources


@ddt.ddt
Expand Down Expand Up @@ -158,17 +156,21 @@ def setUpTestData(cls):
"slug": "2u",
"description": "2U, Trilogy, Getsmarter -- external source for 2u courses and programs"
},
'course_runs': [],
'expected_price': 210000,
'advertised_course_run_uuid': None,
},
{
'entitlements': [
'course_runs': [
{
"mode": "verified",
"price": "794.00",
"currency": "USD",
"sku": "B6DE08E",
'uuid': '1234',
'first_enrollable_paid_seat_price': '123.50',
}
],
'advertised_course_run_uuid': '1234',
'entitlements': None,
'product_source': None,
'expected_price': 12350,
},
)
@ddt.unpack
Expand All @@ -178,6 +180,9 @@ def test_client_can_fetch_mode_specific_prices(
mock_get_content_metadata,
entitlements,
product_source,
course_runs,
expected_price,
advertised_course_run_uuid,
):
"""
Test the enterprise catalog client's ability to handle api requests to fetch content metadata from the catalog
Expand All @@ -186,11 +191,13 @@ def test_client_can_fetch_mode_specific_prices(
mocked_data = self.course_metadata.copy()
mocked_data['product_source'] = product_source
mocked_data['entitlements'] = entitlements
mocked_data['course_runs'] = course_runs
mocked_data['advertised_course_run_uuid'] = advertised_course_run_uuid
mock_get_content_metadata.return_value = mocked_data
price_in_cents = self.content_metadata_api.get_course_price(
self.enterprise_customer_uuid, self.course_key
)
assert price_in_cents == float(entitlements[0].get('price')) * CENTS_PER_DOLLAR
assert price_in_cents == expected_price

@ddt.data(
{
Expand Down Expand Up @@ -371,9 +378,9 @@ def test_summary_data_for_exec_ed_content_variant_id_sometimes_missing(
{
'content_data': {
'product_source': {'name': ProductSources.EDX.value, 'slug': ProductSources.EDX.value},
'entitlements': [{'mode': CourseModes.EDX_VERIFIED.value, 'price': '3.50'}],
'entitlements': [{'mode': CourseModes.EDX_VERIFIED.value, 'price': '34.50'}],
},
'course_run_data': {},
'course_run_data': {'first_enrollable_paid_seat_price': '3.50'},
'expected_price': 350,
},
{
Expand All @@ -387,7 +394,12 @@ def test_summary_data_for_exec_ed_content_variant_id_sometimes_missing(
{
'content_data': {},
'course_run_data': {},
'expected_price': None,
'expected_price': DEFAULT_CONTENT_PRICE,
},
{
'content_data': {},
'course_run_data': {'first_enrollable_paid_seat_price': None},
'expected_price': DEFAULT_CONTENT_PRICE,
},
)
@ddt.unpack
Expand Down

0 comments on commit da60313

Please sign in to comment.