diff --git a/enterprise_catalog/apps/api/v1/tests/test_utils.py b/enterprise_catalog/apps/api/v1/tests/test_utils.py index 51185d1b..d7179d27 100644 --- a/enterprise_catalog/apps/api/v1/tests/test_utils.py +++ b/enterprise_catalog/apps/api/v1/tests/test_utils.py @@ -5,6 +5,7 @@ from enterprise_catalog.apps.api.v1.utils import ( get_archived_content_count, get_most_recent_modified_time, + is_course_run_active, ) from enterprise_catalog.apps.catalog.tests.factories import ( ContentMetadataFactory, @@ -82,3 +83,52 @@ def test_get_archived_content_count(self): [highlighted_content_1, highlighted_content_2, highlighted_content_3] ) assert archived_content_count == 2 + + def test_is_course_run_active(self): + """ + Test that the is_course_run_active function correctly identifies active course runs. + """ + # Test case where course run is active + active_course_run = { + 'is_enrollable': True, + 'is_marketable_external': True, + 'status': 'published', + 'is_marketable': True + } + assert is_course_run_active(active_course_run) is True + + # Test case where course run is not active due to not being enrollable + not_enrollable_course_run = { + 'is_enrollable': False, + 'is_marketable_external': True, + 'status': 'published', + 'is_marketable': True + } + assert is_course_run_active(not_enrollable_course_run) is False + + # Test case where course is not is_marketable but is_marketable_external + not_marketable_course_run = { + 'is_enrollable': True, + 'is_marketable_external': True, + 'status': 'published', + 'is_marketable': False + } + assert is_course_run_active(not_marketable_course_run) is True + + # Test case where course run is not active due to not being published + not_published_course_run = { + 'is_enrollable': False, + 'is_marketable_external': False, + 'status': 'archived', + 'is_marketable': True + } + assert is_course_run_active(not_published_course_run) is False + + # Test case where course run is active due to being marketable externally + marketable_external_course_run = { + 'is_enrollable': True, + 'is_marketable_external': True, + 'status': 'reviewed', + 'is_marketable': False + } + assert is_course_run_active(marketable_external_course_run) is True diff --git a/enterprise_catalog/apps/api/v1/utils.py b/enterprise_catalog/apps/api/v1/utils.py index aead4a5f..f1b45eee 100644 --- a/enterprise_catalog/apps/api/v1/utils.py +++ b/enterprise_catalog/apps/api/v1/utils.py @@ -10,6 +10,10 @@ urlunsplit, ) +from enterprise_catalog.apps.catalog.content_metadata_utils import ( + is_course_run_active, +) + logger = logging.getLogger(__name__) @@ -59,25 +63,6 @@ def get_enterprise_utm_context(enterprise_name): return utm_context -def is_course_run_active(course_run): - """ - Checks whether a course run is active. That is, whether the course run is published, - enrollable, and marketable. - - Arguments: - course_run (dict): The metadata about a course run. - - Returns: - bool: True if course run is "active" - """ - course_run_status = course_run.get('status') or '' - is_published = course_run_status.lower() == 'published' - is_enrollable = course_run.get('is_enrollable', False) - is_marketable = course_run.get('is_marketable', False) - - return is_published and is_enrollable and is_marketable - - def is_any_course_run_active(course_runs): """ Iterates over all course runs to check if there any course run that is available for enrollment. diff --git a/enterprise_catalog/apps/catalog/content_metadata_utils.py b/enterprise_catalog/apps/catalog/content_metadata_utils.py index 60739e27..046dc801 100644 --- a/enterprise_catalog/apps/catalog/content_metadata_utils.py +++ b/enterprise_catalog/apps/catalog/content_metadata_utils.py @@ -66,6 +66,9 @@ def is_course_run_active(course_run): """ Checks whether a course run is active. That is, whether the course run is published, enrollable, and marketable. + Checking is_published in case of is_marketable_external is redundant because + the Discovery service already handles the status behind is_marketable_external + property. Arguments: course_run (dict): The metadata about a course run. Returns: @@ -73,10 +76,13 @@ def is_course_run_active(course_run): """ course_run_status = course_run.get('status') or '' is_published = course_run_status.lower() == 'published' - is_enrollable = course_run.get('is_enrollable', False) is_marketable = course_run.get('is_marketable', False) + is_enrollable = course_run.get('is_enrollable', False) + + is_marketable_internal = is_published and is_marketable + is_marketable_external = course_run.get("is_marketable_external", False) - return is_published and is_enrollable and is_marketable + return is_enrollable and (is_marketable_internal or is_marketable_external) def get_course_first_paid_enrollable_seat_price(course): diff --git a/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py b/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py index 469c07fb..87b07915 100644 --- a/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py +++ b/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py @@ -119,6 +119,18 @@ class AlgoliaUtilsTests(TestCase): 'enrollment_end': days_from_now(30), 'restriction_type': RESTRICTION_FOR_B2B, }, + # A Exec-Ed course, not is_marketable but is_marketable_external. + { + 'expected_result': True, + 'course_type': EXEC_ED_2U_COURSE_TYPE, + 'start': days_from_now(1), + 'end': days_from_now(30), + 'enrollment_end': days_from_now(1), + 'is_marketable': False, + 'is_marketable_external': True, + 'advertised_course_run_status': 'reviewed', + 'course_run_availability': 'Upcoming' + }, ) @ddt.unpack def test_should_index_course( @@ -130,6 +142,7 @@ def test_should_index_course( advertised_course_run_status='published', is_enrollable=True, is_marketable=True, + is_marketable_external=True, course_run_availability='current', seats=None, course_type=COURSE, @@ -155,6 +168,7 @@ def test_should_index_course( 'status': advertised_course_run_status, 'is_enrollable': is_enrollable, 'is_marketable': is_marketable, + 'is_marketable_external': is_marketable_external, 'availability': course_run_availability, 'seats': seats or [], 'start': start, @@ -783,6 +797,18 @@ def test_get_course_runs(self, searchable_course, expected_course_runs): }, ['Archived'], ), + ( + { + 'course_runs': [{ + 'status': 'reviewed', + 'is_enrollable': True, + 'is_marketable': False, + 'is_marketable_external': True, + 'availability': 'Upcoming' + }] + }, + ['Upcoming'], + ), ) @ddt.unpack def test_get_course_availability(self, course_metadata, expected_availability):