Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
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-ora2
Commits
61ab0d3a
Commit
61ab0d3a
authored
Feb 20, 2014
by
Stephen Sanchez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changing to mixins
parent
e39b9718
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
197 additions
and
177 deletions
+197
-177
apps/openassessment/xblock/assessment_block.py
+0
-32
apps/openassessment/xblock/assessment_mixin.py
+30
-0
apps/openassessment/xblock/grade_mixin.py
+0
-0
apps/openassessment/xblock/openassessmentblock.py
+8
-50
apps/openassessment/xblock/peer_assessment_mixin.py
+17
-16
apps/openassessment/xblock/scenario_parser.py
+4
-5
apps/openassessment/xblock/self_assessment_block.py
+0
-10
apps/openassessment/xblock/self_assessment_mixin.py
+10
-0
apps/openassessment/xblock/static/html/oa_peer_assessment.html
+1
-1
apps/openassessment/xblock/static/js/src/oa_base.js
+43
-43
apps/openassessment/xblock/submission_mixin.py
+10
-9
apps/openassessment/xblock/test/test_openassessment.py
+2
-2
apps/openassessment/xblock/test/test_scenario_parser.py
+12
-9
apps/openassessment/xblock/ui_models.py
+60
-0
No files found.
apps/openassessment/xblock/assessment_block.py
deleted
100644 → 0
View file @
e39b9718
from
django.template
import
Context
from
django.template.loader
import
get_template
class
AssessmentBlock
(
object
):
assessment_type
=
None
name
=
''
start_datetime
=
None
due_datetime
=
None
must_grade
=
1
must_be_graded_by
=
0
navigation_text
=
""
path
=
""
title
=
""
def
create_ui_model
(
self
):
return
{
"assessment_type"
:
self
.
assessment_type
,
"name"
:
self
.
name
,
"start_datetime"
:
self
.
start_datetime
,
"due_datetime"
:
self
.
due_datetime
,
"must_grade"
:
self
.
must_grade
,
"must_be_graded_by"
:
self
.
must_be_graded_by
,
"navigation_text"
:
self
.
navigation_text
,
"title"
:
self
.
title
}
def
render
(
self
,
context_dict
):
template
=
get_template
(
self
.
path
)
context
=
Context
(
context_dict
)
return
template
.
render
(
context
)
\ No newline at end of file
apps/openassessment/xblock/assessment_mixin.py
0 → 100644
View file @
61ab0d3a
from
django.template
import
Context
from
django.template.loader
import
get_template
from
webob
import
Response
class
AssessmentMixin
(
object
):
def
render
(
self
,
path
):
"""Render an Assessment Module's HTML
Given the name of an assessment module, find it in the list of
configured modules, and ask for its rendered HTML.
"""
context_dict
=
{
"xblock_trace"
:
self
.
_get_xblock_trace
(),
"rubric_instructions"
:
self
.
rubric_instructions
,
"rubric_criteria"
:
self
.
rubric_criteria
,
}
template
=
get_template
(
path
)
context
=
Context
(
context_dict
)
return
Response
(
template
.
render
(
context
),
content_type
=
'application/html'
,
charset
=
'UTF-8'
)
def
_get_assessment_module
(
self
,
mixin_name
):
"""Get a configured assessment module by name.
"""
for
assessment
in
self
.
rubric_assessments
:
if
assessment
.
name
==
mixin_name
:
return
assessment
\ No newline at end of file
apps/openassessment/xblock/grade_
block
.py
→
apps/openassessment/xblock/grade_
mixin
.py
View file @
61ab0d3a
File moved
apps/openassessment/xblock/openassessmentblock.py
View file @
61ab0d3a
"""An XBlock where students can read a question and compose their response"""
"""An XBlock where students can read a question and compose their response"""
import
datetime
import
datetime
import
json
from
django.template.context
import
Context
from
django.template.context
import
Context
from
django.template.loader
import
get_template
from
django.template.loader
import
get_template
import
pkg_resources
import
pkg_resources
from
webob
import
Response
from
xblock.core
import
XBlock
from
xblock.core
import
XBlock
from
xblock.fields
import
List
,
Scope
,
String
from
xblock.fields
import
List
,
Scope
,
String
from
xblock.fragment
import
Fragment
from
xblock.fragment
import
Fragment
from
openassessment.xblock.peer_assessment_block
import
PeerAssessmentBlock
from
openassessment.xblock.peer_assessment_mixin
import
PeerAssessmentMixin
from
openassessment.xblock.submission_block
import
SubmissionBlock
from
openassessment.xblock.self_assessment_mixin
import
SelfAssessmentMixin
from
openassessment.xblock.submission_mixin
import
SubmissionMixin
from
openassessment.xblock.ui_models
import
PeerAssessmentUIModel
from
scenario_parser
import
ScenarioParser
from
scenario_parser
import
ScenarioParser
...
@@ -112,7 +112,7 @@ DEFAULT_RUBRIC_CRITERIA = [
...
@@ -112,7 +112,7 @@ DEFAULT_RUBRIC_CRITERIA = [
}
}
]
]
DEFAULT_PEER_ASSESSMENT
=
PeerAssessment
Block
()
DEFAULT_PEER_ASSESSMENT
=
PeerAssessment
UIModel
()
DEFAULT_PEER_ASSESSMENT
.
name
=
"peer-assessment"
DEFAULT_PEER_ASSESSMENT
.
name
=
"peer-assessment"
DEFAULT_PEER_ASSESSMENT
.
start_datetime
=
datetime
.
datetime
.
now
()
.
isoformat
()
DEFAULT_PEER_ASSESSMENT
.
start_datetime
=
datetime
.
datetime
.
now
()
.
isoformat
()
DEFAULT_PEER_ASSESSMENT
.
must_grade
=
5
DEFAULT_PEER_ASSESSMENT
.
must_grade
=
5
...
@@ -122,12 +122,14 @@ DEFAULT_ASSESSMENT_MODULES = [
...
@@ -122,12 +122,14 @@ DEFAULT_ASSESSMENT_MODULES = [
DEFAULT_PEER_ASSESSMENT
,
DEFAULT_PEER_ASSESSMENT
,
]
]
def
load
(
path
):
def
load
(
path
):
"""Handy helper for getting resources from our kit."""
"""Handy helper for getting resources from our kit."""
data
=
pkg_resources
.
resource_string
(
__name__
,
path
)
data
=
pkg_resources
.
resource_string
(
__name__
,
path
)
return
data
.
decode
(
"utf8"
)
return
data
.
decode
(
"utf8"
)
class
OpenAssessmentBlock
(
XBlock
):
class
OpenAssessmentBlock
(
XBlock
,
SubmissionMixin
,
PeerAssessmentMixin
,
SelfAssessmentMixin
):
"""Displays a question and gives an area where students can compose a response."""
"""Displays a question and gives an area where students can compose a response."""
start_datetime
=
String
(
start_datetime
=
String
(
...
@@ -230,49 +232,6 @@ class OpenAssessmentBlock(XBlock):
...
@@ -230,49 +232,6 @@ class OpenAssessmentBlock(XBlock):
frag
.
initialize_js
(
'OpenAssessmentBlock'
)
frag
.
initialize_js
(
'OpenAssessmentBlock'
)
return
frag
return
frag
@XBlock.handler
def
render_assessment
(
self
,
data
,
suffix
=
''
):
"""Render an Assessment Module's HTML
Given the name of an assessment module, find it in the list of
configured modules, and ask for its rendered HTML.
"""
body
=
json
.
loads
(
data
.
body
)
context_dict
=
{
"xblock_trace"
:
self
.
_get_xblock_trace
(),
"rubric_instructions"
:
self
.
rubric_instructions
,
"rubric_criteria"
:
self
.
rubric_criteria
,
}
assessment
=
self
.
_get_assessment_module
(
body
[
'assessment'
])
if
assessment
:
return
Response
(
assessment
.
render
(
context_dict
),
content_type
=
'application/html'
,
charset
=
"UTF-8"
)
@XBlock.json_handler
def
assess
(
self
,
data
,
suffix
=
''
):
# TODO Pass name through the handler.
assessment
=
self
.
_get_assessment_module
(
'peer-assessment'
)
if
assessment
:
return
assessment
.
assess
(
self
.
_get_student_item_dict
(),
self
.
rubric_criteria
,
data
)
def
_get_assessment_module
(
self
,
name
):
"""Get a configured assessment module by name.
"""
for
assessment
in
self
.
rubric_assessments
:
if
assessment
.
name
==
name
:
return
assessment
@XBlock.json_handler
def
submit
(
self
,
data
,
suffix
=
''
):
"""
Place the submission text into Openassessment system
"""
return
SubmissionBlock
()
.
submit
(
self
.
_get_student_item_dict
(),
data
)
@staticmethod
@staticmethod
def
workbench_scenarios
():
def
workbench_scenarios
():
"""A canned scenario for display in the workbench."""
"""A canned scenario for display in the workbench."""
...
@@ -301,7 +260,6 @@ class OpenAssessmentBlock(XBlock):
...
@@ -301,7 +260,6 @@ class OpenAssessmentBlock(XBlock):
sparser
=
ScenarioParser
(
block
,
node
,
unknown_handler
)
sparser
=
ScenarioParser
(
block
,
node
,
unknown_handler
)
block
=
sparser
.
parse
()
block
=
sparser
.
parse
()
block
.
rubric_assessments
.
insert
(
0
,
SubmissionBlock
())
return
block
return
block
def
_get_grade_state
(
self
):
def
_get_grade_state
(
self
):
...
...
apps/openassessment/xblock/peer_assessment_
block
.py
→
apps/openassessment/xblock/peer_assessment_
mixin
.py
View file @
61ab0d3a
from
xblock.core
import
XBlock
from
openassessment.peer
import
api
as
peer_api
from
openassessment.peer
import
api
as
peer_api
from
openassessment.peer.api
import
PeerAssessmentWorkflowError
from
openassessment.peer.api
import
PeerAssessmentWorkflowError
from
openassessment.xblock.assessment_
block
import
AssessmentBlock
from
openassessment.xblock.assessment_
mixin
import
AssessmentMixin
class
PeerAssessment
Block
(
AssessmentBlock
):
class
PeerAssessment
Mixin
(
AssessmentMixin
):
assessment_type
=
"peer-assessment"
@XBlock.json_handler
path
=
"static/html/oa_peer_assessment.html"
def
assess
(
self
,
data
,
suffix
=
''
):
title
=
"Assess Peers' Responses"
navigation_text
=
"Your assessment(s) of peer responses"
@classmethod
def
assess
(
cls
,
student_item_dict
,
rubric_criteria
,
data
):
"""Place an assessment into Openassessment system
"""Place an assessment into Openassessment system
"""
"""
with
self
.
_get_assessment_module
(
'peer-assessment'
)
as
assessment
:
assessment_dict
=
{
assessment_dict
=
{
"points_earned"
:
map
(
int
,
data
[
"points_earned"
]),
"points_earned"
:
map
(
int
,
data
[
"points_earned"
]),
"points_possible"
:
sum
(
c
[
'total_value'
]
for
c
in
rubric_criteria
),
"points_possible"
:
sum
(
c
[
'total_value'
]
for
c
in
self
.
rubric_criteria
),
"feedback"
:
"Not yet implemented."
,
"feedback"
:
"Not yet implemented."
,
}
}
assessment
=
peer_api
.
create_assessment
(
assessment
=
peer_api
.
create_assessment
(
data
[
"submission_uuid"
],
data
[
"submission_uuid"
],
student_item_dict
[
"student_id"
],
self
.
_get_student_item_dict
()
[
"student_id"
],
int
(
cls
.
must_grade
),
int
(
assessment
.
must_grade
),
int
(
cls
.
must_be_graded_by
),
int
(
assessment
.
must_be_graded_by
),
assessment_dict
assessment_dict
)
)
...
@@ -33,17 +30,21 @@ class PeerAssessmentBlock(AssessmentBlock):
...
@@ -33,17 +30,21 @@ class PeerAssessmentBlock(AssessmentBlock):
return
assessment
,
"Success"
return
assessment
,
"Success"
def
get_peer_submission
(
self
,
student_item_dict
):
@XBlock.handler
def
render_peer_assessment
(
self
,
data
,
suffix
=
''
):
return
super
(
PeerAssessmentMixin
,
self
)
.
render
(
'static/html/oa_peer_assessment.html'
)
def
get_peer_submission
(
self
,
student_item_dict
,
assessment
):
peer_submission
=
False
peer_submission
=
False
try
:
try
:
peer_submission
=
peer_api
.
get_submission_to_assess
(
peer_submission
=
peer_api
.
get_submission_to_assess
(
student_item_dict
,
self
.
must_be_graded_by
student_item_dict
,
assessment
.
must_be_graded_by
)
)
# context_dict["peer_submission"] = peer_submission
# context_dict["peer_submission"] = peer_submission
peer_submission
=
peer_api
.
get_submission_to_assess
(
peer_submission
=
peer_api
.
get_submission_to_assess
(
student_item_dict
,
student_item_dict
,
self
.
must_be_graded_by
assessment
.
must_be_graded_by
)
)
except
PeerAssessmentWorkflowError
:
except
PeerAssessmentWorkflowError
:
...
...
apps/openassessment/xblock/scenario_parser.py
View file @
61ab0d3a
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
"""XBlock scenario parsing routines"""
"""XBlock scenario parsing routines"""
from
openassessment.xblock.peer_assessment_block
import
PeerAssessmentBlock
from
openassessment.xblock.ui_models
import
PeerAssessmentUIModel
,
SelfAssessmentUIModel
,
SubmissionUIModel
from
openassessment.xblock.self_assessment_block
import
SelfAssessmentBlock
class
ScenarioParser
(
object
):
class
ScenarioParser
(
object
):
...
@@ -76,16 +75,16 @@ class ScenarioParser(object):
...
@@ -76,16 +75,16 @@ class ScenarioParser(object):
must_grade="5"
must_grade="5"
must_be_graded_by="3" />
must_be_graded_by="3" />
</peer-assessment>"""
</peer-assessment>"""
assessment_list
=
[]
assessment_list
=
[
SubmissionUIModel
()
]
for
asmnt
in
assessments
:
for
asmnt
in
assessments
:
assessment
=
None
assessment
=
None
assessment_type
=
asmnt
.
tag
assessment_type
=
asmnt
.
tag
if
'peer-assessment'
==
assessment_type
:
if
'peer-assessment'
==
assessment_type
:
assessment
=
PeerAssessment
Block
()
assessment
=
PeerAssessment
UIModel
()
assessment
.
must_grade
=
int
(
asmnt
.
attrib
.
get
(
'must_grade'
,
1
))
assessment
.
must_grade
=
int
(
asmnt
.
attrib
.
get
(
'must_grade'
,
1
))
assessment
.
must_be_graded_by
=
int
(
asmnt
.
attrib
.
get
(
'must_be_graded_by'
,
0
))
assessment
.
must_be_graded_by
=
int
(
asmnt
.
attrib
.
get
(
'must_be_graded_by'
,
0
))
elif
'self-assessment'
==
assessment_type
:
elif
'self-assessment'
==
assessment_type
:
assessment
=
SelfAssessment
Block
()
assessment
=
SelfAssessment
UIModel
()
if
assessment
:
if
assessment
:
assessment
.
name
=
asmnt
.
attrib
.
get
(
'name'
,
''
)
assessment
.
name
=
asmnt
.
attrib
.
get
(
'name'
,
''
)
...
...
apps/openassessment/xblock/self_assessment_block.py
deleted
100644 → 0
View file @
e39b9718
from
openassessment.xblock.assessment_block
import
AssessmentBlock
class
SelfAssessmentBlock
(
AssessmentBlock
):
assessment_type
=
"self-assessment"
navigation_text
=
"Your assessment of your response"
path
=
"static/html/oa_self_assessment.html"
title
=
"Assess Your Response"
\ No newline at end of file
apps/openassessment/xblock/self_assessment_mixin.py
0 → 100644
View file @
61ab0d3a
from
xblock.core
import
XBlock
from
openassessment.xblock.assessment_mixin
import
AssessmentMixin
class
SelfAssessmentMixin
(
AssessmentMixin
):
@XBlock.handler
def
render_self_assessment
(
self
,
data
,
suffix
=
''
):
return
self
.
render
(
'static/html/oa_self_assessment.html'
)
apps/openassessment/xblock/static/html/oa_peer_assessment.html
View file @
61ab0d3a
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
<!-- CASE: default/not started -->
<!-- CASE: default/not started -->
<li
id=
"openassessment__peer-assessment"
class=
"openassessment__steps__step step--peer-assessment"
>
<li
id=
"openassessment__peer-assessment"
class=
"openassessment__steps__step step--peer-assessment"
>
{#
<header
class=
"step__header"
>
#}
<div
id=
"peer_submission_uuid"
hidden=
"true"
>
{{ peer_submission.uuid }}
</div>
<h2
class=
"step__title"
>
<h2
class=
"step__title"
>
<span
class=
"step__label"
>
Evaluate Peers' Responses
</span>
<span
class=
"step__label"
>
Evaluate Peers' Responses
</span>
<span
class=
"step__deadline"
>
due
<span
class=
"date"
>
January 30, 2014
</span>
at
<span
class=
"time"
>
15:00 UTC
</span></span>
<span
class=
"step__deadline"
>
due
<span
class=
"date"
>
January 30, 2014
</span>
at
<span
class=
"time"
>
15:00 UTC
</span></span>
...
...
apps/openassessment/xblock/static/js/src/oa_base.js
View file @
61ab0d3a
...
@@ -2,90 +2,90 @@
...
@@ -2,90 +2,90 @@
function
OpenAssessmentBlock
(
runtime
,
element
)
{
function
OpenAssessmentBlock
(
runtime
,
element
)
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'submit'
);
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'submit'
);
var
renderUrl
=
runtime
.
handlerUrl
(
element
,
'render_assessment'
);
var
renderSubmissionUrl
=
runtime
.
handlerUrl
(
element
,
'render_submission'
);
var
renderPeerUrl
=
runtime
.
handlerUrl
(
element
,
'render_peer_assessment'
);
var
renderSelfUrl
=
runtime
.
handlerUrl
(
element
,
'render_self_assessment'
);
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
/*
/*
Peer Assessment
Functions
Submission
Functions
*/
*/
function
prepare_assessment_post
(
element
)
{
function
render_submissions
(
data
)
{
var
selector
=
$
(
"input[type=radio]:checked"
,
element
);
$
(
'#submission'
,
element
).
replaceWith
(
data
);
var
values
=
[];
$
(
'#step--response__submit'
,
element
).
click
(
function
(
eventObject
)
{
for
(
i
=
0
;
i
<
selector
.
length
;
i
++
)
{
values
[
i
]
=
selector
[
i
].
value
;
}
return
{
"submission_uuid"
:
$
(
"div#peer_submission_uuid"
)[
0
].
innerText
,
"points_earned"
:
values
};
}
$
(
'.openassessment_submit'
,
element
).
click
(
function
(
eventObject
)
{
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
handlerUrl
,
url
:
handlerUrl
,
/* data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}), */
data
:
JSON
.
stringify
({
"submission"
:
$
(
'#submission__answer__value'
,
element
).
val
()}),
data
:
JSON
.
stringify
(
prepare_assessment_post
(
element
)),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
renderUrl
,
url
:
renderPeerUrl
,
data
:
JSON
.
stringify
({
"assessment"
:
"peer-assessment"
}),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
(
'#peer-assessment'
,
element
).
replaceWith
(
data
);
render_peer_assessment
(
data
);
}
}
});
});
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
renderUrl
,
url
:
renderSubmissionUrl
,
data
:
JSON
.
stringify
({
"assessment"
:
"self-assessment"
}),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
(
'#self-assessment'
,
element
).
replaceWith
(
data
);
render_submissions
(
data
);
}
}
});
});
}
}
});
});
});
});
}
$
(
function
(
$
)
{
/* Here's where you'd do things on page load. */
$
.
ajax
({
type
:
"POST"
,
url
:
renderUrl
,
data
:
JSON
.
stringify
({
"assessment"
:
"submission"
}),
success
:
function
(
data
)
{
$
(
'#submission'
,
element
).
replaceWith
(
data
);
/*
/*
Submission
Functions
Peer Assessment
Functions
*/
*/
$
(
'#step--response__submit'
,
element
).
click
(
function
(
eventObject
)
{
function
render_peer_assessment
(
data
)
{
$
(
'#peer-assessment'
,
element
).
replaceWith
(
data
);
function
prepare_assessment_post
(
element
)
{
var
selector
=
$
(
"input[type=radio]:checked"
,
element
);
var
values
=
[];
for
(
var
i
=
0
;
i
<
selector
.
length
;
i
++
)
{
values
[
i
]
=
selector
[
i
].
value
;
}
return
{
"submission_uuid"
:
$
(
"div#peer_submission_uuid"
)[
0
].
innerText
,
"points_earned"
:
values
};
}
$
(
'#peer-assessment--001__assessment__submit'
,
element
).
click
(
function
(
eventObject
)
{
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
handlerUrl
,
url
:
handlerUrl
,
data
:
JSON
.
stringify
({
"submission"
:
$
(
'#submission__answer__value'
,
element
).
val
()}),
/* data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}), */
data
:
JSON
.
stringify
(
prepare_assessment_post
(
element
)),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
alert
(
"Success?"
)
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
renderUrl
,
url
:
renderSelfUrl
,
data
:
JSON
.
stringify
({
"assessment"
:
"submission"
}),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
(
'#submission
'
,
element
).
replaceWith
(
data
);
$
(
'#self-assessment
'
,
element
).
replaceWith
(
data
);
}
}
});
});
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
renderUrl
,
url
:
renderPeerUrl
,
data
:
JSON
.
stringify
({
"assessment"
:
"peer-assessment"
}),
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
(
'#peer-assessment'
,
element
).
replaceWith
(
data
);
render_peer_assessment
(
data
)
}
}
});
});
},
}
fail
:
function
(
data
)
{
alert
(
"FAIL!!"
)}
});
});
});
});
}
}
$
(
function
(
$
)
{
/* Here's where you'd do things on page load. */
$
.
ajax
({
type
:
"POST"
,
url
:
renderSubmissionUrl
,
success
:
function
(
data
)
{
render_submissions
(
data
);
}
});
});
});
});
}
}
...
...
apps/openassessment/xblock/submission_
block
.py
→
apps/openassessment/xblock/submission_
mixin
.py
View file @
61ab0d3a
from
openassessment.xblock.assessment_block
import
AssessmentBlock
from
xblock.core
import
XBlock
from
openassessment.xblock.assessment_mixin
import
AssessmentMixin
from
submissions
import
api
from
submissions
import
api
class
SubmissionBlock
(
AssessmentBlock
):
class
SubmissionMixin
(
AssessmentMixin
):
assessment_type
=
"submission"
name
=
"submission"
navigation_text
=
"Your response to this problem"
path
=
"static/html/oa_response.html"
title
=
"Your Response"
submit_errors
=
{
submit_errors
=
{
# Reported to user sometimes, and useful in tests
# Reported to user sometimes, and useful in tests
...
@@ -18,10 +13,12 @@ class SubmissionBlock(AssessmentBlock):
...
@@ -18,10 +13,12 @@ class SubmissionBlock(AssessmentBlock):
'EUNKNOWN'
:
'API returned unclassified exception'
,
'EUNKNOWN'
:
'API returned unclassified exception'
,
}
}
def
submit
(
self
,
student_item_dict
,
data
):
@XBlock.json_handler
def
submit
(
self
,
data
,
suffix
=
''
):
"""
"""
Place the submission text into Openassessment system
Place the submission text into Openassessment system
"""
"""
student_item_dict
=
self
.
_get_student_item_dict
()
status
=
False
status
=
False
status_text
=
None
status_text
=
None
student_sub
=
data
[
'submission'
]
student_sub
=
data
[
'submission'
]
...
@@ -40,3 +37,7 @@ class SubmissionBlock(AssessmentBlock):
...
@@ -40,3 +37,7 @@ class SubmissionBlock(AssessmentBlock):
# relies on success being orthogonal to errors
# relies on success being orthogonal to errors
status_text
=
status_text
if
status_text
else
self
.
submit_errors
[
status_tag
]
status_text
=
status_text
if
status_text
else
self
.
submit_errors
[
status_tag
]
return
status
,
status_tag
,
status_text
return
status
,
status_tag
,
status_text
@XBlock.handler
def
render_submission
(
self
,
data
,
suffix
=
''
):
return
super
(
SubmissionMixin
,
self
)
.
render
(
'static/html/oa_response.html'
)
apps/openassessment/xblock/test/test_openassessment.py
View file @
61ab0d3a
...
@@ -7,7 +7,7 @@ import webob
...
@@ -7,7 +7,7 @@ import webob
from
django.test
import
TestCase
from
django.test
import
TestCase
from
mock
import
patch
from
mock
import
patch
from
openassessment.xblock.submission_
block
import
SubmissionBlock
from
openassessment.xblock.submission_
mixin
import
SubmissionMixin
from
submissions
import
api
from
submissions
import
api
from
submissions.api
import
SubmissionRequestError
,
SubmissionInternalError
from
submissions.api
import
SubmissionRequestError
,
SubmissionInternalError
...
@@ -98,7 +98,7 @@ class TestOpenAssessment(TestCase):
...
@@ -98,7 +98,7 @@ class TestOpenAssessment(TestCase):
result
=
json
.
loads
(
resp
.
body
)
result
=
json
.
loads
(
resp
.
body
)
self
.
assertFalse
(
result
[
0
])
self
.
assertFalse
(
result
[
0
])
self
.
assertEqual
(
result
[
1
],
"EUNKNOWN"
)
self
.
assertEqual
(
result
[
1
],
"EUNKNOWN"
)
self
.
assertEqual
(
result
[
2
],
Submission
Block
()
.
submit_errors
[
"EUNKNOWN"
])
self
.
assertEqual
(
result
[
2
],
Submission
Mixin
()
.
submit_errors
[
"EUNKNOWN"
])
@patch.object
(
api
,
'create_submission'
)
@patch.object
(
api
,
'create_submission'
)
def
test_submission_API_failure
(
self
,
mock_submit
):
def
test_submission_API_failure
(
self
,
mock_submit
):
...
...
apps/openassessment/xblock/test/test_scenario_parser.py
View file @
61ab0d3a
...
@@ -76,19 +76,22 @@ class TestScenarioParser(TestCase):
...
@@ -76,19 +76,22 @@ class TestScenarioParser(TestCase):
assessments_xml
=
etree
.
fromstring
(
assessments
)
assessments_xml
=
etree
.
fromstring
(
assessments
)
parsed_list
=
self
.
test_parser
.
get_assessments
(
assessments_xml
)
parsed_list
=
self
.
test_parser
.
get_assessments
(
assessments_xml
)
# Need to capture Submissions in Tests
self
.
assertEqual
(
parsed_list
[
0
]
.
assessment_type
,
'submission'
)
# Self assessments take all the parameters, but mostly ignore them.
# Self assessments take all the parameters, but mostly ignore them.
self
.
assertEqual
(
parsed_list
[
0
]
.
assessment_type
,
'self-assessment'
)
self
.
assertEqual
(
parsed_list
[
1
]
.
assessment_type
,
'self-assessment'
)
self
.
assertEqual
(
parsed_list
[
0
]
.
name
,
'0382e03c808e4f2bb12dfdd2d45d5c4b'
)
self
.
assertEqual
(
parsed_list
[
1
]
.
name
,
'0382e03c808e4f2bb12dfdd2d45d5c4b'
)
self
.
assertEqual
(
parsed_list
[
0
]
.
must_grade
,
1
)
self
.
assertEqual
(
parsed_list
[
1
]
.
must_grade
,
1
)
self
.
assertEqual
(
parsed_list
[
0
]
.
must_be_graded_by
,
0
)
self
.
assertEqual
(
parsed_list
[
1
]
.
must_be_graded_by
,
0
)
# Peer assessments are more interesting
# Peer assessments are more interesting
self
.
assertEqual
(
parsed_list
[
1
]
.
assessment_type
,
'peer-assessment'
)
self
.
assertEqual
(
parsed_list
[
2
]
.
assessment_type
,
'peer-assessment'
)
self
.
assertEqual
(
parsed_list
[
1
]
.
name
,
''
)
self
.
assertEqual
(
parsed_list
[
2
]
.
name
,
''
)
self
.
assertEqual
(
parsed_list
[
1
]
.
must_grade
,
5
)
self
.
assertEqual
(
parsed_list
[
2
]
.
must_grade
,
5
)
self
.
assertEqual
(
parsed_list
[
1
]
.
must_be_graded_by
,
3
)
self
.
assertEqual
(
parsed_list
[
2
]
.
must_be_graded_by
,
3
)
# We can parse arbitrary workflow descriptions as a list of assessments.
# We can parse arbitrary workflow descriptions as a list of assessments.
# Whether or not the workflow system can use them is another matter
# Whether or not the workflow system can use them is another matter
self
.
assertEqual
(
parsed_list
[
2
]
.
assessment_type
,
'self-assessment'
)
self
.
assertEqual
(
parsed_list
[
3
]
.
assessment_type
,
'self-assessment'
)
apps/openassessment/xblock/ui_models.py
0 → 100644
View file @
61ab0d3a
class
SubmissionUIModel
(
object
):
def
__init__
(
self
):
self
.
assessment_type
=
"submission"
self
.
name
=
"submission"
self
.
navigation_text
=
"Your response to this problem"
self
.
title
=
"Your Response"
def
create_ui_model
(
self
):
return
{
"assessment_type"
:
self
.
assessment_type
,
"name"
:
self
.
name
,
"navigation_text"
:
self
.
navigation_text
,
"title"
:
self
.
title
}
class
AssessmentUIModel
(
object
):
def
__init__
(
self
):
self
.
assessment_type
=
None
self
.
name
=
''
self
.
start_datetime
=
None
self
.
due_datetime
=
None
self
.
must_grade
=
1
self
.
must_be_graded_by
=
0
self
.
navigation_text
=
""
self
.
title
=
""
def
create_ui_model
(
self
):
return
{
"assessment_type"
:
self
.
assessment_type
,
"name"
:
self
.
name
,
"start_datetime"
:
self
.
start_datetime
,
"due_datetime"
:
self
.
due_datetime
,
"must_grade"
:
self
.
must_grade
,
"must_be_graded_by"
:
self
.
must_be_graded_by
,
"navigation_text"
:
self
.
navigation_text
,
"title"
:
self
.
title
}
class
PeerAssessmentUIModel
(
AssessmentUIModel
):
def
__init__
(
self
):
super
(
PeerAssessmentUIModel
,
self
)
.
__init__
()
self
.
assessment_type
=
"peer-assessment"
self
.
title
=
"Assess Peers' Responses"
self
.
navigation_text
=
"Your assessment(s) of peer responses"
class
SelfAssessmentUIModel
(
AssessmentUIModel
):
def
__init__
(
self
):
super
(
SelfAssessmentUIModel
,
self
)
.
__init__
()
self
.
assessment_type
=
"self-assessment"
self
.
navigation_text
=
"Your assessment of your response"
self
.
title
=
"Assess Your Response"
\ No newline at end of file
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