Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
course-discovery
Commits
9278e7a2
Commit
9278e7a2
authored
Feb 21, 2018
by
McKenzie Welter
Committed by
McKenzie Welter
Mar 08, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
endpoint to retrieve course and run data simultaneously
parent
ba6a6cc6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
144 additions
and
1 deletions
+144
-1
course_discovery/apps/api/v1/tests/test_views/test_catalog_queries.py
+93
-0
course_discovery/apps/api/v1/urls.py
+3
-1
course_discovery/apps/api/v1/views/catalog_queries.py
+47
-0
course_discovery/apps/course_metadata/search_indexes.py
+1
-0
No files found.
course_discovery/apps/api/v1/tests/test_views/test_catalog_queries.py
0 → 100644
View file @
9278e7a2
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
)
course_discovery/apps/api/v1/urls.py
View file @
9278e7a2
...
@@ -4,6 +4,7 @@ from rest_framework import routers
...
@@ -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
import
search
as
search_views
from
course_discovery.apps.api.v1.views.affiliates
import
AffiliateWindowViewSet
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.catalogs
import
CatalogViewSet
from
course_discovery.apps.api.v1.views.course_runs
import
CourseRunViewSet
from
course_discovery.apps.api.v1.views.course_runs
import
CourseRunViewSet
from
course_discovery.apps.api.v1.views.courses
import
CourseViewSet
from
course_discovery.apps.api.v1.views.courses
import
CourseViewSet
...
@@ -21,7 +22,8 @@ partners_router.register(r'affiliate_window/catalogs', AffiliateWindowViewSet, b
...
@@ -21,7 +22,8 @@ partners_router.register(r'affiliate_window/catalogs', AffiliateWindowViewSet, b
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^partners/'
,
include
(
partners_router
.
urls
,
namespace
=
'partners'
)),
url
(
r'^partners/'
,
include
(
partners_router
.
urls
,
namespace
=
'partners'
)),
url
(
r'search/typeahead'
,
search_views
.
TypeaheadSearchView
.
as_view
(),
name
=
'search-typeahead'
),
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
()
router
=
routers
.
SimpleRouter
()
...
...
course_discovery/apps/api/v1/views/catalog_queries.py
0 → 100644
View file @
9278e7a2
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
)
course_discovery/apps/course_metadata/search_indexes.py
View file @
9278e7a2
...
@@ -118,6 +118,7 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
...
@@ -118,6 +118,7 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
class
CourseIndex
(
BaseCourseIndex
,
indexes
.
Indexable
):
class
CourseIndex
(
BaseCourseIndex
,
indexes
.
Indexable
):
model
=
Course
model
=
Course
uuid
=
indexes
.
CharField
(
model_attr
=
'uuid'
)
course_runs
=
indexes
.
MultiValueField
()
course_runs
=
indexes
.
MultiValueField
()
expected_learning_items
=
indexes
.
MultiValueField
()
expected_learning_items
=
indexes
.
MultiValueField
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment