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
cf4605e5
Commit
cf4605e5
authored
Aug 31, 2016
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated search API endpoints
The endpoints now only return published objects. ECOM-5414
parent
2a83c0ee
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
68 additions
and
21 deletions
+68
-21
course_discovery/apps/api/serializers.py
+2
-1
course_discovery/apps/api/tests/test_serializers.py
+3
-0
course_discovery/apps/api/v1/tests/test_views/test_search.py
+58
-18
course_discovery/apps/api/v1/views.py
+5
-2
No files found.
course_discovery/apps/api/serializers.py
View file @
cf4605e5
...
...
@@ -45,7 +45,7 @@ COURSE_RUN_FACET_FIELD_QUERIES = {
COURSE_RUN_SEARCH_FIELDS
=
(
'text'
,
'key'
,
'title'
,
'short_description'
,
'full_description'
,
'start'
,
'end'
,
'enrollment_start'
,
'enrollment_end'
,
'pacing_type'
,
'language'
,
'transcript_languages'
,
'marketing_url'
,
'content_type'
,
'org'
,
'number'
,
'seat_types'
,
'image_url'
,
'type'
,
'level_type'
,
'availability'
,
'number'
,
'seat_types'
,
'image_url'
,
'type'
,
'level_type'
,
'availability'
,
'published'
,
)
PROGRAM_FACET_FIELD_OPTIONS
=
{
...
...
@@ -57,6 +57,7 @@ PROGRAM_FACET_FIELD_OPTIONS = {
BASE_PROGRAM_FIELDS
=
(
'text'
,
'uuid'
,
'title'
,
'subtitle'
,
'type'
,
'marketing_url'
,
'content_type'
,
'status'
,
'card_image_url'
,
'published'
,
)
PROGRAM_SEARCH_FIELDS
=
BASE_PROGRAM_FIELDS
+
(
'authoring_organizations'
,)
...
...
course_discovery/apps/api/tests/test_serializers.py
View file @
cf4605e5
...
...
@@ -606,6 +606,7 @@ class CourseRunSearchSerializerTests(TestCase):
'type'
:
course_run
.
type
,
'level_type'
:
course_run
.
level_type
.
name
,
'availability'
:
course_run
.
availability
,
'published'
:
course_run
.
status
==
CourseRun
.
Status
.
Published
,
}
self
.
assertDictEqual
(
serializer
.
data
,
expected
)
...
...
@@ -648,6 +649,7 @@ class ProgramSearchSerializerTests(TestCase):
'content_type'
:
'program'
,
'card_image_url'
:
program
.
card_image_url
,
'status'
:
program
.
status
,
'published'
:
program
.
status
==
Program
.
Status
.
Active
,
}
self
.
assertDictEqual
(
serializer
.
data
,
expected
)
...
...
@@ -668,5 +670,6 @@ class ProgramSearchSerializerTests(TestCase):
'content_type'
:
'program'
,
'card_image_url'
:
program
.
card_image_url
,
'status'
:
program
.
status
,
'published'
:
program
.
status
==
Program
.
Status
.
Active
,
}
self
.
assertDictEqual
(
serializer
.
data
,
expected
)
course_discovery/apps/api/v1/tests/test_views/test_search.py
View file @
cf4605e5
...
...
@@ -7,24 +7,36 @@ from django.core.urlresolvers import reverse
from
haystack.query
import
SearchQuerySet
from
rest_framework.test
import
APITestCase
from
course_discovery.apps.api.serializers
import
CourseRunSearchSerializer
from
course_discovery.apps.api.serializers
import
CourseRunSearchSerializer
,
ProgramSearchSerializer
from
course_discovery.apps.core.tests.factories
import
UserFactory
,
USER_PASSWORD
from
course_discovery.apps.core.tests.mixins
import
ElasticsearchTestMixin
from
course_discovery.apps.course_metadata.models
import
CourseRun
from
course_discovery.apps.course_metadata.tests.factories
import
CourseRunFactory
from
course_discovery.apps.course_metadata.models
import
CourseRun
,
Program
from
course_discovery.apps.course_metadata.tests.factories
import
CourseRunFactory
,
ProgramFactory
@ddt.ddt
class
CourseRunSearchViewSetTests
(
ElasticsearchTestMixin
,
APITestCase
):
""" Tests for CourseRunSearchViewSet. """
faceted_path
=
reverse
(
'api:v1:search-course_runs-facets'
)
list_path
=
reverse
(
'api:v1:search-course_runs-list'
)
class
SerializationMixin
:
def
serialize_course_run
(
self
,
course_run
):
result
=
SearchQuerySet
()
.
models
(
CourseRun
)
.
filter
(
key
=
course_run
.
key
)[
0
]
return
CourseRunSearchSerializer
(
result
)
.
data
def
serialize_program
(
self
,
program
):
result
=
SearchQuerySet
()
.
models
(
Program
)
.
filter
(
uuid
=
program
.
uuid
)[
0
]
return
ProgramSearchSerializer
(
result
)
.
data
class
LoginMixin
:
def
setUp
(
self
):
super
(
CourseRunSearchViewSetTests
,
self
)
.
setUp
()
super
(
LoginMixin
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
USER_PASSWORD
)
@ddt.ddt
class
CourseRunSearchViewSetTests
(
SerializationMixin
,
LoginMixin
,
ElasticsearchTestMixin
,
APITestCase
):
""" Tests for CourseRunSearchViewSet. """
faceted_path
=
reverse
(
'api:v1:search-course_runs-facets'
)
list_path
=
reverse
(
'api:v1:search-course_runs-list'
)
def
get_search_response
(
self
,
query
=
None
,
faceted
=
False
):
qs
=
''
...
...
@@ -35,10 +47,6 @@ class CourseRunSearchViewSetTests(ElasticsearchTestMixin, APITestCase):
url
=
'{path}?{qs}'
.
format
(
path
=
path
,
qs
=
qs
)
return
self
.
client
.
get
(
url
)
def
serialize_course_run
(
self
,
course_run
):
result
=
SearchQuerySet
()
.
models
(
CourseRun
)
.
filter
(
key
=
course_run
.
key
)[
0
]
return
CourseRunSearchSerializer
(
result
)
.
data
@ddt.data
(
True
,
False
)
def
test_authentication
(
self
,
faceted
):
""" Verify the endpoint requires authentication. """
...
...
@@ -65,7 +73,7 @@ class CourseRunSearchViewSetTests(ElasticsearchTestMixin, APITestCase):
""" Asserts the search functionality returns results for a generated query. """
# Generate data that should be indexed and returned by the query
course_run
=
CourseRunFactory
(
course__title
=
'Software Testing'
)
course_run
=
CourseRunFactory
(
course__title
=
'Software Testing'
,
status
=
CourseRun
.
Status
.
Published
)
response
=
self
.
get_search_response
(
'software'
,
faceted
=
faceted
)
self
.
assertEqual
(
response
.
status_code
,
200
)
...
...
@@ -101,10 +109,14 @@ class CourseRunSearchViewSetTests(ElasticsearchTestMixin, APITestCase):
def
test_availability_faceting
(
self
):
""" Verify the endpoint returns availability facets with the results. """
now
=
datetime
.
datetime
.
utcnow
()
archived
=
CourseRunFactory
(
start
=
now
-
datetime
.
timedelta
(
weeks
=
2
),
end
=
now
-
datetime
.
timedelta
(
weeks
=
1
))
current
=
CourseRunFactory
(
start
=
now
-
datetime
.
timedelta
(
weeks
=
2
),
end
=
now
+
datetime
.
timedelta
(
weeks
=
1
))
starting_soon
=
CourseRunFactory
(
start
=
now
+
datetime
.
timedelta
(
days
=
10
),
end
=
now
+
datetime
.
timedelta
(
days
=
90
))
upcoming
=
CourseRunFactory
(
start
=
now
+
datetime
.
timedelta
(
days
=
61
),
end
=
now
+
datetime
.
timedelta
(
days
=
90
))
archived
=
CourseRunFactory
(
start
=
now
-
datetime
.
timedelta
(
weeks
=
2
),
end
=
now
-
datetime
.
timedelta
(
weeks
=
1
),
status
=
CourseRun
.
Status
.
Published
)
current
=
CourseRunFactory
(
start
=
now
-
datetime
.
timedelta
(
weeks
=
2
),
end
=
now
+
datetime
.
timedelta
(
weeks
=
1
),
status
=
CourseRun
.
Status
.
Published
)
starting_soon
=
CourseRunFactory
(
start
=
now
+
datetime
.
timedelta
(
days
=
10
),
end
=
now
+
datetime
.
timedelta
(
days
=
90
),
status
=
CourseRun
.
Status
.
Published
)
upcoming
=
CourseRunFactory
(
start
=
now
+
datetime
.
timedelta
(
days
=
61
),
end
=
now
+
datetime
.
timedelta
(
days
=
90
),
status
=
CourseRun
.
Status
.
Published
)
response
=
self
.
get_search_response
(
faceted
=
True
)
self
.
assertEqual
(
response
.
status_code
,
200
)
...
...
@@ -148,3 +160,31 @@ class CourseRunSearchViewSetTests(ElasticsearchTestMixin, APITestCase):
},
}
self
.
assertDictContainsSubset
(
expected
,
response_data
[
'queries'
])
class
AggregateSearchViewSet
(
SerializationMixin
,
LoginMixin
,
ElasticsearchTestMixin
,
APITestCase
):
path
=
reverse
(
'api:v1:search-all-facets'
)
def
get_search_response
(
self
,
query
=
None
):
qs
=
''
if
query
:
qs
=
urllib
.
parse
.
urlencode
({
'q'
:
query
})
url
=
'{path}?{qs}'
.
format
(
path
=
self
.
path
,
qs
=
qs
)
return
self
.
client
.
get
(
url
)
def
test_results_only_include_published_objects
(
self
):
""" Verify the search results only include items with status set to 'Published'. """
# These items should NOT be in the results
CourseRunFactory
(
status
=
CourseRun
.
Status
.
Unpublished
)
ProgramFactory
(
status
=
Program
.
Status
.
Unpublished
)
course_run
=
CourseRunFactory
(
status
=
CourseRun
.
Status
.
Published
)
program
=
ProgramFactory
(
status
=
Program
.
Status
.
Active
)
response
=
self
.
get_search_response
()
self
.
assertEqual
(
response
.
status_code
,
200
)
response_data
=
json
.
loads
(
response
.
content
.
decode
(
'utf-8'
))
self
.
assertListEqual
(
response_data
[
'objects'
][
'results'
],
[
self
.
serialize_course_run
(
course_run
),
self
.
serialize_program
(
program
)])
course_discovery/apps/api/v1/views.py
View file @
cf4605e5
...
...
@@ -328,7 +328,7 @@ class CourseRunViewSet(viewsets.ReadOnlyModelViewSet):
if
query
and
course_run_ids
:
course_run_ids
=
course_run_ids
.
split
(
','
)
course_runs
=
CourseRun
.
search
(
query
)
.
filter
(
partner
=
partner
.
short_code
)
.
filter
(
key__in
=
course_run_ids
)
.
\
course_runs
=
CourseRun
.
search
(
query
)
.
filter
(
partner
=
partner
.
short_code
)
.
filter
(
key__in
=
course_run_ids
)
.
\
values_list
(
'key'
,
flat
=
True
)
contains
=
{
course_run_id
:
course_run_id
in
course_runs
for
course_run_id
in
course_run_ids
}
...
...
@@ -477,7 +477,7 @@ class BaseHaystackViewSet(FacetMixin, HaystackViewSet):
"""
return
super
(
BaseHaystackViewSet
,
self
)
.
list
(
request
,
*
args
,
**
kwargs
)
@list_route
(
methods
=
[
"get"
],
url_path
=
"facets"
)
@list_route
(
methods
=
[
'get'
],
url_path
=
'facets'
)
def
facets
(
self
,
request
):
"""
Returns faceted search results
...
...
@@ -513,6 +513,9 @@ class BaseHaystackViewSet(FacetMixin, HaystackViewSet):
facet_serializer_cls
=
self
.
get_facet_serializer_class
()
field_queries
=
getattr
(
facet_serializer_cls
.
Meta
,
'field_queries'
,
{})
# Ensure we only return published items
queryset
=
queryset
.
filter
(
published
=
True
)
for
facet
in
self
.
request
.
query_params
.
getlist
(
'selected_query_facets'
):
query
=
field_queries
.
get
(
facet
)
...
...
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