Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
092cc4b2
Commit
092cc4b2
authored
Nov 25, 2015
by
wajeeha-khalid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MA-1211; Discussion API - make boolean params case insensitive
parent
8c69f226
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
114 additions
and
12 deletions
+114
-12
lms/djangoapps/discussion_api/forms.py
+4
-6
lms/djangoapps/discussion_api/tests/test_views.py
+72
-5
openedx/core/djangoapps/util/forms.py
+38
-1
No files found.
lms/djangoapps/discussion_api/forms.py
View file @
092cc4b2
...
...
@@ -9,11 +9,11 @@ from django.forms import (
Form
,
IntegerField
,
NullBooleanField
,
)
Select
)
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locator
import
CourseLocator
from
openedx.core.djangoapps.util.forms
import
MultiValueField
from
openedx.core.djangoapps.util.forms
import
MultiValueField
,
ExtendedNullBooleanField
class
_PaginationForm
(
Form
):
...
...
@@ -39,7 +39,7 @@ class ThreadListGetForm(_PaginationForm):
course_id
=
CharField
()
topic_id
=
MultiValueField
(
required
=
False
)
text_search
=
CharField
(
required
=
False
)
following
=
NullBooleanField
(
required
=
False
)
following
=
Extended
NullBooleanField
(
required
=
False
)
view
=
ChoiceField
(
choices
=
[(
choice
,
choice
)
for
choice
in
[
"unread"
,
"unanswered"
]],
required
=
False
,
...
...
@@ -106,9 +106,7 @@ class CommentListGetForm(_PaginationForm):
A form to validate query parameters in the comment list retrieval endpoint
"""
thread_id
=
CharField
()
# TODO: should we use something better here? This only accepts "True",
# "False", "1", and "0"
endorsed
=
NullBooleanField
(
required
=
False
)
endorsed
=
ExtendedNullBooleanField
(
required
=
False
)
class
CommentActionsForm
(
Form
):
...
...
lms/djangoapps/discussion_api/tests/test_views.py
View file @
092cc4b2
...
...
@@ -306,7 +306,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"has_endorsed"
:
False
,
}]
self
.
register_get_threads_response
(
source_threads
,
page
=
1
,
num_pages
=
2
)
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
)})
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
)
,
"following"
:
""
})
self
.
assert_response_correct
(
response
,
200
,
...
...
@@ -395,16 +395,15 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"text"
:
[
"test search string"
],
})
def
test_following
(
self
):
@ddt.data
(
True
,
"true"
,
"1"
)
def
test_following_true
(
self
,
following
):
self
.
register_get_user_response
(
self
.
user
)
self
.
register_subscribed_threads_response
(
self
.
user
,
[],
page
=
1
,
num_pages
=
1
)
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
),
"page"
:
"1"
,
"page_size"
:
"4"
,
"following"
:
"True"
,
"following"
:
following
,
}
)
self
.
assert_response_correct
(
...
...
@@ -417,6 +416,39 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"/api/v1/users/{}/subscribed_threads"
.
format
(
self
.
user
.
id
)
)
@ddt.data
(
False
,
"false"
,
"0"
)
def
test_following_false
(
self
,
following
):
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
),
"following"
:
following
,
}
)
self
.
assert_response_correct
(
response
,
400
,
{
"field_errors"
:
{
"following"
:
{
"developer_message"
:
"The value of the 'following' parameter must be true."
}
}}
)
def
test_following_error
(
self
):
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
),
"following"
:
"invalid-boolean"
,
}
)
self
.
assert_response_correct
(
response
,
400
,
{
"field_errors"
:
{
"following"
:
{
"developer_message"
:
"Invalid Boolean Value."
}
}}
)
@ddt.data
(
(
"last_activity_at"
,
"activity"
),
(
"comment_count"
,
"comments"
),
...
...
@@ -740,6 +772,7 @@ class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
self
.
assertEqual
(
response
.
status_code
,
404
)
@ddt.ddt
@httpretty.activate
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CommentViewSetListTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
...
...
@@ -750,6 +783,15 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
self
.
url
=
reverse
(
"comment-list"
)
self
.
thread_id
=
"test_thread"
def
make_minimal_cs_thread
(
self
,
overrides
=
None
):
"""
Create a thread with the given overrides, plus the course_id if not
already in overrides.
"""
overrides
=
overrides
.
copy
()
if
overrides
else
{}
overrides
.
setdefault
(
"course_id"
,
unicode
(
self
.
course
.
id
))
return
make_minimal_cs_thread
(
overrides
)
def
test_thread_id_missing
(
self
):
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assert_response_correct
(
...
...
@@ -869,6 +911,31 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
}
)
@ddt.data
(
(
True
,
"endorsed_comment"
),
(
"true"
,
"endorsed_comment"
),
(
"1"
,
"endorsed_comment"
),
(
False
,
"non_endorsed_comment"
),
(
"false"
,
"non_endorsed_comment"
),
(
"0"
,
"non_endorsed_comment"
),
)
@ddt.unpack
def
test_question_content
(
self
,
endorsed
,
comment_id
):
self
.
register_get_user_response
(
self
.
user
)
thread
=
self
.
make_minimal_cs_thread
({
"thread_type"
:
"question"
,
"endorsed_responses"
:
[
make_minimal_cs_comment
({
"id"
:
"endorsed_comment"
})],
"non_endorsed_responses"
:
[
make_minimal_cs_comment
({
"id"
:
"non_endorsed_comment"
})],
"non_endorsed_resp_total"
:
1
,
})
self
.
register_get_thread_response
(
thread
)
response
=
self
.
client
.
get
(
self
.
url
,
{
"thread_id"
:
thread
[
"id"
],
"endorsed"
:
endorsed
,
})
parsed_content
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
parsed_content
[
"results"
][
0
][
"id"
],
comment_id
)
@httpretty.activate
@disable_signal
(
api
,
'comment_deleted'
)
...
...
openedx/core/djangoapps/util/forms.py
View file @
092cc4b2
...
...
@@ -3,7 +3,7 @@ Custom forms-related types
"""
from
django.core.exceptions
import
ValidationError
from
django.forms
import
Field
,
MultipleHiddenInput
from
django.forms
import
Field
,
MultipleHiddenInput
,
NullBooleanField
,
Select
class
MultiValueField
(
Field
):
...
...
@@ -42,3 +42,40 @@ class MultiValueField(Field):
"""
if
values
and
""
in
values
:
raise
ValidationError
(
"This field cannot be empty."
)
class
ExtendedNullBooleanField
(
NullBooleanField
):
"""
A field whose valid values are None, True, 'True', 'true', '1',
False, 'False', 'false' and '0'.
"""
NULL_BOOLEAN_CHOICES
=
(
(
None
,
""
),
(
True
,
True
),
(
True
,
"True"
),
(
True
,
"true"
),
(
True
,
"1"
),
(
False
,
False
),
(
False
,
"False"
),
(
False
,
"false"
),
(
False
,
"0"
),
)
widget
=
Select
(
choices
=
NULL_BOOLEAN_CHOICES
)
def
to_python
(
self
,
value
):
"""
Explicitly checks for the string 'True', 'False', 'true',
'false', '1' and '0' and returns boolean True or False.
Returns None if value is not passed at all and raises an
exception for any other value.
"""
if
value
in
(
True
,
'True'
,
'true'
,
'1'
):
return
True
elif
value
in
(
False
,
'False'
,
'false'
,
'0'
):
return
False
elif
not
value
:
return
None
else
:
raise
ValidationError
(
"Invalid Boolean Value."
)
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