Skip to content

Commit

Permalink
fix: set enrollment url course id to advertised course run key
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Jan 9, 2025
1 parent 1ded448 commit e675f09
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 212 deletions.
35 changes: 7 additions & 28 deletions enterprise_catalog/apps/catalog/algolia_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
VIDEO,
)
from enterprise_catalog.apps.catalog.content_metadata_utils import (
get_advertised_course_run,
get_course_first_paid_enrollable_seat_price,
get_course_run_by_uuid,
is_course_run_active,
)
from enterprise_catalog.apps.catalog.models import ContentMetadata
Expand Down Expand Up @@ -229,11 +229,7 @@ def _should_index_course(course_metadata):
bool: Whether or not the course should be indexed by algolia.
"""
course_json_metadata = course_metadata.json_metadata
advertised_course_run_uuid = course_json_metadata.get('advertised_course_run_uuid')
advertised_course_run = get_course_run_by_uuid(
course_json_metadata,
advertised_course_run_uuid,
)
advertised_course_run = get_advertised_course_run(course_json_metadata)

# We define a series of no-arg functions, each of which has the property that,
# if it returns true, means we should *not* index this record.
Expand Down Expand Up @@ -477,8 +473,7 @@ def get_course_language(course):
Returns:
string: human-readable language name parsed from a language code, or None if language name is not present.
"""
advertised_course_run = get_course_run_by_uuid(course, course.get('advertised_course_run_uuid'))
if not advertised_course_run:
if not (advertised_course_run := get_advertised_course_run(course)):
return None

