Commit 5f25faf1 by zubair-arbi Committed by Zubair Afzal

add support for course run key in catalog contains endpoint

ENT-201
parent ff0ac78a
......@@ -59,6 +59,20 @@ class CatalogViewSetTests(ElasticsearchTestMixin, SerializationMixin, OAuth2Mixi
self.assertEqual(catalog.query, query)
self.assertListEqual(list(catalog.viewers), [viewer])
def assert_catalog_contains_query_string(self, query_string_kwargs, course_key):
"""
Helper method to validate the provided course key or course run key
in the catalog contains endpoint.
"""
query_string = urllib.parse.urlencode(query_string_kwargs)
url = '{base_url}?{query_string}'.format(
base_url=reverse('api:v1:catalog-contains', kwargs={'id': self.catalog.id}),
query_string=query_string
)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, {'courses': {course_key: True}})
def grant_catalog_permission_to_user(self, user, action, catalog=None):
""" Grant the user access to view `self.catalog`. """
catalog = catalog or self.catalog
......@@ -152,18 +166,24 @@ class CatalogViewSetTests(ElasticsearchTestMixin, SerializationMixin, OAuth2Mixi
assert response.status_code == 200
assert response.data['results'] == self.serialize_catalog_course(courses, many=True)
def test_contains(self):
""" Verify the endpoint returns a filtered list of courses contained in the catalog. """
def test_contains_for_course_key(self):
"""
Verify the endpoint returns a filtered list of courses contained in
the catalog for course keys with the format "org+course".
"""
course_key = self.course.key
query_string = urllib.parse.urlencode({'course_id': course_key})
url = '{base_url}?{query_string}'.format(
base_url=reverse('api:v1:catalog-contains', kwargs={'id': self.catalog.id}),
query_string=query_string
)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, {'courses': {course_key: True}})
query_string_kwargs = {'course_id': course_key}
self.assert_catalog_contains_query_string(query_string_kwargs, course_key)
def test_contains_for_course_run_key(self):
"""
Verify the endpoint returns a filtered list of courses contained in
the catalog for course run keys with the format "org/course/run" or
"course-v1:org+course+key".
"""
course_run_key = self.course_run.key
query_string_kwargs = {'course_run_id': course_run_key}
self.assert_catalog_contains_query_string(query_string_kwargs, course_run_key)
def test_csv(self):
SeatFactory(type='audit', course_run=self.course_run)
......
......@@ -113,12 +113,25 @@ class CatalogViewSet(viewsets.ModelViewSet):
type: string
paramType: query
multiple: true
- name: course_run_id
description: Course run IDs to check for existence in the Catalog.
required: false
type: string
paramType: query
multiple: true
"""
course_ids = request.query_params.get('course_id')
course_ids = course_ids.split(',')
course_run_ids = request.query_params.get('course_run_id')
catalog = self.get_object()
courses = catalog.contains(course_ids)
courses = {}
if course_ids:
course_ids = course_ids.split(',')
courses.update(catalog.contains(course_ids))
if course_run_ids:
course_run_ids = course_run_ids.split(',')
courses.update(catalog.contains_course_runs(course_run_ids))
instance = {'courses': courses}
serializer = serializers.ContainedCoursesSerializer(instance)
......
......@@ -7,7 +7,7 @@ from guardian.shortcuts import get_users_with_perms
from haystack.query import SearchQuerySet
from course_discovery.apps.core.mixins import ModelPermissionsMixin
from course_discovery.apps.course_metadata.models import Course
from course_discovery.apps.course_metadata.models import Course, CourseRun
class Catalog(ModelPermissionsMixin, TimeStampedModel):
......@@ -56,6 +56,23 @@ class Catalog(ModelPermissionsMixin, TimeStampedModel):
return contains
def contains_course_runs(self, course_run_ids): # pylint: disable=unused-argument
"""
Determines if the given course runs are contained in this catalog.
Arguments:
course_run_ids (str[]): List of course run IDs
Returns:
dict: Mapping of course IDs to booleans indicating if course run is
contained in this catalog.
"""
contains = {course_run_id: False for course_run_id in course_run_ids}
course_runs = CourseRun.search(self.query).filter(key__in=course_run_ids).values_list('key', flat=True)
contains.update({course_run_id: course_run_id in course_runs for course_run_id in course_run_ids})
return contains
@property
def viewers(self):
""" Returns a QuerySet of users who have been granted explicit access to view this Catalog.
......
......@@ -5,7 +5,7 @@ from course_discovery.apps.catalogs.models import Catalog
from course_discovery.apps.catalogs.tests import factories
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.core.tests.mixins import ElasticsearchTestMixin
from course_discovery.apps.course_metadata.tests.factories import CourseFactory
from course_discovery.apps.course_metadata.tests.factories import CourseFactory, CourseRunFactory
@ddt.ddt
......@@ -39,6 +39,15 @@ class CatalogTests(ElasticsearchTestMixin, TestCase):
{self.course.key: True, uncontained_course.key: False}
)
def test_contains_course_runs(self):
""" Verify the method returns a mapping of course run IDs to booleans. """
course_run = CourseRunFactory(course=self.course)
uncontained_course_run = CourseRunFactory(title_override='ABD')
self.assertDictEqual(
self.catalog.contains_course_runs([course_run.key, uncontained_course_run.key]),
{course_run.key: True, uncontained_course_run.key: False}
)
def test_courses_count(self):
""" Verify the method returns the number of courses contained in the Catalog. """
self.assertEqual(self.catalog.courses_count, 1)
......
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