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
6e92ddf3
Commit
6e92ddf3
authored
Jun 12, 2013
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cannot set String field to a dict anymore!
parent
89d00036
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
27 deletions
+63
-27
cms/djangoapps/contentstore/features/advanced-settings.feature
+6
-1
cms/djangoapps/contentstore/features/advanced-settings.py
+18
-9
cms/djangoapps/contentstore/features/problem-editor.py
+4
-2
cms/djangoapps/contentstore/views/course.py
+5
-2
common/lib/xmodule/xmodule/tests/test_xml_module.py
+21
-9
common/lib/xmodule/xmodule/xml_module.py
+9
-4
No files found.
cms/djangoapps/contentstore/features/advanced-settings.feature
View file @
6e92ddf3
...
@@ -28,11 +28,16 @@ Feature: Advanced (manual) course policy
...
@@ -28,11 +28,16 @@ Feature: Advanced (manual) course policy
Scenario
:
Test how multi-line input appears
Scenario
:
Test how multi-line input appears
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I create a JSON object as a value
When
I create a JSON object as a value
for
"discussion_topics"
Then
it is displayed as formatted
Then
it is displayed as formatted
And
I reload the page
And
I reload the page
Then
it is displayed as formatted
Then
it is displayed as formatted
Scenario
:
Test error if value supplied is of the wrong type
Given
I am on the Advanced Course Settings page in Studio
When
I create a JSON object as a value for
"display_name"
Then
I get an error on save
Scenario
:
Test automatic quoting of non-JSON values
Scenario
:
Test automatic quoting of non-JSON values
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I create a non-JSON value not in quotes
When
I create a non-JSON value not in quotes
...
...
cms/djangoapps/contentstore/features/advanced-settings.py
View file @
6e92ddf3
...
@@ -2,8 +2,7 @@
...
@@ -2,8 +2,7 @@
#pylint: disable=W0621
#pylint: disable=W0621
from
lettuce
import
world
,
step
from
lettuce
import
world
,
step
from
common
import
*
from
nose.tools
import
assert_false
,
assert_equal
,
assert_regexp_matches
from
nose.tools
import
assert_false
,
assert_equal
"""
"""
http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver/selenium.webdriver.common.keys.html
http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver/selenium.webdriver.common.keys.html
...
@@ -52,9 +51,9 @@ def edit_the_value_of_a_policy_key_and_save(step):
...
@@ -52,9 +51,9 @@ def edit_the_value_of_a_policy_key_and_save(step):
change_display_name_value
(
step
,
'"foo"'
)
change_display_name_value
(
step
,
'"foo"'
)
@step
(
'I create a JSON object as a value$'
)
@step
(
'I create a JSON object as a value
for "(.*)"
$'
)
def
create_JSON_object
(
step
):
def
create_JSON_object
(
step
,
key
):
change_
display_name_value
(
step
,
'{"key": "value", "key_2": "value_2"}'
)
change_
value
(
step
,
key
,
'{"key": "value", "key_2": "value_2"}'
)
@step
(
'I create a non-JSON value not in quotes$'
)
@step
(
'I create a non-JSON value not in quotes$'
)
...
@@ -82,7 +81,12 @@ def they_are_alphabetized(step):
...
@@ -82,7 +81,12 @@ def they_are_alphabetized(step):
@step
(
'it is displayed as formatted$'
)
@step
(
'it is displayed as formatted$'
)
def
it_is_formatted
(
step
):
def
it_is_formatted
(
step
):
assert_policy_entries
([
DISPLAY_NAME_KEY
],
[
'{
\n
"key": "value",
\n
"key_2": "value_2"
\n
}'
])
assert_policy_entries
([
'discussion_topics'
],
[
'{
\n
"key": "value",
\n
"key_2": "value_2"
\n
}'
])
@step
(
'I get an error on save$'
)
def
error_on_save
(
step
):
assert_regexp_matches
(
world
.
css_text
(
'#notification-error-description'
),
'Incorrect setting format'
)
@step
(
'it is displayed as a string'
)
@step
(
'it is displayed as a string'
)
...
@@ -124,11 +128,16 @@ def get_display_name_value():
...
@@ -124,11 +128,16 @@ def get_display_name_value():
def
change_display_name_value
(
step
,
new_value
):
def
change_display_name_value
(
step
,
new_value
):
change_value
(
step
,
DISPLAY_NAME_KEY
,
new_value
)
world
.
css_find
(
".CodeMirror"
)[
get_index_of
(
DISPLAY_NAME_KEY
)]
.
click
()
def
change_value
(
step
,
key
,
new_value
):
index
=
get_index_of
(
key
)
world
.
css_find
(
".CodeMirror"
)[
index
]
.
click
()
g
=
world
.
css_find
(
"div.CodeMirror.CodeMirror-focused > div > textarea"
)
g
=
world
.
css_find
(
"div.CodeMirror.CodeMirror-focused > div > textarea"
)
display_name
=
get_display_name_value
()
current_value
=
world
.
css_find
(
VALUE_CSS
)[
index
]
.
value
for
count
in
range
(
len
(
display_name
)):
g
.
_element
.
send_keys
(
Keys
.
CONTROL
+
Keys
.
END
)
for
count
in
range
(
len
(
current_value
)):
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
)
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
)
# Must delete "" before typing the JSON value
# Must delete "" before typing the JSON value
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
,
Keys
.
BACK_SPACE
,
new_value
)
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
,
Keys
.
BACK_SPACE
,
new_value
)
...
...
cms/djangoapps/contentstore/features/problem-editor.py
View file @
6e92ddf3
...
@@ -41,7 +41,9 @@ def i_see_five_settings_with_values(step):
...
@@ -41,7 +41,9 @@ def i_see_five_settings_with_values(step):
@step
(
'I can modify the display name'
)
@step
(
'I can modify the display name'
)
def
i_can_modify_the_display_name
(
step
):
def
i_can_modify_the_display_name
(
step
):
world
.
get_setting_entry
(
DISPLAY_NAME
)
.
find_by_css
(
'.setting-input'
)[
0
]
.
fill
(
'modified'
)
# Verifying that the display name can be a string containing a floating point value
# (to confirm that we don't throw an error because it is of the wrong type).
world
.
get_setting_entry
(
DISPLAY_NAME
)
.
find_by_css
(
'.setting-input'
)[
0
]
.
fill
(
'3.4'
)
verify_modified_display_name
()
verify_modified_display_name
()
...
@@ -172,7 +174,7 @@ def verify_modified_randomization():
...
@@ -172,7 +174,7 @@ def verify_modified_randomization():
def
verify_modified_display_name
():
def
verify_modified_display_name
():
world
.
verify_setting_entry
(
world
.
get_setting_entry
(
DISPLAY_NAME
),
DISPLAY_NAME
,
'
modified
'
,
True
)
world
.
verify_setting_entry
(
world
.
get_setting_entry
(
DISPLAY_NAME
),
DISPLAY_NAME
,
'
3.4
'
,
True
)
def
verify_modified_display_name_with_special_chars
():
def
verify_modified_display_name_with_special_chars
():
...
...
cms/djangoapps/contentstore/views/course.py
View file @
6e92ddf3
...
@@ -401,8 +401,11 @@ def course_advanced_updates(request, org, course, name):
...
@@ -401,8 +401,11 @@ def course_advanced_updates(request, org, course, name):
request_body
.
update
({
'tabs'
:
new_tabs
})
request_body
.
update
({
'tabs'
:
new_tabs
})
#Indicate that tabs should *not* be filtered out of the metadata
#Indicate that tabs should *not* be filtered out of the metadata
filter_tabs
=
False
filter_tabs
=
False
try
:
response_json
=
json
.
dumps
(
CourseMetadata
.
update_from_json
(
location
,
response_json
=
json
.
dumps
(
CourseMetadata
.
update_from_json
(
location
,
request_body
,
request_body
,
filter_tabs
=
filter_tabs
))
filter_tabs
=
filter_tabs
))
except
(
TypeError
,
ValueError
),
e
:
return
HttpResponseBadRequest
(
"Incorrect setting format. "
+
str
(
e
),
content_type
=
"text/plain"
)
return
HttpResponse
(
response_json
,
mimetype
=
"application/json"
)
return
HttpResponse
(
response_json
,
mimetype
=
"application/json"
)
common/lib/xmodule/xmodule/tests/test_xml_module.py
View file @
6e92ddf3
...
@@ -188,6 +188,18 @@ def assertDeserializeEqual(field, expected, arg):
...
@@ -188,6 +188,18 @@ def assertDeserializeEqual(field, expected, arg):
assert_equals
(
expected
,
deserialize_field
(
field
,
arg
))
assert_equals
(
expected
,
deserialize_field
(
field
,
arg
))
def
assertDeserializeNonString
(
field
):
"""
Asserts input value is returned for None or something that is not a string.
"""
assertDeserializeEqual
(
field
,
None
,
None
)
assertDeserializeEqual
(
field
,
3.14
,
3.14
)
assertDeserializeEqual
(
field
,
True
,
True
)
assertDeserializeEqual
(
field
,
[
10
],
[
10
])
assertDeserializeEqual
(
field
,
{},
{})
assertDeserializeEqual
(
field
,
[],
[])
class
TestSerializeInteger
(
unittest
.
TestCase
):
class
TestSerializeInteger
(
unittest
.
TestCase
):
""" Tests serialize/deserialize as related to Integer type. """
""" Tests serialize/deserialize as related to Integer type. """
...
@@ -208,7 +220,7 @@ class TestSerializeInteger(unittest.TestCase):
...
@@ -208,7 +220,7 @@ class TestSerializeInteger(unittest.TestCase):
def
test_deserialize_unsupported_types
(
self
):
def
test_deserialize_unsupported_types
(
self
):
assertDeserializeEqual
(
Integer
(),
'[3]'
,
'[3]'
)
assertDeserializeEqual
(
Integer
(),
'[3]'
,
'[3]'
)
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
assertDeserializeNonString
(
Integer
()
)
class
FloatTest
(
unittest
.
TestCase
):
class
FloatTest
(
unittest
.
TestCase
):
...
@@ -235,7 +247,7 @@ class FloatTest(unittest.TestCase):
...
@@ -235,7 +247,7 @@ class FloatTest(unittest.TestCase):
def
test_deserialize_unsupported_types
(
self
):
def
test_deserialize_unsupported_types
(
self
):
assertDeserializeEqual
(
Float
(),
'[3]'
,
'[3]'
)
assertDeserializeEqual
(
Float
(),
'[3]'
,
'[3]'
)
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
assertDeserializeNonString
(
Float
()
)
class
BooleanTest
(
unittest
.
TestCase
):
class
BooleanTest
(
unittest
.
TestCase
):
...
@@ -264,8 +276,7 @@ class BooleanTest(unittest.TestCase):
...
@@ -264,8 +276,7 @@ class BooleanTest(unittest.TestCase):
assertDeserializeEqual
(
Boolean
(),
'fAlse'
,
'"fAlse"'
)
assertDeserializeEqual
(
Boolean
(),
'fAlse'
,
'"fAlse"'
)
assertDeserializeEqual
(
Boolean
(),
"TruE"
,
'"TruE"'
)
assertDeserializeEqual
(
Boolean
(),
"TruE"
,
'"TruE"'
)
def
test_deserialize_unsupported_types
(
self
):
assertDeserializeNonString
(
Boolean
())
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
class
StringTest
(
unittest
.
TestCase
):
class
StringTest
(
unittest
.
TestCase
):
...
@@ -286,7 +297,7 @@ class StringTest(unittest.TestCase):
...
@@ -286,7 +297,7 @@ class StringTest(unittest.TestCase):
assertDeserializeEqual
(
String
(),
'false'
,
'false'
)
assertDeserializeEqual
(
String
(),
'false'
,
'false'
)
assertDeserializeEqual
(
String
(),
'2'
,
'2'
)
assertDeserializeEqual
(
String
(),
'2'
,
'2'
)
assertDeserializeEqual
(
String
(),
'[3]'
,
'[3]'
)
assertDeserializeEqual
(
String
(),
'[3]'
,
'[3]'
)
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
assertDeserializeNonString
(
String
()
)
class
AnyTest
(
unittest
.
TestCase
):
class
AnyTest
(
unittest
.
TestCase
):
...
@@ -307,9 +318,7 @@ class AnyTest(unittest.TestCase):
...
@@ -307,9 +318,7 @@ class AnyTest(unittest.TestCase):
assertDeserializeEqual
(
Any
(),
'['
,
'['
)
assertDeserializeEqual
(
Any
(),
'['
,
'['
)
assertDeserializeEqual
(
Any
(),
False
,
'false'
)
assertDeserializeEqual
(
Any
(),
False
,
'false'
)
assertDeserializeEqual
(
Any
(),
3.4
,
'3.4'
)
assertDeserializeEqual
(
Any
(),
3.4
,
'3.4'
)
assertDeserializeNonString
(
Any
())
def
test_deserialize_unsupported_types
(
self
):
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
class
ListTest
(
unittest
.
TestCase
):
class
ListTest
(
unittest
.
TestCase
):
...
@@ -330,7 +339,7 @@ class ListTest(unittest.TestCase):
...
@@ -330,7 +339,7 @@ class ListTest(unittest.TestCase):
assertDeserializeEqual
(
List
(),
'3.4'
,
'3.4'
)
assertDeserializeEqual
(
List
(),
'3.4'
,
'3.4'
)
assertDeserializeEqual
(
List
(),
'false'
,
'false'
)
assertDeserializeEqual
(
List
(),
'false'
,
'false'
)
assertDeserializeEqual
(
List
(),
'2'
,
'2'
)
assertDeserializeEqual
(
List
(),
'2'
,
'2'
)
self
.
assertRaises
(
TypeError
,
deserialize_field
,
None
)
assertDeserializeNonString
(
List
()
)
class
DateTest
(
unittest
.
TestCase
):
class
DateTest
(
unittest
.
TestCase
):
...
@@ -342,9 +351,11 @@ class DateTest(unittest.TestCase):
...
@@ -342,9 +351,11 @@ class DateTest(unittest.TestCase):
def
test_deserialize
(
self
):
def
test_deserialize
(
self
):
assertDeserializeEqual
(
Date
(),
'2012-12-31T23:59:59Z'
,
"2012-12-31T23:59:59Z"
)
assertDeserializeEqual
(
Date
(),
'2012-12-31T23:59:59Z'
,
"2012-12-31T23:59:59Z"
)
assertDeserializeEqual
(
Date
(),
'2012-12-31T23:59:59Z'
,
'"2012-12-31T23:59:59Z"'
)
assertDeserializeEqual
(
Date
(),
'2012-12-31T23:59:59Z'
,
'"2012-12-31T23:59:59Z"'
)
assertDeserializeNonString
(
Date
())
class
TimedeltaTest
(
unittest
.
TestCase
):
class
TimedeltaTest
(
unittest
.
TestCase
):
""" Tests serialize/deserialize as related to Timedelta type. """
def
test_serialize
(
self
):
def
test_serialize
(
self
):
assertSerializeEqual
(
'"1 day 12 hours 59 minutes 59 seconds"'
,
assertSerializeEqual
(
'"1 day 12 hours 59 minutes 59 seconds"'
,
...
@@ -355,3 +366,4 @@ class TimedeltaTest(unittest.TestCase):
...
@@ -355,3 +366,4 @@ class TimedeltaTest(unittest.TestCase):
'1 day 12 hours 59 minutes 59 seconds'
)
'1 day 12 hours 59 minutes 59 seconds'
)
assertDeserializeEqual
(
Timedelta
(),
'1 day 12 hours 59 minutes 59 seconds'
,
assertDeserializeEqual
(
Timedelta
(),
'1 day 12 hours 59 minutes 59 seconds'
,
'"1 day 12 hours 59 minutes 59 seconds"'
)
'"1 day 12 hours 59 minutes 59 seconds"'
)
assertDeserializeNonString
(
Timedelta
())
common/lib/xmodule/xmodule/xml_module.py
View file @
6e92ddf3
...
@@ -95,23 +95,28 @@ def deserialize_field(field, value):
...
@@ -95,23 +95,28 @@ def deserialize_field(field, value):
Note that this is not the same as the value returned by from_json, as model types typically store
Note that this is not the same as the value returned by from_json, as model types typically store
their value internally as JSON. By default, this method will return the result of calling json.loads
their value internally as JSON. By default, this method will return the result of calling json.loads
on the supplied value, unless json.loads throws a TypeError, or the type of the value returned by json.loads
on the supplied value, unless json.loads throws a TypeError, or the type of the value returned by json.loads
is not supported for this class (
see 'is_type_supported'
). In either of those cases, this method returns
is not supported for this class (
from_json throws an Error
). In either of those cases, this method returns
the input value.
the input value.
"""
"""
try
:
try
:
deserialized
=
json
.
loads
(
value
)
deserialized
=
json
.
loads
(
value
)
if
deserialized
is
None
:
if
deserialized
is
None
:
return
deserialized
return
deserialized
try
:
try
:
field
.
from_json
(
deserialized
)
field
.
from_json
(
deserialized
)
return
deserialized
return
deserialized
except
(
ValueError
,
TypeError
):
except
(
ValueError
,
TypeError
):
# Support older serialized forms by simply returning the String representation
# Support older serialized version, which was just a string, not result of json.dumps.
# If the deserialized version cannot be converted to the type (via from_json),
# just return the original value. For example, if a string value of '3.4' was
# stored for a String field (before we started storing the result of json.dumps),
# then it would be deserialized as 3.4, but 3.4 is not supported for a String
# field. Therefore field.from_json(3.4) will throw an Error, and we should
# actually return the original value of '3.4'.
return
value
return
value
except
(
ValueError
,
TypeError
):
except
(
ValueError
,
TypeError
):
# Support older serialized version
, which was just the String (not the result of json.dumps)
.
# Support older serialized version.
return
value
return
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