Skip to content

Commit 30d4b6b

Browse files
author
Dave St.Germain
authored
Merge pull request openedx#1442 from open-craft/ahmed/bb-2602-make-ora-indexable
[BD-29] [TNL-6993] [BB-2602]: Make ORA indexable
2 parents 5c6fefd + 49108e6 commit 30d4b6b

File tree

6 files changed

+283
-2
lines changed

6 files changed

+283
-2
lines changed

openassessment/xblock/openassessmentblock.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import json
66
import logging
77
import os
8+
import re
89

910
import pkg_resources
1011
import pytz
1112

1213
from django.conf import settings
1314
from django.template.loader import get_template
1415

16+
from bleach.sanitizer import Cleaner
1517
from lazy import lazy
1618
from webob import Response
1719
from xblock.core import XBlock
@@ -1242,3 +1244,46 @@ def get_xblock_id(self):
12421244
Returns the xblock id
12431245
"""
12441246
return str(self.scope_ids.usage_id)
1247+
1248+
def _clean_data(self, data):
1249+
cleaner = Cleaner(tags=[], strip=True)
1250+
cleaned_text = " ".join(re.split(r"\s+", cleaner.clean(data), flags=re.UNICODE)).strip()
1251+
return cleaned_text
1252+
1253+
def index_dictionary(self):
1254+
"""
1255+
Return dictionary prepared with module content and type for indexing.
1256+
"""
1257+
1258+
# return key/value fields in a Python dict object
1259+
# values may be numeric / string or dict
1260+
# default implementation is an empty dict
1261+
xblock_body = super(OpenAssessmentBlock, self).index_dictionary()
1262+
1263+
# Check whether there is only one prompt or more than one
1264+
# If there is single prompt, self.prompt would be simply a string
1265+
# otherwise self.prompt would have json embedded in the string.
1266+
try:
1267+
prompt = {
1268+
"prompt_{}".format(prompt_i): self._clean_data(prompt.get("description", ""))
1269+
for prompt_i, prompt in enumerate(json.loads(self.prompt))
1270+
}
1271+
except ValueError:
1272+
prompt = {
1273+
"prompt": self._clean_data(self.prompt)
1274+
}
1275+
1276+
content = {
1277+
"display_name": self.display_name,
1278+
"title": self.title,
1279+
**prompt
1280+
}
1281+
1282+
if "content" in xblock_body:
1283+
xblock_body["content"].update(content)
1284+
else:
1285+
xblock_body["content"] = content
1286+
1287+
xblock_body["content_type"] = "ORA"
1288+
1289+
return xblock_body
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<openassessment url_name="35809bfd971f4acc9b55e5a7c737b77d" submission_start="2001-01-01T00:00:00+00:00" submission_due="2029-01-01T00:00:00+00:00" text_response="required" allow_latex="False" prompts_type="html">
2+
<title>Quiz about computers</title>
3+
<assessments>
4+
<assessment name="student-training">
5+
<example>
6+
<answer>
7+
<part>Ideas: 3, Content: 3</part>
8+
</answer>
9+
<select criterion="Ideas" option="Fair"/>
10+
<select criterion="Content" option="Good"/>
11+
</example>
12+
<example>
13+
<answer>
14+
<part>Ideas: 0, Content: 3</part>
15+
</answer>
16+
<select criterion="Ideas" option="Poor"/>
17+
<select criterion="Content" option="Good"/>
18+
</example>
19+
</assessment>
20+
<assessment name="peer-assessment" must_grade="3" must_be_graded_by="3" start="2001-01-01T00:00:00+00:00" due="2029-01-01T00:00:00+00:00"/>
21+
<assessment name="self-assessment" start="2001-01-01T00:00:00+00:00" due="2029-01-01T00:00:00+00:00"/>
22+
</assessments>
23+
<prompts>
24+
<prompt>
25+
<description>&lt;p&gt;&lt;strong&gt;What&lt;/strong&gt; is &lt;span style="text-decoration: underline;"&gt;computer&lt;/span&gt;?&lt;/p&gt;
26+
&lt;p&gt;&lt;img src="https://open.edx.org/wp-content/themes/openedx/src/assets/images/open-edx-logo-white.svg" alt="OpenEdX Logo" type="saveimage" target="[object Object]" width="123" height="47" /&gt;&lt;/p&gt;
27+
&lt;p&gt;It is a&lt;/p&gt;
28+
&lt;ul&gt;
29+
&lt;li&gt;machine&lt;/li&gt;
30+
&lt;/ul&gt;
31+
&lt;p&gt;&lt;/p&gt;
32+
&lt;p&gt;&lt;/p&gt;</description>
33+
</prompt>
34+
<prompt>
35+
<description>&lt;p&gt;&lt;strong&gt;Is&lt;/strong&gt; it a &lt;span style="text-decoration: underline;"&gt;calculator&lt;/span&gt;?&lt;/p&gt;
36+
&lt;p&gt;&lt;img src="https://open.edx.org/wp-content/themes/openedx/src/assets/images/open-edx-logo-white.svg" alt="OpenEdX Logo" type="saveimage" target="[object Object]" width="123" height="47" /&gt;&lt;/p&gt;
37+
&lt;p&gt;Or is it a&lt;/p&gt;
38+
&lt;ul&gt;
39+
&lt;li&gt;microwave&lt;/li&gt;
40+
&lt;/ul&gt;
41+
&lt;p&gt;&lt;/p&gt;
42+
&lt;p&gt;&lt;/p&gt;</description>
43+
</prompt>
44+
</prompts>
45+
<rubric>
46+
<criterion feedback="optional">
47+
<name>Ideas</name>
48+
<label>Ideas</label>
49+
<prompt>Determine if there is a unifying theme or main idea.</prompt>
50+
<option points="0">
51+
<name>Poor</name>
52+
<label>Poor</label>
53+
<explanation>Difficult for the reader to discern the main idea. Too brief or too repetitive to establish or maintain a focus.</explanation>
54+
</option>
55+
<option points="3">
56+
<name>Fair</name>
57+
<label>Fair</label>
58+
<explanation>Presents a unifying theme or main idea, but may include minor tangents. Stays somewhat focused on topic and task.</explanation>
59+
</option>
60+
<option points="5">
61+
<name>Good</name>
62+
<label>Good</label>
63+
<explanation>Presents a unifying theme or main idea without going off on tangents. Stays completely focused on topic and task.</explanation>
64+
</option>
65+
</criterion>
66+
<criterion>
67+
<name>Content</name>
68+
<label>Content</label>
69+
<prompt>Assess the content of the submission</prompt>
70+
<option points="0">
71+
<name>Poor</name>
72+
<label>Poor</label>
73+
<explanation>Includes little information with few or no details or unrelated details. Unsuccessful in attempts to explore any facets of the topic.</explanation>
74+
</option>
75+
<option points="1">
76+
<name>Fair</name>
77+
<label>Fair</label>
78+
<explanation>Includes little information and few or no details. Explores only one or two facets of the topic.</explanation>
79+
</option>
80+
<option points="3">
81+
<name>Good</name>
82+
<label>Good</label>
83+
<explanation>Includes sufficient information and supporting details. (Details may not be fully developed; ideas may be listed.) Explores some facets of the topic.</explanation>
84+
</option>
85+
<option points="3">
86+
<name>Excellent</name>
87+
<label>Excellent</label>
88+
<explanation>Includes in-depth information and exceptional supporting details that are fully developed. Explores all facets of the topic.</explanation>
89+
</option>
90+
</criterion>
91+
<feedbackprompt>(Optional) What aspects of this response stood out to you? What did it do well? How could it be improved?
92+
</feedbackprompt>
93+
<feedback_default_text>I think that this response...
94+
</feedback_default_text>
95+
</rubric>
96+
</openassessment>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<openassessment url_name="35809bfd971f4acc9b55e5a7c737b77d" submission_start="2001-01-01T00:00:00+00:00" submission_due="2029-01-01T00:00:00+00:00" text_response="required" allow_latex="False" prompts_type="html">
2+
<title>Quiz about computers</title>
3+
<assessments>
4+
<assessment name="student-training">
5+
<example>
6+
<answer>
7+
<part>Ideas: 3, Content: 3</part>
8+
</answer>
9+
<select criterion="Ideas" option="Fair"/>
10+
<select criterion="Content" option="Good"/>
11+
</example>
12+
<example>
13+
<answer>
14+
<part>Ideas: 0, Content: 3</part>
15+
</answer>
16+
<select criterion="Ideas" option="Poor"/>
17+
<select criterion="Content" option="Good"/>
18+
</example>
19+
</assessment>
20+
<assessment name="peer-assessment" must_grade="3" must_be_graded_by="3" start="2001-01-01T00:00:00+00:00" due="2029-01-01T00:00:00+00:00"/>
21+
<assessment name="self-assessment" start="2001-01-01T00:00:00+00:00" due="2029-01-01T00:00:00+00:00"/>
22+
</assessments>
23+
<prompts>
24+
<prompt>
25+
<description>&lt;p&gt;&lt;strong&gt;What&lt;/strong&gt; is &lt;span style="text-decoration: underline;"&gt;computer&lt;/span&gt;?&lt;/p&gt;
26+
&lt;p&gt;&lt;img src="https://open.edx.org/wp-content/themes/openedx/src/assets/images/open-edx-logo-white.svg" alt="OpenEdX Logo" type="saveimage" target="[object Object]" width="123" height="47" /&gt;&lt;/p&gt;
27+
&lt;p&gt;It is a&lt;/p&gt;
28+
&lt;ul&gt;
29+
&lt;li&gt;machine&lt;/li&gt;
30+
&lt;/ul&gt;
31+
&lt;p&gt;&lt;/p&gt;
32+
&lt;p&gt;&lt;/p&gt;</description>
33+
</prompt>
34+
</prompts>
35+
<rubric>
36+
<criterion feedback="optional">
37+
<name>Ideas</name>
38+
<label>Ideas</label>
39+
<prompt>Determine if there is a unifying theme or main idea.</prompt>
40+
<option points="0">
41+
<name>Poor</name>
42+
<label>Poor</label>
43+
<explanation>Difficult for the reader to discern the main idea. Too brief or too repetitive to establish or maintain a focus.</explanation>
44+
</option>
45+
<option points="3">
46+
<name>Fair</name>
47+
<label>Fair</label>
48+
<explanation>Presents a unifying theme or main idea, but may include minor tangents. Stays somewhat focused on topic and task.</explanation>
49+
</option>
50+
<option points="5">
51+
<name>Good</name>
52+
<label>Good</label>
53+
<explanation>Presents a unifying theme or main idea without going off on tangents. Stays completely focused on topic and task.</explanation>
54+
</option>
55+
</criterion>
56+
<criterion>
57+
<name>Content</name>
58+
<label>Content</label>
59+
<prompt>Assess the content of the submission</prompt>
60+
<option points="0">
61+
<name>Poor</name>
62+
<label>Poor</label>
63+
<explanation>Includes little information with few or no details or unrelated details. Unsuccessful in attempts to explore any facets of the topic.</explanation>
64+
</option>
65+
<option points="1">
66+
<name>Fair</name>
67+
<label>Fair</label>
68+
<explanation>Includes little information and few or no details. Explores only one or two facets of the topic.</explanation>
69+
</option>
70+
<option points="3">
71+
<name>Good</name>
72+
<label>Good</label>
73+
<explanation>Includes sufficient information and supporting details. (Details may not be fully developed; ideas may be listed.) Explores some facets of the topic.</explanation>
74+
</option>
75+
<option points="3">
76+
<name>Excellent</name>
77+
<label>Excellent</label>
78+
<explanation>Includes in-depth information and exceptional supporting details that are fully developed. Explores all facets of the topic.</explanation>
79+
</option>
80+
</criterion>
81+
<feedbackprompt>(Optional) What aspects of this response stood out to you? What did it do well? How could it be improved?
82+
</feedbackprompt>
83+
<feedback_default_text>I think that this response...
84+
</feedback_default_text>
85+
</rubric>
86+
</openassessment>

openassessment/xblock/test/test_openassessment.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,3 +915,57 @@ def test_get_username_unknown_id(self, xblock):
915915
xblock.xmodule_runtime.get_real_user.return_value = None
916916

917917
self.assertIsNone(xblock.get_username('unknown_id'))
918+
919+
920+
class OpenAssessmentIndexingTestCase(XBlockHandlerTestCase):
921+
"""Tests indexibility of Open Assessment"""
922+
923+
@scenario('data/basic_scenario.xml')
924+
def test_ora_indexibility_with_multiple_prompts(self, xblock):
925+
result = xblock.index_dictionary()
926+
content, content_type = result["content"], result["content_type"]
927+
self.assertEqual(content_type, "ORA")
928+
self.assertEqual(content["title"], "Open Assessment Test")
929+
self.assertEqual(content["display_name"], "Open Response Assessment")
930+
self.assertEqual(
931+
[key.startswith("prompt") and content[key] != "" for key in content.keys()].count(True), 2
932+
)
933+
934+
@scenario('data/empty_prompt.xml')
935+
def test_ora_indexibility_with_no_prompt(self, xblock):
936+
result = xblock.index_dictionary()
937+
content, content_type = result["content"], result["content_type"]
938+
self.assertEqual(content_type, "ORA")
939+
self.assertEqual(content["title"], "Open Assessment Test")
940+
self.assertEqual(content["display_name"], "Open Response Assessment")
941+
self.assertEqual(content["prompt"], "")
942+
943+
@scenario('data/file_upload_missing_scenario.xml')
944+
def test_ora_indexibility_with_single_prompt(self, xblock):
945+
result = xblock.index_dictionary()
946+
content, content_type = result["content"], result["content_type"]
947+
self.assertEqual(content_type, "ORA")
948+
self.assertEqual(
949+
content["prompt"],
950+
"Given the state of the world today, what do you think should be done to combat poverty? "
951+
"Please answer in a short essay of 200-300 words."
952+
)
953+
954+
@scenario('data/assessment_with_single_html_prompt.xml')
955+
def test_ora_indexibility_with_single_html_prompt(self, xblock):
956+
result = xblock.index_dictionary()
957+
content, content_type = result["content"], result["content_type"]
958+
self.assertEqual(content_type, "ORA")
959+
self.assertEqual(content["title"], "Quiz about computers")
960+
self.assertEqual(content["display_name"], "Open Response Assessment")
961+
self.assertEqual(content["prompt"], "What is computer? It is a machine")
962+
963+
@scenario('data/assessment_with_multiple_html_prompt.xml')
964+
def test_ora_indexibility_with_multiple_html_prompt(self, xblock):
965+
result = xblock.index_dictionary()
966+
content, content_type = result["content"], result["content_type"]
967+
self.assertEqual(content_type, "ORA")
968+
self.assertEqual(content["title"], "Quiz about computers")
969+
self.assertEqual(content["display_name"], "Open Response Assessment")
970+
self.assertEqual(content["prompt_0"], "What is computer? It is a machine")
971+
self.assertEqual(content["prompt_1"], "Is it a calculator? Or is it a microwave")

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "edx-ora2",
3-
"version": "2.8.7",
3+
"version": "2.8.8",
44
"repository": "https://github.com/edx/edx-ora2.git",
55
"dependencies": {
66
"backbone": "~1.2.3",

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def load_requirements(*requirements_paths):
3636

3737
setup(
3838
name='ora2',
39-
version='2.8.7',
39+
version='2.8.8',
4040
author='edX',
4141
author_email='[email protected]',
4242
url='http://github.com/edx/edx-ora2',

0 commit comments

Comments
 (0)