예제 #1
0
    def test_get_course_catalogs_for_failure(self):
        """
        Verify that method "get_course_catalogs" raises exception in case
        the Course Discovery API fails to return data.
        """
        self.mock_course_discovery_api_for_failure()

        with self.assertRaises(Exception):
            get_course_catalogs(self.request.site)
예제 #2
0
    def test_get_course_catalogs_for_failure(self):
        """
        Verify that method "get_course_catalogs" raises exception in case
        the Course Discovery API fails to return data.
        """
        exception = ConnectionError
        self.mock_course_discovery_api_for_catalogs_with_failure(exception)

        with self.assertRaises(exception):
            get_course_catalogs(self.request.site)
예제 #3
0
    def test_get_course_catalogs_for_failure(self):
        """
        Verify that method "get_course_catalogs" raises exception in case
        the Course Discovery API fails to return data.
        """
        exception = ConnectionError
        self.mock_access_token_response()
        self.mock_discovery_api_failure(exception, self.site_configuration.discovery_api_url)

        with self.assertRaises(exception):
            get_course_catalogs(self.request.site)
예제 #4
0
    def contains_product(self, product):
        """
        Assert if the range contains the product.
        """
        if self.course_catalog:
            request = get_current_request()
            try:
                course_catalog = get_course_catalogs(site=request.site, resource_id=self.course_catalog)
            except (ConnectionError, SlumberBaseException, Timeout):
                raise Exception(
                    'Unable to connect to Course Catalog service for catalog with id [%s].' % self.course_catalog
                )

            response = self.run_catalog_query(product, course_catalog.get('query'))
            # Range can have a catalog query and 'regular' products in it,
            # therefor an OR is used to check for both possibilities.
            return ((response['course_runs'][product.course_id]) or
                    super(Range, self).contains_product(product))  # pylint: disable=bad-super-call
        elif self.catalog_query and self.course_seat_types:
            if product.attr.certificate_type.lower() in self.course_seat_types:  # pylint: disable=unsupported-membership-test
                response = self.run_catalog_query(product)
                # Range can have a catalog query and 'regular' products in it,
                # therefor an OR is used to check for both possibilities.
                return ((response['course_runs'][product.course_id]) or
                        super(Range, self).contains_product(product))  # pylint: disable=bad-super-call
        elif self.catalog:
            return (
                product.id in self.catalog.stock_records.values_list('product', flat=True) or
                super(Range, self).contains_product(product)  # pylint: disable=bad-super-call
            )
        return super(Range, self).contains_product(product)  # pylint: disable=bad-super-call
예제 #5
0
    def test_get_course_catalogs_for_single_catalog_with_id(self):
        """
        Verify that method "get_course_catalogs" returns proper response for a
        single catalog by its id.
        """
        self.mock_access_token_response()
        self.mock_catalog_detail_endpoint(
            self.site_configuration.discovery_api_url)

        catalog_id = 1
        resource = "catalogs"
        cache_key = get_cache_key(site_domain=self.site.domain,
                                  resource="{}-{}".format(
                                      resource, catalog_id))
        course_catalogs_cached_response = TieredCache.get_cached_response(
            cache_key)
        self.assertFalse(course_catalogs_cached_response.is_found)

        response = get_course_catalogs(self.request.site, catalog_id)
        self.assertEqual(response['name'], 'All Courses')

        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertEqual(course_cached_response.value, response)

        # Verify the API was actually hit (not the cache)
        self._assert_num_requests(2)
예제 #6
0
    def test_get_course_catalogs_for_single_catalog_with_id(self):
        """
        Verify that method "get_course_catalogs" returns proper response for a
        single catalog by its id.
        """
        self.mock_access_token_response()
        self.mock_catalog_detail_endpoint(
            self.site_configuration.discovery_api_url)

        catalog_id = 1
        cache_key = u'{}.catalog.api.data.{}'.format(self.request.site.domain,
                                                     catalog_id)
        cache_key = hashlib.md5(cache_key.encode('utf-8')).hexdigest()
        course_catalogs_cached_response = TieredCache.get_cached_response(
            cache_key)
        self.assertFalse(course_catalogs_cached_response.is_found)

        response = get_course_catalogs(self.request.site, catalog_id)
        self.assertEqual(response['name'], 'All Courses')

        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertEqual(course_cached_response.value, response)

        # Verify the API was actually hit (not the cache)
        self._assert_num_requests(2)
