def get_credit_provider_attribute_values(course_key, attribute_name): """Get the course information from ecommerce and parse the data to get providers. Arguments: course_key (CourseKey): The identifier for the course. attribute_name (String): Name of the attribute of credit provider. Returns: List of provided credit provider attribute values. """ course_id = six.text_type(course_key) credit_config = CreditConfig.current() cache_key = None attribute_values = None if credit_config.is_cache_enabled: cache_key = '{key_prefix}.{course_key}.{attribute_name}'.format( key_prefix=credit_config.CACHE_KEY, course_key=course_id, attribute_name=attribute_name) attribute_values = cache.get(cache_key) if attribute_values is not None: return attribute_values try: user = User.objects.get( username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME) response = ecommerce_api_client(user).courses(course_id).get( include_products=1) except Exception: # pylint: disable=broad-except log.exception( u"Failed to receive data from the ecommerce course API for Course ID '%s'.", course_id) return attribute_values if not response: log.info( u"No Course information found from ecommerce API for Course ID '%s'.", course_id) return attribute_values provider_ids = [] for product in response.get('products'): provider_ids += [ attr.get('value') for attr in product.get('attribute_values') if attr.get('name') == 'credit_provider' ] attribute_values = [] credit_providers = CreditProvider.get_credit_providers() for provider in credit_providers: if provider['id'] in provider_ids: attribute_values.append(provider[attribute_name]) if credit_config.is_cache_enabled: cache.set(cache_key, attribute_values, credit_config.cache_ttl) return attribute_values
def setUp(self): super(CourseApiTests, self).setUp() self.worker_user = User.objects.create_user(username=TEST_ECOMMERCE_WORKER) self.add_credit_course(self.course_key) self.credit_config = CreditConfig(cache_ttl=100, enabled=True) self.credit_config.save() # Add another provider. CreditProvider.objects.get_or_create( provider_id='ASU', display_name='Arizona State University', provider_url=self.PROVIDER_URL, provider_status_url=self.PROVIDER_STATUS_URL, provider_description=self.PROVIDER_DESCRIPTION, enable_integration=self.ENABLE_INTEGRATION, fulfillment_instructions=self.FULFILLMENT_INSTRUCTIONS, thumbnail_url=self.THUMBNAIL_URL ) self.assertFalse(hasattr(self.worker_user, 'profile'))
def get_credit_provider_attribute_values(course_key, attribute_name): """Get the course information from ecommerce and parse the data to get providers. Arguments: course_key (CourseKey): The identifier for the course. attribute_name (String): Name of the attribute of credit provider. Returns: List of provided credit provider attribute values. """ course_id = six.text_type(course_key) credit_config = CreditConfig.current() cache_key = None attribute_values = None if credit_config.is_cache_enabled: cache_key = '{key_prefix}.{course_key}.{attribute_name}'.format( key_prefix=credit_config.CACHE_KEY, course_key=course_id, attribute_name=attribute_name ) attribute_values = cache.get(cache_key) if attribute_values is not None: return attribute_values try: user = User.objects.get(username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME) response = ecommerce_api_client(user).courses(course_id).get(include_products=1) except Exception: # pylint: disable=broad-except log.exception(u"Failed to receive data from the ecommerce course API for Course ID '%s'.", course_id) return attribute_values if not response: log.info(u"No Course information found from ecommerce API for Course ID '%s'.", course_id) return attribute_values provider_ids = [] for product in response.get('products'): provider_ids += [ attr.get('value') for attr in product.get('attribute_values') if attr.get('name') == 'credit_provider' ] attribute_values = [] credit_providers = CreditProvider.get_credit_providers() for provider in credit_providers: if provider['id'] in provider_ids: attribute_values.append(provider[attribute_name]) if credit_config.is_cache_enabled: cache.set(cache_key, attribute_values, credit_config.cache_ttl) return attribute_values
def get_credit_provider_display_names(course_key): """Get the course information from ecommerce and parse the data to get providers. Arguments: course_key (CourseKey): The identifier for the course. Returns: List of credit provider display names. """ course_id = unicode(course_key) credit_config = CreditConfig.current() cache_key = None provider_names = None if credit_config.is_cache_enabled: cache_key = "{key_prefix}.{course_key}".format(key_prefix=credit_config.CACHE_KEY, course_key=course_id) provider_names = cache.get(cache_key) if provider_names is not None: return provider_names try: user = User.objects.get(username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME) response = ecommerce_api_client(user).courses(course_id).get(include_products=1) except Exception: # pylint: disable=broad-except log.exception("Failed to receive data from the ecommerce course API for Course ID '%s'.", course_id) return provider_names if not response: log.info("No Course information found from ecommerce API for Course ID '%s'.", course_id) return provider_names provider_ids = [] for product in response.get("products"): provider_ids += [ attr.get("value") for attr in product.get("attribute_values") if attr.get("name") == "credit_provider" ] provider_names = [] credit_providers = CreditProvider.get_credit_providers() for provider in credit_providers: if provider["id"] in provider_ids: provider_names.append(provider["display_name"]) if credit_config.is_cache_enabled: cache.set(cache_key, provider_names, credit_config.cache_ttl) return provider_names
class CourseApiTests(CreditApiTestBase): """Test Python API for course product information.""" def setUp(self): super(CourseApiTests, self).setUp() self.worker_user = User.objects.create_user(username=TEST_ECOMMERCE_WORKER) self.add_credit_course(self.course_key) self.credit_config = CreditConfig(cache_ttl=100, enabled=True) self.credit_config.save() # Add another provider. CreditProvider.objects.get_or_create( provider_id='ASU', display_name='Arizona State University', provider_url=self.PROVIDER_URL, provider_status_url=self.PROVIDER_STATUS_URL, provider_description=self.PROVIDER_DESCRIPTION, enable_integration=self.ENABLE_INTEGRATION, fulfillment_instructions=self.FULFILLMENT_INSTRUCTIONS, thumbnail_url=self.THUMBNAIL_URL ) self.assertFalse(hasattr(self.worker_user, 'profile')) @httpretty.activate def test_get_credit_provider_display_names_method(self): """Verify that parsed providers list is returns after getting course production information.""" self._mock_ecommerce_courses_api(self.course_key, self.COURSE_API_RESPONSE) response_providers = get_credit_provider_display_names(self.course_key) self.assertListEqual(self.PROVIDERS_LIST, response_providers) @httpretty.activate @mock.patch('edx_rest_api_client.client.EdxRestApiClient.__init__') def test_get_credit_provider_display_names_method_with_exception(self, mock_init): """Verify that in case of any exception it logs the error and return.""" mock_init.side_effect = Exception response = get_credit_provider_display_names(self.course_key) self.assertTrue(mock_init.called) self.assertEqual(response, None) @httpretty.activate def test_get_credit_provider_display_names_caching(self): """Verify that providers list is cached.""" self.assertTrue(self.credit_config.is_cache_enabled) self._mock_ecommerce_courses_api(self.course_key, self.COURSE_API_RESPONSE) # Warm up the cache. response_providers = get_credit_provider_display_names(self.course_key) self.assertListEqual(self.PROVIDERS_LIST, response_providers) # Hit the cache. response_providers = get_credit_provider_display_names(self.course_key) self.assertListEqual(self.PROVIDERS_LIST, response_providers) # Verify only one request was made. self.assertEqual(len(httpretty.httpretty.latest_requests), 1) @httpretty.activate def test_get_credit_provider_display_names_without_caching(self): """Verify that providers list is not cached.""" self.credit_config.cache_ttl = 0 self.credit_config.save() self.assertFalse(self.credit_config.is_cache_enabled) self._mock_ecommerce_courses_api(self.course_key, self.COURSE_API_RESPONSE) response_providers = get_credit_provider_display_names(self.course_key) self.assertListEqual(self.PROVIDERS_LIST, response_providers) response_providers = get_credit_provider_display_names(self.course_key) self.assertListEqual(self.PROVIDERS_LIST, response_providers) self.assertEqual(len(httpretty.httpretty.latest_requests), 2) @httpretty.activate @ddt.data( (None, None), ({'products': []}, []), ( { 'products': [{'expires': '', 'attribute_values': [{'name': 'credit_provider', 'value': 'ASU'}]}] }, ['Arizona State University'] ), ( { 'products': [{'expires': '', 'attribute_values': [{'name': 'namespace', 'value': 'grade'}]}] }, [] ), ( { 'products': [ { 'expires': '', 'attribute_values': [ {'name': 'credit_provider', 'value': 'ASU'}, {'name': 'credit_provider', 'value': 'hogwarts'}, {'name': 'course_type', 'value': 'credit'} ] } ] }, ['Hogwarts School of Witchcraft and Wizardry', 'Arizona State University'] ) ) @ddt.unpack def test_get_provider_api_with_multiple_data(self, data, expected_data): self._mock_ecommerce_courses_api(self.course_key, data) response_providers = get_credit_provider_display_names(self.course_key) self.assertEqual(expected_data, response_providers) @httpretty.activate def test_get_credit_provider_display_names_without_providers(self): """Verify that if all providers are in-active than method return empty list.""" self._mock_ecommerce_courses_api(self.course_key, self.COURSE_API_RESPONSE) CreditProvider.objects.all().update(active=False) self.assertEqual(get_credit_provider_display_names(self.course_key), []) @ddt.data(None, ['asu'], ['asu', 'co'], ['asu', 'co', 'mit']) def test_make_providers_strings(self, providers): """ Verify that method returns given provider list as comma separated string. """ provider_string = make_providers_strings(providers) if not providers: self.assertEqual(provider_string, None) elif len(providers) == 1: self.assertEqual(provider_string, providers[0]) elif len(providers) == 2: self.assertEqual(provider_string, 'asu and co') else: self.assertEqual(provider_string, 'asu, co, and mit')