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
aef89279
Commit
aef89279
authored
May 04, 2016
by
Marko Jevtic
Committed by
Peter Fogg
May 19, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SOL-1772] Add seat type query API endpoint
parent
56c37d0e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
98 additions
and
4 deletions
+98
-4
course_discovery/apps/api/serializers.py
+7
-0
course_discovery/apps/api/tests/test_serializers.py
+13
-1
course_discovery/apps/api/v1/tests/test_views/test_course_runs.py
+38
-1
course_discovery/apps/api/v1/views.py
+40
-2
No files found.
course_discovery/apps/api/serializers.py
View file @
aef89279
...
...
@@ -151,6 +151,13 @@ class CourseRunSerializer(TimestampModelSerializer):
)
class
ContainedCourseRunsSerializer
(
serializers
.
Serializer
):
# pylint: disable=abstract-method
course_runs
=
serializers
.
DictField
(
child
=
serializers
.
BooleanField
(),
help_text
=
_
(
'Dictionary mapping course run IDs to boolean values'
)
)
class
CourseSerializer
(
TimestampModelSerializer
):
level_type
=
serializers
.
SlugRelatedField
(
read_only
=
True
,
slug_field
=
'name'
)
subjects
=
SubjectSerializer
(
many
=
True
)
...
...
course_discovery/apps/api/tests/test_serializers.py
View file @
aef89279
...
...
@@ -8,7 +8,7 @@ from rest_framework.test import APIRequestFactory
from
course_discovery.apps.api.serializers
import
(
CatalogSerializer
,
CourseSerializer
,
CourseRunSerializer
,
ContainedCoursesSerializer
,
ImageSerializer
,
SubjectSerializer
,
PrerequisiteSerializer
,
VideoSerializer
,
OrganizationSerializer
,
SeatSerializer
,
PersonSerializer
,
AffiliateWindowSerializer
PersonSerializer
,
AffiliateWindowSerializer
,
ContainedCourseRunsSerializer
)
from
course_discovery.apps.catalogs.tests.factories
import
CatalogFactory
from
course_discovery.apps.core.models
import
User
...
...
@@ -156,6 +156,18 @@ class CourseRunSerializerTests(TestCase):
self
.
assertDictEqual
(
serializer
.
data
,
expected
)
class
ContainedCourseRunsSerializerTests
(
TestCase
):
def
test_data
(
self
):
instance
=
{
'course_runs'
:
{
'course-v1:edX+DemoX+Demo_Course'
:
True
,
'a/b/c'
:
False
}
}
serializer
=
ContainedCourseRunsSerializer
(
instance
)
self
.
assertDictEqual
(
serializer
.
data
,
instance
)
class
ContainedCoursesSerializerTests
(
TestCase
):
def
test_data
(
self
):
instance
=
{
...
...
course_discovery/apps/api/v1/tests/test_views/test_course_runs.py
View file @
aef89279
# pylint: disable=no-member
import
urllib
import
ddt
from
django.db.models.functions
import
Lower
from
rest_framework.reverse
import
reverse
from
rest_framework.test
import
APITestCase
from
course_discovery.apps.api.serializers
import
CourseRunSerializer
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
CourseRunFactory
from
course_discovery.apps.course_metadata.models
import
CourseRun
class
CourseRunViewSetTests
(
APITestCase
):
@ddt.ddt
class
CourseRunViewSetTests
(
ElasticsearchTestMixin
,
APITestCase
):
def
setUp
(
self
):
super
(
CourseRunViewSetTests
,
self
)
.
setUp
()
self
.
user
=
UserFactory
(
is_staff
=
True
,
is_superuser
=
True
)
self
.
client
.
force_authenticate
(
self
.
user
)
self
.
course_run
=
CourseRunFactory
()
self
.
refresh_index
()
def
test_get
(
self
):
""" Verify the endpoint returns the details for a single course. """
...
...
@@ -49,3 +55,34 @@ class CourseRunViewSetTests(APITestCase):
CourseRunSerializer
(
course_runs
,
many
=
True
)
.
data
,
key
=
lambda
course_run
:
course_run
[
'key'
]
)
self
.
assertListEqual
(
actual_sorted
,
expected_sorted
)
def
test_contains
(
self
):
qs
=
urllib
.
parse
.
urlencode
({
'query'
:
'id:course*'
,
'course_run_ids'
:
self
.
course_run
.
key
})
url
=
'{}?{}'
.
format
(
reverse
(
'api:v1:course_run-contains'
),
qs
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
data
,
{
'course_runs'
:
{
self
.
course_run
.
key
:
True
}
}
)
@ddt.data
(
{
'params'
:
{
'course_run_ids'
:
'a/b/c'
}},
{
'params'
:
{
'query'
:
'id:course*'
}},
{
'params'
:
{}}
)
@ddt.unpack
def
test_contains_missing_parameter
(
self
,
params
):
qs
=
urllib
.
parse
.
urlencode
(
params
)
url
=
'{}?{}'
.
format
(
reverse
(
'api:v1:course_run-contains'
),
qs
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
400
)
course_discovery/apps/api/v1/views.py
View file @
aef89279
...
...
@@ -7,7 +7,7 @@ from django.db.models.functions import Lower
from
django.shortcuts
import
get_object_or_404
from
dry_rest_permissions.generics
import
DRYPermissions
from
edx_rest_framework_extensions.permissions
import
IsSuperuser
from
rest_framework
import
viewsets
from
rest_framework
import
status
,
viewsets
from
rest_framework.decorators
import
detail_route
,
list_route
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework.response
import
Response
...
...
@@ -15,7 +15,7 @@ from rest_framework.response import Response
from
course_discovery.apps.api.filters
import
PermissionsFilter
from
course_discovery.apps.api.serializers
import
(
CatalogSerializer
,
CourseSerializer
,
CourseRunSerializer
,
ContainedCoursesSerializer
,
CourseSerializerExcludingClosedRuns
,
AffiliateWindowSerializer
CourseSerializerExcludingClosedRuns
,
AffiliateWindowSerializer
,
ContainedCourseRunsSerializer
)
from
course_discovery.apps.api.renderers
import
AffiliateWindowXMLRenderer
from
course_discovery.apps.catalogs.models
import
Catalog
...
...
@@ -183,6 +183,44 @@ class CourseRunViewSet(viewsets.ReadOnlyModelViewSet):
""" Retrieve details for a course run. """
return
super
(
CourseRunViewSet
,
self
)
.
retrieve
(
request
,
*
args
,
**
kwargs
)
@list_route
()
def
contains
(
self
,
request
):
"""
Determine if course runs are found in the query results.
A dictionary mapping course run keys to booleans,
indicating course run presence, will be returned.
---
serializer: ContainedCourseRunsSerializer
parameters:
- name: query
description: Elasticsearch querystring query
required: true
type: string
paramType: query
multiple: false
- name: course_run_ids
description: Comma-separated list of course run IDs
required: true
type: string
paramType: query
multiple: true
"""
query
=
request
.
GET
.
get
(
'query'
)
course_run_ids
=
request
.
GET
.
get
(
'course_run_ids'
)
if
query
and
course_run_ids
:
course_runs
=
CourseRun
.
search
(
query
)
contains
=
{
course_run_id
:
False
for
course_run_id
in
course_run_ids
.
split
(
','
)}
for
course_run
in
course_runs
:
contains
[
course_run
.
key
]
=
True
instance
=
{
'course_runs'
:
contains
}
serializer
=
ContainedCourseRunsSerializer
(
instance
)
return
Response
(
serializer
.
data
)
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
)
class
ManagementViewSet
(
viewsets
.
ViewSet
):
permission_classes
=
(
IsSuperuser
,)
...
...
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