예제 #7
0
def is_course_in_enterprise_catalog(site, course_id, enterprise_catalog_id):
    """
    Verify that the provided course id exists in the site base list of course
    run keys from the provided enterprise course catalog.

    Arguments:
        course_id (str): The course ID.
        site: (django.contrib.sites.Site) site instance
        enterprise_catalog_id (Int): Course catalog id of enterprise

    Returns:
        Boolean

    """
    try:
        enterprise_course_catalog = get_course_catalogs(
            site=site, resource_id=enterprise_catalog_id)
    except (ConnectionError, SlumberBaseException, Timeout):
        logger.exception(
            'Unable to connect to Course Catalog service for course catalogs.')
        return None

    if is_course_in_catalog_query(site, course_id,
                                  enterprise_course_catalog.get('query')):
        return True

    return False
예제 #8
0
    def test_get_course_catalogs_for_single_page_api_response(self, catalog_name_list):
        """
        Verify that method "get_course_catalogs" returns proper response for
        single page Course Discovery API response and uses cache to return data
        in case of same API request.
        """
        self.mock_course_discovery_api_for_catalogs(catalog_name_list)

        self._assert_get_course_catalogs(catalog_name_list)

        # Verify the API was hit once
        self._assert_num_requests(1)

        # Now fetch the catalogs again and there should be no more actual call
        # to Course Discovery API as the data will be fetched from the cache
        get_course_catalogs(self.request.site)
        self._assert_num_requests(1)
예제 #9
0
    def test_get_course_catalogs_for_single_page_api_response(
            self, catalog_name_list):
        """
        Verify that method "get_course_catalogs" returns proper response for
        single page Course Discovery API response and uses cache to return data
        in case of same API request.
        """
        self.mock_course_discovery_api_for_catalogs(catalog_name_list)

        self._assert_get_course_catalogs(catalog_name_list)

        # Verify the API was hit once
        self._assert_num_requests(1)

        # Now fetch the catalogs again and there should be no more actual call
        # to Course Discovery API as the data will be fetched from the cache
        get_course_catalogs(self.request.site)
        self._assert_num_requests(1)
예제 #10
0
    def course_catalogs(self, request):
        """
        Returns response with all course catalogs in the format:
        ["results": {"id": 1, "name": "Dummy Catalog"}]
        """
        try:
            results = get_course_catalogs(site=request.site)
        except:  # pylint: disable=bare-except
            logger.exception('Failed to retrieve course catalogs data from the Course Discovery API.')
            results = []

        # Create catalogs list with sorting by name
        catalogs = [{'id': catalog['id'], 'name': catalog['name']} for catalog in results]
        data = {'results': sorted(catalogs, key=lambda catalog: catalog.get('name', '').lower())}
        return Response(data=data)
예제 #11
0
    def course_catalogs(self, request):
        """
        Returns response with all course catalogs in the format:
        ["results": {"id": 1, "name": "Dummy Catalog"}]
        """
        try:
            results = get_course_catalogs(site=request.site)
        except:  # pylint: disable=bare-except
            logger.exception('Failed to retrieve course catalogs data from the Course Discovery API.')
            results = []

        # Create catalogs list with sorting by name
        catalogs = [{'id': catalog['id'], 'name': catalog['name']} for catalog in results]
        data = {'results': sorted(catalogs, key=lambda catalog: catalog.get('name', '').lower())}
        return Response(data=data)
예제 #12
0
    def _assert_get_course_catalogs(self, catalog_name_list):
        """
        Helper method to validate the response from the method
        "get_course_catalogs".
        """
        cache_key = '{}.catalog.api.data'.format(self.request.site.domain)
        cache_key = hashlib.md5(cache_key).hexdigest()
        cached_course_catalogs = cache.get(cache_key)
        self.assertIsNone(cached_course_catalogs)

        response = get_course_catalogs(self.request.site)

        self.assertEqual(len(response), len(catalog_name_list))
        for catalog_index, catalog in enumerate(response):
            self.assertEqual(catalog['name'], catalog_name_list[catalog_index])

        cached_course = cache.get(cache_key)
        self.assertEqual(cached_course, response)
예제 #13
0
    def _assert_get_course_catalogs(self, catalog_name_list):
        """
        Helper method to validate the response from the method
        "get_course_catalogs".
        """
        cache_key = '{}.catalog.api.data'.format(self.request.site.domain)
        cache_key = hashlib.md5(cache_key).hexdigest()
        cached_course_catalogs = cache.get(cache_key)
        self.assertIsNone(cached_course_catalogs)

        response = get_course_catalogs(self.request.site)

        self.assertEqual(len(response), len(catalog_name_list))
        for catalog_index, catalog in enumerate(response):
            self.assertEqual(catalog['name'], catalog_name_list[catalog_index])

        cached_course = cache.get(cache_key)
        self.assertEqual(cached_course, response)