content_language_name = advertised_course_run.get('content_language_search_facet_name')
Expand All @@ -496,8 +491,7 @@ def get_course_transcript_languages(course):
Returns:
list: a list of available human-readable video transcript languages parsed from a language code.
"""
advertised_course_run = get_course_run_by_uuid(course, course.get('advertised_course_run_uuid'))
if not advertised_course_run:
if not (advertised_course_run := get_advertised_course_run(course)):
return None

transcript_languages = advertised_course_run.get('transcript_languages_search_facet_names')
Expand Down Expand Up @@ -1168,23 +1162,6 @@ def _get_course_run(course, course_run):
return course_run


def get_advertised_course_run(course):
"""
Get part of the advertised course_run as per advertised_course_run_uuid
Argument:
course (dict)
Returns:
dict: containing key, pacing_type, start, end, and upgrade deadline
for the course_run, or None
"""
full_course_run = get_course_run_by_uuid(course, course.get('advertised_course_run_uuid'))
if full_course_run is None:
return None
return _get_course_run(course, full_course_run)


def get_course_runs(course):
"""
Extract and transform a list of course runs into what we'll index.
Expand Down Expand Up @@ -1514,6 +1491,8 @@ def _algolia_object_from_product(product, algolia_fields):
"""
searchable_product = copy.deepcopy(product)
if searchable_product.get('content_type') == COURSE:
advertised_course_run = get_advertised_course_run(searchable_product)
transformed_advertised_course_run = _get_course_run(searchable_product, advertised_course_run)
searchable_product.update({
'language': get_course_language(searchable_product),
'availability': get_course_availability(searchable_product),
Expand All @@ -1522,7 +1501,7 @@ def _algolia_object_from_product(product, algolia_fields):
'program_titles': get_course_program_titles(searchable_product),
'subjects': get_course_subjects(searchable_product),
'card_image_url': get_course_card_image_url(searchable_product),
'advertised_course_run': get_advertised_course_run(searchable_product),
'advertised_course_run': transformed_advertised_course_run,
'course_runs': get_course_runs(searchable_product),
'upcoming_course_runs': get_upcoming_course_runs(searchable_product),
'skill_names': get_course_skill_names(searchable_product),
Expand Down
19 changes: 18 additions & 1 deletion enterprise_catalog/apps/catalog/content_metadata_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_course_first_paid_enrollable_seat_price(course):
# Use advertised course run.
# If that fails use one of the other active course runs.
# (The latter is what Discovery does)
advertised_course_run = get_course_run_by_uuid(course, course.get('advertised_course_run_uuid'))
advertised_course_run = get_advertised_course_run(course)
if advertised_course_run and advertised_course_run.get('first_enrollable_paid_seat_price'):
return advertised_course_run.get('first_enrollable_paid_seat_price')

Expand All @@ -102,3 +102,20 @@ def get_course_first_paid_enrollable_seat_price(course):
if 'first_enrollable_paid_seat_price' in course_run:
return course_run['first_enrollable_paid_seat_price']
return None


def get_advertised_course_run(course):
"""
Get part of the advertised course_run as per advertised_course_run_uuid
Argument:
course (dict)
Returns:
dict: containing key, pacing_type, start, end, and upgrade deadline
for the course_run, or None
"""
full_course_run = get_course_run_by_uuid(course, course.get('advertised_course_run_uuid'))
if full_course_run is None:
return None
return full_course_run
8 changes: 7 additions & 1 deletion enterprise_catalog/apps/catalog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
json_serialized_course_modes,
)
from enterprise_catalog.apps.catalog.content_metadata_utils import (
get_advertised_course_run,
get_course_first_paid_enrollable_seat_price,
)
from enterprise_catalog.apps.catalog.utils import (
Expand Down Expand Up @@ -555,10 +556,15 @@ def get_content_enrollment_url(self, content_metadata):
else:
# Catalog param only needed for legacy (non-learner-portal) enrollment URLs
params['catalog'] = self.uuid

course_run_key = content_key
if not parent_content_key:
if advertised_course_run := get_advertised_course_run(content_metadata.json_metadata):
course_run_key = advertised_course_run['key']
url = '{}/enterprise/{}/course/{}/enroll/'.format(
settings.LMS_BASE_URL,
self.enterprise_uuid,
content_key,
course_run_key,
)

return update_query_parameters(url, params)
Expand Down
5 changes: 2 additions & 3 deletions enterprise_catalog/apps/catalog/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from enterprise_catalog.apps.api.constants import CourseMode
from enterprise_catalog.apps.catalog.constants import EXEC_ED_2U_COURSE_TYPE
from enterprise_catalog.apps.catalog.content_metadata_utils import (
get_course_run_by_uuid,
get_advertised_course_run,
)


Expand Down Expand Up @@ -113,8 +113,7 @@ def is_exec_ed_2u_course(self):
def course_run_metadata(self):
if run_metadata := self.instance.get('course_run_metadata'):
return run_metadata
advertised_course_run_uuid = self.course_metadata.get('advertised_course_run_uuid')
return get_course_run_by_uuid(self.course_metadata, advertised_course_run_uuid)
return get_advertised_course_run(self.course_metadata)

@extend_schema_field(serializers.DateTimeField)
def get_start_date(self, obj) -> str: # pylint: disable=unused-argument
Expand Down
2 changes: 1 addition & 1 deletion enterprise_catalog/apps/catalog/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def _json_metadata(self):
'logo_image_url': fake.image_url() + '.jpg',
}]
course_runs = [{
'key': 'course-v1:edX+DemoX',
'key': 'course-v1:edX+DemoX+2T2024',
'uuid': str(FAKE_ADVERTISED_COURSE_RUN_UUID),
'content_language': 'en-us',
'status': 'published',
Expand Down
157 changes: 0 additions & 157 deletions enterprise_catalog/apps/catalog/tests/test_algolia_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,163 +353,6 @@ def test_get_course_subjects(self, course_metadata, expected_subjects):
course_subjects = utils.get_course_subjects(course_metadata)
assert sorted(course_subjects) == sorted(expected_subjects)

@ddt.data(
(
{
'course_runs': [{
'key': 'course-v1:org+course+1T2021',
'uuid': ADVERTISED_COURSE_RUN_UUID,
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'enrollment_end': '2013-10-17T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'status': 'published',
'is_enrollable': True,
'is_marketable': True,
'enrollment_start': '2013-10-01T14:00:00Z',
}],
'advertised_course_run_uuid': ADVERTISED_COURSE_RUN_UUID
},
{
'key': 'course-v1:org+course+1T2021',
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'upgrade_deadline': 32503680000.0,
'enroll_start': 1380636000,
'has_enroll_start': True,
'has_enroll_by': True,
'enroll_by': 1382018400.0,
'is_active': True,
'is_late_enrollment_eligible': False,
'content_price': 0.0,
'restriction_type': None,
},
),
(
{
'course_runs': [{
'uuid': uuid4(),
}],
'advertised_course_run_uuid': ADVERTISED_COURSE_RUN_UUID
},
None,
),
(
{
'course_runs': [{
'key': 'course-v1:org+course+1T2021',
'uuid': ADVERTISED_COURSE_RUN_UUID,
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'enrollment_end': '2013-10-17T14:00:00Z',
'enrollment_start_date': '2013-10-01T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'status': 'published',
'is_enrollable': True,
'is_marketable': True,
'seats': [
{
'type': 'audit',
'upgrade_deadline': None,
},
{
'type': 'verified',
'upgrade_deadline': '2015-01-04T15:52:00Z',
'price': '50.00',
}
],
'first_enrollable_paid_seat_price': 50,
'enrollment_start': '2013-10-01T14:00:00Z',
}],
'advertised_course_run_uuid': ADVERTISED_COURSE_RUN_UUID
},
{
'key': 'course-v1:org+course+1T2021',
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'upgrade_deadline': 1420386720.0,
'enroll_by': 1382018400.0,
'enroll_start': 1380636000.0,
'has_enroll_by': True,
'has_enroll_start': True,
'content_price': 50,
'is_active': True,
'is_late_enrollment_eligible': False,
'restriction_type': None,
}
),
(
{
'course_runs': [{
'key': 'course-v1:org+course+1T2021',
'uuid': ADVERTISED_COURSE_RUN_UUID,
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'enrollment_end': '2013-10-17T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'status': 'published',
'is_enrollable': True,
'is_marketable': True,
'seats': [{
'type': 'verified',
'upgrade_deadline': None,
'price': '50.00',
}],
'first_enrollable_paid_seat_price': 50,
}],
'advertised_course_run_uuid': ADVERTISED_COURSE_RUN_UUID
},
{
'key': 'course-v1:org+course+1T2021',
'pacing_type': 'instructor_paced',
'start': '2013-10-16T14:00:00Z',
'end': '2014-10-16T14:00:00Z',
'availability': 'Current',
'min_effort': 10,
'max_effort': 14,
'weeks_to_complete': 13,
'upgrade_deadline': 32503680000.0,
'enroll_by': 1382018400.0,
'enroll_start': None,
'has_enroll_by': True,
'has_enroll_start': False,
'content_price': 50,
'is_active': True,
'is_late_enrollment_eligible': False,
'restriction_type': None,
}
)
)
@ddt.unpack
def test_get_advertised_course_run(self, searchable_course, expected_course_run):
"""
Assert get_advertised_course_runs fetches just enough info about advertised course run
"""
advertised_course_run = utils.get_advertised_course_run(searchable_course)
assert advertised_course_run == expected_course_run

@ddt.data(
(
{
Expand Down
Loading

0 comments on commit e675f09

Please sign in to comment.