diff --git a/openedx/core/djangoapps/programs/tests/mixins.py b/openedx/core/djangoapps/programs/tests/mixins.py
index 3b6bf79d7f..b3df487342 100644
--- a/openedx/core/djangoapps/programs/tests/mixins.py
+++ b/openedx/core/djangoapps/programs/tests/mixins.py
@@ -99,11 +99,13 @@ class ProgramsDataMixin(object):
]
}
- def mock_programs_api(self, data=None, status_code=200):
+ def mock_programs_api(self, data=None, program_id='', status_code=200):
"""Utility for mocking out Programs API URLs."""
self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Programs API calls.')
url = ProgramsApiConfig.current().internal_api_url.strip('/') + '/programs/'
+ if program_id:
+ url += '{}/'.format(str(program_id))
if data is None:
data = self.PROGRAMS_API_RESPONSE
diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py
index 8f16be3931..d20a4a3626 100644
--- a/openedx/core/djangoapps/programs/tests/test_utils.py
+++ b/openedx/core/djangoapps/programs/tests/test_utils.py
@@ -40,8 +40,10 @@ ECOMMERCE_URL_ROOT = 'https://example-ecommerce.com'
MARKETING_URL = 'https://www.example.com/marketing/path'
-@skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+@ddt.ddt
@attr('shard_2')
+@httpretty.activate
+@skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, CredentialsDataMixin,
CredentialsApiConfigMixin, CacheIsolationTestCase):
"""Tests covering the retrieval of programs from the Programs service."""
@@ -77,7 +79,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
)
]
- @httpretty.activate
def test_get_programs(self):
"""Verify programs data can be retrieved."""
self.create_programs_config()
@@ -92,7 +93,24 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
# Verify the API was actually hit (not the cache).
self.assertEqual(len(httpretty.httpretty.latest_requests), 1)
- @httpretty.activate
+ @ddt.data(True, False)
+ def test_get_programs_category_casing(self, is_detail):
+ """Temporary. Verify that program categories are lowercased."""
+ self.create_programs_config()
+
+ program = factories.Program(category='camelCase')
+
+ if is_detail:
+ program_id = program['id']
+
+ self.mock_programs_api(data=program, program_id=program_id)
+ data = utils.get_programs(self.user, program_id=program_id)
+ self.assertEqual(data['category'], 'camelcase')
+ else:
+ self.mock_programs_api(data={'results': [program]})
+ data = utils.get_programs(self.user)
+ self.assertEqual(data[0]['category'], 'camelcase')
+
def test_get_programs_caching(self):
"""Verify that when enabled, the cache is used for non-staff users."""
self.create_programs_config(cache_ttl=1)
@@ -133,7 +151,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
self.assertEqual(actual, [])
self.assertTrue(mock_init.called)
- @httpretty.activate
def test_get_programs_data_retrieval_failure(self):
"""Verify behavior when data can't be retrieved from Programs."""
self.create_programs_config()
@@ -142,7 +159,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
actual = utils.get_programs(self.user)
self.assertEqual(actual, [])
- @httpretty.activate
def test_get_programs_for_dashboard(self):
"""Verify programs data can be retrieved and parsed correctly."""
self.create_programs_config()
@@ -165,7 +181,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
actual = utils.get_programs_for_dashboard(self.user, self.COURSE_KEYS)
self.assertEqual(actual, {})
- @httpretty.activate
def test_get_programs_for_dashboard_no_data(self):
"""Verify behavior when no programs data is found for the user."""
self.create_programs_config()
@@ -174,17 +189,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
actual = utils.get_programs_for_dashboard(self.user, self.COURSE_KEYS)
self.assertEqual(actual, {})
- @httpretty.activate
- def test_get_programs_for_dashboard_invalid_data(self):
- """Verify behavior when the Programs API returns invalid data and parsing fails."""
- self.create_programs_config()
- invalid_program = {'invalid_key': 'invalid_data'}
- self.mock_programs_api(data={'results': [invalid_program]})
-
- actual = utils.get_programs_for_dashboard(self.user, self.COURSE_KEYS)
- self.assertEqual(actual, {})
-
- @httpretty.activate
def test_get_program_for_certificates(self):
"""Verify programs data can be retrieved and parsed correctly for certificates."""
self.create_programs_config()
@@ -199,7 +203,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
self.assertEqual(len(actual), 2)
self.assertEqual(actual, expected)
- @httpretty.activate
def test_get_program_for_certificates_no_data(self):
"""Verify behavior when no programs data is found for the user."""
self.create_programs_config()
@@ -210,7 +213,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
actual = utils.get_programs_for_credentials(self.user, program_credentials_data)
self.assertEqual(actual, [])
- @httpretty.activate
def test_get_program_for_certificates_id_not_exist(self):
"""Verify behavior when no program with the given program_id in
credentials exists.
@@ -233,7 +235,6 @@ class TestProgramRetrieval(ProgramsApiConfigMixin, ProgramsDataMixin, Credential
actual = utils.get_programs_for_credentials(self.user, credential_data)
self.assertEqual(actual, [])
- @httpretty.activate
def test_get_display_category_success(self):
self.create_programs_config()
self.mock_programs_api()
diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py
index 4a1c1f7b31..ebd6e5f802 100644
--- a/openedx/core/djangoapps/programs/utils.py
+++ b/openedx/core/djangoapps/programs/utils.py
@@ -48,7 +48,17 @@ def get_programs(user, program_id=None):
# Bypass caching for staff users, who may be creating Programs and want
# to see them displayed immediately.
cache_key = programs_config.CACHE_KEY if programs_config.is_cache_enabled and not user.is_staff else None
- return get_edx_api_data(programs_config, user, 'programs', resource_id=program_id, cache_key=cache_key)
+
+ data = get_edx_api_data(programs_config, user, 'programs', resource_id=program_id, cache_key=cache_key)
+
+ # TODO: Temporary, to be removed once category names are cased for display. ECOM-5018.
+ if data and program_id:
+ data['category'] = data['category'].lower()
+ else:
+ for program in data:
+ program['category'] = program['category'].lower()
+
+ return data
def flatten_programs(programs, course_ids):