Commit 9278e7a2 by McKenzie Welter Committed by McKenzie Welter

endpoint to retrieve course and run data simultaneously

parent ba6a6cc6
import urllib
from rest_framework.reverse import reverse
from course_discovery.apps.api.v1.tests.test_views.mixins import APITestCase
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.tests.factories import CourseFactory, CourseRunFactory
class CatalogQueryViewSetTests(APITestCase):
def setUp(self):
super(CatalogQueryViewSetTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.client.force_authenticate(self.user)
self.course_run = CourseRunFactory(course__partner=self.partner)
self.course = CourseFactory(partner=self.partner, key='simple_key')
self.url_base = reverse('api:v1:catalog-query_contains')
self.error_message = 'CatalogQueryContains endpoint requires query and identifiers list(s)'
def test_contains_single_course_run(self):
""" Verify that a single course_run is contained in a query. """
qs = urllib.parse.urlencode({
'query': 'id:' + self.course_run.key,
'course_run_ids': self.course_run.key,
'course_uuids': self.course.uuid,
})
url = '{}/?{}'.format(self.url_base, qs)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.data,
{
self.course_run.key: True,
str(self.course.uuid): False
}
)
def test_contains_single_course(self):
""" Verify that a single course is contained in a query. """
qs = urllib.parse.urlencode({
'query': 'key:' + self.course.key,
'course_run_ids': self.course_run.key,
'course_uuids': self.course.uuid,
})
url = '{}/?{}'.format(self.url_base, qs)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.data,
{
self.course_run.key: False,
str(self.course.uuid): True
}
)
def test_contains_course_and_run(self):
""" Verify that both the course and the run are contained in the broadest query. """
qs = urllib.parse.urlencode({
'query': 'key:*',
'course_run_ids': self.course_run.key,
'course_uuids': self.course.uuid,
})
url = '{}/?{}'.format(self.url_base, qs)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.data,
{
self.course_run.key: True,
str(self.course.uuid): True
}
)
def test_no_identifiers(self):
""" Verify that a 400 status is returned if request does not contain any identifier lists. """
qs = urllib.parse.urlencode({
'query': 'id:*'
})
url = '{}/?{}'.format(self.url_base, qs)
response = self.client.get(url)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.data, self.error_message)
def test_no_query(self):
""" Verify that a 400 status is returned if request does not contain a querystring. """
qs = urllib.parse.urlencode({
'course_run_ids': self.course_run.key,
'course_uuids': self.course.uuid,
})
url = '{}/?{}'.format(self.url_base, qs)
response = self.client.get(url)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.data, self.error_message)
......@@ -4,6 +4,7 @@ from rest_framework import routers
from course_discovery.apps.api.v1.views import search as search_views
from course_discovery.apps.api.v1.views.affiliates import AffiliateWindowViewSet
from course_discovery.apps.api.v1.views.catalog_queries import CatalogQueryContainsViewSet
from course_discovery.apps.api.v1.views.catalogs import CatalogViewSet
from course_discovery.apps.api.v1.views.course_runs import CourseRunViewSet
from course_discovery.apps.api.v1.views.courses import CourseViewSet
......@@ -21,7 +22,8 @@ partners_router.register(r'affiliate_window/catalogs', AffiliateWindowViewSet, b
urlpatterns = [
url(r'^partners/', include(partners_router.urls, namespace='partners')),
url(r'search/typeahead', search_views.TypeaheadSearchView.as_view(), name='search-typeahead'),
url(r'currency', CurrencyView.as_view(), name='currency')
url(r'currency', CurrencyView.as_view(), name='currency'),
url(r'^catalog/query-contains/?', CatalogQueryContainsViewSet.as_view(), name='catalog-query_contains')
]
router = routers.SimpleRouter()
......
from uuid import UUID
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import DjangoModelPermissions, IsAuthenticated
from rest_framework.response import Response
from course_discovery.apps.course_metadata.models import Course, CourseRun
class CatalogQueryContainsViewSet(GenericAPIView):
permission_classes = (IsAuthenticated, DjangoModelPermissions)
queryset = Course.objects.all()
def get(self, request):
"""
Determine if a set of courses and/or course runs is found in the query results.
Returns
dict: mapping of course and run indentifiers included in the request to boolean values
indicating whether or not the associated course or run is contained in the queryset
described by the query found in the request.
"""
query = request.GET.get('query')
course_run_ids = request.GET.get('course_run_ids', None)
course_uuids = request.GET.get('course_uuids', None)
partner = self.request.site.partner
if query and (course_run_ids or course_uuids):
identified_course_ids = set()
specified_course_ids = []
if course_run_ids:
course_run_ids = course_run_ids.split(',')
specified_course_ids = course_run_ids
identified_course_ids.update(CourseRun.search(query).filter(
partner=partner.short_code, key__in=course_run_ids).values_list('key', flat=True))
if course_uuids:
course_uuids = [UUID(course_uuid) for course_uuid in course_uuids.split(',')]
specified_course_ids += course_uuids
identified_course_ids.update(Course.search(query).filter(partner=partner, uuid__in=course_uuids).
values_list('uuid', flat=True))
contains = {str(identifier): identifier in identified_course_ids for identifier in specified_course_ids}
return Response(contains)
return Response(
'CatalogQueryContains endpoint requires query and identifiers list(s)', status=status.HTTP_400_BAD_REQUEST
)
......@@ -118,6 +118,7 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
class CourseIndex(BaseCourseIndex, indexes.Indexable):
model = Course
uuid = indexes.CharField(model_attr='uuid')
course_runs = indexes.MultiValueField()
expected_learning_items = indexes.MultiValueField()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment