Commit 26f1237d by Usman Khalid

Added tests for xml parsing & serialization.

TNL-708
parent 6c1be448
<openassessment>
<title>Open Assessment Test</title>
<prompts>
<prompt>
Given the state of the world today, what do you think should be done to
combat poverty? Please answer in a short essay of 200-300 words.
<description>Given the state of the world today, what do you think should be done to combat poverty? Please answer in a short essay of 200-300 words.</description>
</prompt>
</prompts>
<rubric>
<prompt>Read for conciseness, clarity of thought, and form.</prompt>
<criterion>
<name>Concise</name>
<prompt>How concise is it?</prompt>
......
{
"promptless": {
"xml": [
"<openassessment>",
"<rubric>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": ""}]
},
"rubric_prompt": {
"xml": [
"<openassessment>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "Test prompt"}]
},
"rubric_prompt_empty": {
"xml": [
"<openassessment>",
"<rubric>",
"<prompt></prompt>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": ""}]
},
"rubric_prompt_unicode": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description>ՇєรՇ קг๏๓קՇ</description></prompt>",
"</prompts>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "ՇєรՇ קг๏๓קՇ"}]
},
"prompts_one": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description>Test prompt</description></prompt>",
"</prompts>",
"<rubric>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "Test prompt"}]
},
"prompts_multiple": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description>Test prompt 1</description></prompt>",
"<prompt><description>Test prompt 2</description></prompt>",
"<prompt><description>Test prompt 3</description></prompt>",
"</prompts>",
"<rubric>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "Test prompt 1"}, {"description": "Test prompt 2"}, {"description": "Test prompt 3"}]
},
"prompts_empty": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description></description></prompt>",
"</prompts>",
"<rubric>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": ""}]
},
"prompts_multiple_empty": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description></description></prompt>",
"<prompt><description></description></prompt>",
"</prompts>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": ""}, {"description": ""}]
},
"prompts_unicode": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description>ՇєรՇ קг๏๓קՇ 1</description></prompt>",
"<prompt><description>ՇєรՇ קг๏๓קՇ 2</description></prompt>",
"</prompts>",
"<rubric>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "ՇєรՇ קг๏๓קՇ 1"}, {"description": "ՇєรՇ קг๏๓קՇ 2"}]
},
"rubric_prompt_and_prompts": {
"xml": [
"<openassessment>",
"<prompts>",
"<prompt><description>Test prompt 1</description></prompt>",
"<prompt><description>Test prompt 2</description></prompt>",
"</prompts>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"</rubric>",
"</openassessment>"
],
"prompts": [{"description": "Test prompt 1"}, {"description": "Test prompt 2"}]
}
}
......@@ -211,6 +211,77 @@
]
},
"multiple_prompts": {
"title": "Foo",
"prompt": "[{\"description\": \"Test prompt 1.\"}, {\"description\": \"Test prompt 2.\"}]",
"rubric_feedback_prompt": "Test Feedback Prompt",
"rubric_feedback_default_text": "Test default text...",
"start": null,
"due": null,
"submission_start": null,
"submission_due": null,
"allow_file_upload": null,
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
],
"assessments": [
{
"name": "peer-assessment",
"start": "2014-02-27T09:46:28",
"due": "2014-03-01T00:00:00",
"must_grade": 5,
"must_be_graded_by": 3
},
{
"name": "self-assessment",
"start": "2014-04-01T00:00:00",
"due": "2014-06-01T00:00:00"
}
],
"expected_xml": [
"<openassessment>",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"<assessment name=\"self-assessment\" start=\"2014-04-01T00:00:00\" due=\"2014-06-01T00:00:00\" />",
"</assessments>",
"<prompts>",
"<prompt><description>Test prompt 1.</description></prompt>",
"<prompt><description>Test prompt 2.</description></prompt>",
"</prompts>",
"<rubric>",
"<criterion>",
"<name>Test criterion</name>",
"<label>Test criterion</label>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"0\"><name>No</name><label>No</label><explanation>No explanation</explanation></option>",
"<option points=\"2\"><name>Yes</name><label>Yes</label><explanation>Yes explanation</explanation></option>",
"</criterion>",
"<feedbackprompt>Test Feedback Prompt</feedbackprompt>",
"<feedback_default_text>Test default text...</feedback_default_text>",
"</rubric>",
"</openassessment>"
]
},
"unicode": {
"title": "ƒσσ",
"prompt": "Ṫëṡẗ ṗṛöṁṗẗ",
......
......@@ -20,7 +20,7 @@
"</openassessment>"
],
"title": "Foo",
"prompt": "Test prompt",
"prompts": [{"description": "Test prompt"}],
"submission_start": null,
"submission_due": null,
"leaderboard_show": 0,
......@@ -82,7 +82,7 @@
"</rubric>",
"</openassessment>"
],
"prompt": null
"prompts": [{"description": ""}]
},
"empty_prompt": {
......@@ -103,7 +103,7 @@
"</rubric>",
"</openassessment>"
],
"prompt": ""
"prompt": [{"description": ""}]
},
"unicode": {
......@@ -113,8 +113,10 @@
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"</assessments>",
"<prompts>",
"<prompt><description>ՇєรՇ קг๏๓קՇ</description></prompt>",
"</prompts>",
"<rubric>",
"<prompt>ՇєรՇ קг๏๓קՇ</prompt>",
"<criterion>",
"<name>𝓣𝓮𝓼𝓽 𝓬𝓻𝓲𝓽𝓮𝓻𝓲𝓸𝓷</name>",
"<label>Ṫëṡẗ ċṛïẗëṛïöṅ ḷäḅëḷ</label>",
......@@ -126,7 +128,7 @@
"</openassessment>"
],
"title": "िѻѻ",
"prompt": "ՇєรՇ קг๏๓קՇ",
"prompts": [{"description": "ՇєรՇ קг๏๓קՇ"}],
"rubric_criteria": [
{
"order_num": 0,
......@@ -238,7 +240,7 @@
"</rubric>",
"</openassessment>"
],
"prompt": "Test prompt",
"prompts": [{"description": "Test prompt"}],
"submission_start": null,
"submission_due": null
},
......
......@@ -69,6 +69,28 @@
]
},
"missing_prompt_description": {
"xml": [
"<openassessment>",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"</assessments>",
"<prompts>",
"<prompt></prompt>",
"</prompts>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"<criterion>",
"<name>Test criterion</name>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"2\"><name>Yes</name><explanation>Yes explanation</explanation></option>",
"</criterion>",
"</rubric>",
"</openassessment>"
]
},
"non_numeric_points": {
"xml": [
"<openassessment>",
......
......@@ -173,7 +173,12 @@ class TestOpenAssessment(XBlockHandlerTestCase):
@scenario('data/basic_scenario.xml', user_id='Bob')
def test_prompts_fields(self, xblock):
self.assertEqual(xblock.prompts, [{'description':'Read for conciseness, clarity of thought, and form.'}])
self.assertEqual(xblock.prompts, [
{
'description': (u'Given the state of the world today, what do you think should be done to '
u'combat poverty? Please answer in a short essay of 200-300 words.')
}
])
xblock.prompt = None
self.assertEqual(xblock.prompts, [{'description': ''}])
......
......@@ -14,7 +14,7 @@ import ddt
from openassessment.xblock.data_conversion import create_prompts_list
from openassessment.xblock.openassessmentblock import OpenAssessmentBlock
from openassessment.xblock.xml import (
serialize_content, parse_from_xml_str, parse_rubric_xml,
serialize_content, parse_from_xml_str, _parse_prompts_xml, parse_rubric_xml,
parse_examples_xml, parse_assessments_xml,
serialize_rubric_to_xml_str, serialize_examples_to_xml_str,
serialize_assessments_to_xml_str, UpdateFromXmlError
......@@ -61,6 +61,17 @@ class TestSerializeContent(TestCase):
}
]
BASIC_PROMPTS = [
[
{
"description": "Prompt 1."
},
{
"description": "Prompt 2."
}
]
]
BASIC_ASSESSMENTS = [
{
"name": "student-training",
......@@ -200,6 +211,20 @@ class TestSerializeContent(TestCase):
msg = "Could not parse mutated criteria dict {criteria}\n{ex}".format(criteria=mutated_dict, ex=ex)
self.fail(msg)
def test_mutated_prompts_dict(self):
self._configure_xblock({})
for prompts_list in self.BASIC_PROMPTS:
for mutated_list in self._list_mutations(prompts_list):
self.oa_block.prompts = mutated_list
xml = serialize_content(self.oa_block)
try:
etree.fromstring(xml)
except Exception as ex: # pylint:disable=W0703
msg = "Could not parse mutated prompts list {prompts}\n{ex}".format(prompts=mutated_list, ex=ex)
self.fail(msg)
def test_mutated_assessments_dict(self):
self._configure_xblock({})
......@@ -320,6 +345,33 @@ class TestSerializeContent(TestCase):
for mutated in self._value_mutations(input_dict, key):
yield mutated
def _list_mutations(self, input_list):
"""
Iterator over mutations of a list:
1) Empty list
2) Replace list with None
3) Replace list with unicode
4) Replace list with an integer
Args:
input_list (list): A JSON-serializable list to traverse.
Yields:
list
"""
print "== Emptying list"
yield list()
# Mutation #3-5: value mutations
for mutated in (None, u"\u9731", 0):
yield mutated
# Recursively mutate sub-items
for index, item in enumerate(input_list):
if isinstance(item, dict):
for sub_mutation in self._dict_mutations(item):
yield self._mutate_list(input_list, index, sub_mutation)
def _value_mutations(self, input_dict, key):
"""
Iterate over mutations of the value for `key` in a dictionary.
......@@ -356,6 +408,34 @@ class TestSerializeContent(TestCase):
mutated[key] = new_val
return mutated
def _mutate_list(self, input_list, index, new_val):
"""
Copy and update a list.
Args:
input_list (list): The list to copy and update.
index (int): The index of the value to update.
new_val: The new value to set at the index.
Returns:
A copy of the list with the value at `index` set to `new_val`.
"""
mutated = copy.deepcopy(input_list)
mutated[index] = new_val
return mutated
@ddt.ddt
class TestParsePromptsFromXml(TestCase):
@ddt.file_data("data/parse_prompts_xml.json")
def test_parse_prompts_from_xml(self, data):
xml = etree.fromstring("".join(data['xml']))
prompts = _parse_prompts_xml(xml)
self.assertEqual(prompts, data['prompts'])
@ddt.ddt
class TestParseRubricFromXml(TestCase):
......
......@@ -67,6 +67,9 @@ def _serialize_prompts(prompts_root, prompts_list):
Returns:
None
"""
if not isinstance(prompts_list, list):
return
for prompt in prompts_list:
prompt_el = etree.SubElement(prompts_root, 'prompt')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment