Skip to content

Commit

Permalink
feat: expose enroll_by_date in content metadata response payload
Browse files Browse the repository at this point in the history
ENT-7472
  • Loading branch information
iloveagent57 committed Aug 14, 2024
1 parent f18ac7d commit c48a7a0
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
2 changes: 2 additions & 0 deletions enterprise_subsidy/apps/api/v1/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,7 @@ def test_successful_get(
'content_price': expected_content_price,
'mode': expected_mode,
'geag_variant_id': expected_geag_variant_id,
'enroll_by_date': None,
}

# Now make a second call to validate that the view-level cache is utilized.
Expand All @@ -1824,6 +1825,7 @@ def test_successful_get(
'content_price': expected_content_price,
'mode': expected_mode,
'geag_variant_id': expected_geag_variant_id,
'enroll_by_date': None,
}
# Validate that, in the first, non-cached request, we call
# the enterprise catalog endpoint via the client, and that
Expand Down
38 changes: 37 additions & 1 deletion enterprise_subsidy/apps/content_metadata/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,57 @@ def get_geag_variant_id_for_content(self, content_identifier, content_data):
variant_id = additional_metadata.get('variant_id')
return variant_id

def enroll_by_date_for_content(self, content_data, content_mode):
"""
Determines the enrollment deadline for the given ``content_data``,
which could be either a course or course run, hence the branching
on content type below.
Args:
content_data: A dictionary of metadata pertaining to a course or course run.
content_mode: The (already computed) course mode for the content.
Returns:
A datetime string, or possibly null.
"""
if content_data.get('content_type') == 'course':
return content_data.get('normalized_metadata', {}).get('enroll_by_date')

# For edx-verified mode course runs, first try to extract
# the verified upgrade deadline from the course run's seat
# associated with the given content_mode
upgrade_deadline = None
if content_mode == CourseModes.EDX_VERIFIED.value:
seats_for_mode = [
seat for seat in content_data.get('seats', [])
if seat.get('type') == content_mode
]
if seats_for_mode:
seat = seats_for_mode[0]
upgrade_deadline = seat.get('upgrade_deadline_override') or seat.get('upgrade_deadline')

# Return the upgrade deadline. If no such deadline exists,
# or if we're dealing with another course mode (e.g. exec ed),
# use the `enrollment_end` of the course run.
return upgrade_deadline or content_data.get('enrollment_end')

def summary_data_for_content(self, content_identifier, content_data):
"""
Returns a summary dict specifying the content_uuid, content_key, source, and content_price
for a dict of content metadata.
"""
course_run_content = self.get_course_run(content_identifier, content_data)
content_mode = self.mode_for_content(content_data)
return {
'content_title': content_data.get('title'),
'content_uuid': content_data.get('uuid'),
'content_key': content_data.get('key'),
'course_run_uuid': course_run_content.get('uuid'),
'course_run_key': course_run_content.get('key'),
'source': self.product_source_for_content(content_data),
'mode': self.mode_for_content(content_data),
'mode': content_mode,
'content_price': self.price_for_content(content_data, course_run_content),
'enroll_by_date': self.enroll_by_date_for_content(content_data, content_mode),
'geag_variant_id': self.get_geag_variant_id_for_content(content_identifier, content_data),
}

Expand Down
45 changes: 44 additions & 1 deletion enterprise_subsidy/apps/content_metadata/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ def setUpTestData(cls):
'course_run_keys': [cls.courserun_key_1],
'content_last_modified': '2023-03-06T20:56:46.003840Z',
'enrollment_url': 'https://foobar.com',
'active': False
'active': False,
'normalized_metadata': {
'enroll_by_date': '2023-05-26T15:45:32.494051Z',
},
}

cls.executive_education_course_metadata = {
Expand Down Expand Up @@ -136,6 +139,9 @@ def setUpTestData(cls):
"additional_metadata": {
"variant_id": cls.variant_id_2,
},
"normalized_metadata": {
"enroll_by_date": "2024-01-01T00:00:00Z",
},
}

@ddt.data(
Expand Down Expand Up @@ -216,6 +222,7 @@ def test_summary_data_for_content(self):
assert summary.get('content_key') == self.course_key
assert summary.get('course_run_key') == self.courserun_key_1
assert summary.get('content_price') == 14900
assert summary.get('enroll_by_date') == '2023-05-26T15:45:32.494051Z'

def test_summary_data_for_exec_ed_content(self):
mode = self.content_metadata_api.mode_for_content(self.executive_education_course_metadata)
Expand Down Expand Up @@ -251,6 +258,7 @@ def test_summary_data_for_exec_ed_content(self):
assert summary.get('course_run_key') is self.courserun_key_2
assert summary.get('content_price') == 59949
assert summary.get('geag_variant_id') == self.variant_id_2
assert summary.get('enroll_by_date') == '2024-01-01T00:00:00Z'

@ddt.data(
{
Expand Down Expand Up @@ -428,3 +436,38 @@ def test_tiered_caching_works(self, mock_catalog_client):
)
assert client_instance.get_content_metadata.call_count == 1
TieredCache.delete_all_tiers(cache_key)

@ddt.data(True, False)
def test_enroll_by_date_for_verified_course_run_content(self, has_override):
upgrade_deadline_key = 'upgrade_deadline_override' if has_override else 'upgrade_deadline'
content_data = {
'content_type': 'courserun',
'enrollment_end': '2024-12-01T00:00:00Z',
'seats': [
{
'type': 'verified',
upgrade_deadline_key: '2025-01-01T00:00:00Z',
}
]
}
self.assertEqual(
ContentMetadataApi().enroll_by_date_for_content(content_data, 'verified'),
'2025-01-01T00:00:00Z',
)

@ddt.data('verified', 'paid-executive-education')
def test_enroll_by_date_for_content_fallback(self, mode):
content_data = {
'content_type': 'courserun',
'enrollment_end': '2024-12-01T00:00:00Z',
}
self.assertEqual(
ContentMetadataApi().enroll_by_date_for_content(content_data, mode),
'2024-12-01T00:00:00Z',
)

def test_enroll_by_date_for_content_handles_null(self):
content_data = {
'content_type': 'courserun',
}
self.assertIsNone(ContentMetadataApi().enroll_by_date_for_content(content_data, 'verified'))

0 comments on commit c48a7a0

Please sign in to comment.