예제 #14
0
    def _assert_get_course_catalogs(self, catalog_name_list):
        """
        Helper method to validate the response from the method
        "get_course_catalogs".
        """
        cache_key = u'{}.catalog.api.data'.format(self.request.site.domain)
        cache_key = hashlib.md5(cache_key.encode('utf-8')).hexdigest()
        course_catalogs_cached_response = TieredCache.get_cached_response(
            cache_key)
        self.assertFalse(course_catalogs_cached_response.is_found)

        response = get_course_catalogs(self.request.site)

        self.assertEqual(len(response), len(catalog_name_list))
        for catalog_index, catalog in enumerate(response):
            self.assertEqual(catalog['name'], catalog_name_list[catalog_index])

        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertEqual(course_cached_response.value, response)
예제 #15
0
def get_course_ids_from_voucher(site, voucher):
    """
    Get site base list of course run keys from the provided voucher object.

    Arguments:
        site: (django.contrib.sites.Site) site instance
        voucher (Voucher): voucher class object

    Returns:
        list of course ids

    """
    voucher_offer = voucher.offers.first()
    offer_range = voucher_offer.condition.range
    if offer_range.course_catalog:
        try:
            course_catalog = get_course_catalogs(site=site, resource_id=offer_range.course_catalog)
        except (ConnectionError, SlumberBaseException, Timeout):
            logger.error('Unable to connect to Course Catalog service for course catalogs.')
            return None

        try:
            course_runs = get_catalog_course_runs(site, course_catalog.get('query'))['results']
        except (ConnectionError, SlumberBaseException, Timeout, KeyError):
            logger.error('Unable to get course runs from Course Catalog service.')
            return None

        voucher_course_ids = [course_run.get('key') for course_run in course_runs if course_run.get('key')]
    elif offer_range.catalog_query:
        try:
            course_runs = get_catalog_course_runs(site, offer_range.catalog_query)['results']
        except (ConnectionError, SlumberBaseException, Timeout, KeyError):
            logger.error('Unable to get course runs from Course Catalog service.')
            return None

        voucher_course_ids = [course_run.get('key') for course_run in course_runs if course_run.get('key')]
    else:
        stock_records = offer_range.catalog.stock_records.all()
        seats = Product.objects.filter(id__in=[sr.product.id for sr in stock_records])
        voucher_course_ids = [seat.course_id for seat in seats]

    return voucher_course_ids
예제 #16
0
    def _assert_get_course_catalogs(self, catalog_name_list):
        """
        Helper method to validate the response from the method
        "get_course_catalogs".
        """
        resource = "catalogs"
        cache_key = get_cache_key(site_domain=self.site.domain,
                                  resource=resource)
        course_catalogs_cached_response = TieredCache.get_cached_response(
            cache_key)
        self.assertFalse(course_catalogs_cached_response.is_found)

        response = get_course_catalogs(self.request.site)

        self.assertEqual(len(response), len(catalog_name_list))
        for catalog_index, catalog in enumerate(response):
            self.assertEqual(catalog['name'], catalog_name_list[catalog_index])

        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertEqual(course_cached_response.value, response)
예제 #17
0
    def test_get_course_catalogs_for_single_catalog_with_id(self):
        """
        Verify that method "get_course_catalogs" returns proper response for a
        single catalog by its id.
        """
        self.mock_course_discovery_api_for_catalog_by_resource_id()

        catalog_id = 1
        cache_key = '{}.catalog.api.data.{}'.format(self.request.site.domain, catalog_id)
        cache_key = hashlib.md5(cache_key).hexdigest()
        cached_course_catalog = cache.get(cache_key)
        self.assertIsNone(cached_course_catalog)

        response = get_course_catalogs(self.request.site, catalog_id)
        self.assertEqual(response['name'], 'Catalog {}'.format(catalog_id))

        cached_course = cache.get(cache_key)
        self.assertEqual(cached_course, response)

        # Verify the API was actually hit (not the cache)
        self._assert_num_requests(1)
예제 #18
0
    def test_get_course_catalogs_for_single_catalog_with_id(self):
        """
        Verify that method "get_course_catalogs" returns proper response for a
        single catalog by its id.
        """
        self.mock_course_discovery_api_for_catalog_by_resource_id()

        catalog_id = 1
        cache_key = '{}.catalog.api.data.{}'.format(self.request.site.domain,
                                                    catalog_id)
        cache_key = hashlib.md5(cache_key).hexdigest()
        cached_course_catalog = cache.get(cache_key)
        self.assertIsNone(cached_course_catalog)

        response = get_course_catalogs(self.request.site, catalog_id)
        self.assertEqual(response['name'], 'Catalog {}'.format(catalog_id))

        cached_course = cache.get(cache_key)
        self.assertEqual(cached_course, response)

        # Verify the API was actually hit (not the cache)
        self._assert_num_requests(1)