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
57300f83
Commit
57300f83
authored
May 12, 2014
by
Stephen Sanchez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding hooks to new user lookup service.
parent
77ee930e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
380 additions
and
77 deletions
+380
-77
apps/openassessment/assessment/api/peer.py
+10
-2
apps/openassessment/assessment/test/test_peer.py
+4
-0
apps/openassessment/templates/openassessmentblock/oa_base.html
+1
-1
apps/openassessment/templates/openassessmentblock/staff_debug/staff_debug.html
+4
-4
apps/openassessment/templates/openassessmentblock/staff_debug/student_info.html
+9
-8
apps/openassessment/xblock/staff_info_mixin.py
+16
-6
apps/openassessment/xblock/static/css/openassessment.css
+25
-19
apps/openassessment/xblock/static/js/openassessment.min.js
+0
-0
apps/openassessment/xblock/static/js/src/oa_staff_info.js
+4
-4
apps/openassessment/xblock/static/sass/oa/utilities/_developer.scss
+16
-4
apps/openassessment/xblock/test/data/peer_only_scenario.xml
+89
-0
apps/openassessment/xblock/test/data/self_only_scenario.xml
+89
-0
apps/openassessment/xblock/test/test_staff_info.py
+113
-29
No files found.
apps/openassessment/assessment/api/peer.py
View file @
57300f83
...
...
@@ -60,6 +60,9 @@ def get_score(submission_uuid, requirements):
workflow
=
PeerWorkflow
.
get_by_submission_uuid
(
submission_uuid
)
if
workflow
is
None
:
return
None
# This query will use the ordering defined by the assessment model
# (descending scored_at, then descending id)
items
=
workflow
.
graded_by
.
filter
(
...
...
@@ -420,7 +423,9 @@ def get_submitted_assessments(submission_uuid, scored_only=True, limit=None):
Returns:
list(dict): A list of dictionaries, where each dictionary represents a
separate assessment. Each assessment contains points earned, points
possible, time scored, scorer id, score type, and feedback.
possible, time scored, scorer id, score type, and feedback. If no
workflow is found associated with the given submission_uuid, returns
an empty list.
Raises:
PeerAssessmentRequestError: Raised when the submission_id is invalid.
...
...
@@ -448,6 +453,8 @@ def get_submitted_assessments(submission_uuid, scored_only=True, limit=None):
"""
try
:
# If no workflow is found associated with the uuid, this returns None,
# and an empty set of assessments will be returned.
workflow
=
PeerWorkflow
.
get_by_submission_uuid
(
submission_uuid
)
items
=
PeerWorkflowItem
.
objects
.
filter
(
scorer
=
workflow
,
...
...
@@ -460,7 +467,8 @@ def get_submitted_assessments(submission_uuid, scored_only=True, limit=None):
return
serialize_assessments
(
assessments
)
except
DatabaseError
:
error_message
=
_
(
u"Error getting assessments graded by author of submission {}"
.
format
(
submission_uuid
)
u"Couldn't retrieve the assessments that the author of response {}"
u" completed"
.
format
(
submission_uuid
)
)
logger
.
exception
(
error_message
)
raise
PeerAssessmentInternalError
(
error_message
)
...
...
apps/openassessment/assessment/test/test_peer.py
View file @
57300f83
...
...
@@ -807,6 +807,10 @@ class TestPeerApi(CacheResetTest):
submitted_assessments
=
peer_api
.
get_submitted_assessments
(
bob_sub
[
"uuid"
],
scored_only
=
False
)
self
.
assertEqual
(
1
,
len
(
submitted_assessments
))
def
test_get_submitted_assessments_with_bad_submission
(
self
):
submitted_assessments
=
peer_api
.
get_submitted_assessments
(
"bad-uuid"
,
scored_only
=
True
)
self
.
assertEqual
(
0
,
len
(
submitted_assessments
))
def
test_find_active_assessments
(
self
):
buffy_answer
,
_
=
self
.
_create_student_and_submission
(
"Buffy"
,
"Buffy's answer"
)
xander_answer
,
_
=
self
.
_create_student_and_submission
(
"Xander"
,
"Xander's answer"
)
...
...
apps/openassessment/templates/openassessmentblock/oa_base.html
View file @
57300f83
...
...
@@ -66,7 +66,7 @@
</ol>
{% if is_course_staff %}
<div
id=
"openassessment__staff
_
info"
></div>
<div
id=
"openassessment__staff
-
info"
></div>
{% endif %}
</div>
</div>
...
...
apps/openassessment/templates/openassessmentblock/staff_debug/staff_debug.html
View file @
57300f83
{% load i18n %}
{% load tz %}
<div
id=
"openassessment__staff
_
info"
class=
"wrapper--staff-info wrapper--ui-staff"
>
<div
id=
"openassessment__staff
-
info"
class=
"wrapper--staff-info wrapper--ui-staff"
>
<div
class=
"staff-info ui-staff ui-toggle-visibility is--collapsed"
>
<h2
class=
"staff-info__title ui-staff__title ui-toggle-visibility__control"
>
<i
class=
"ico icon-caret-right"
></i>
...
...
@@ -82,10 +82,10 @@
<div
class=
"wrapper--input"
class=
"staff-info__student__form"
>
<form
id=
"openassessment_student_info_form"
>
<ul>
<li
class=
"
label
"
>
<li
class=
"
openassessment__student-info_list
"
>
<label
for=
"openassessment__student_id"
class=
"label"
>
{% trans "Get Student Info" %}
</label>
</li>
<li>
<li
class=
"openassessment__student-info_list"
>
<input
id=
"openassessment__student_id"
type=
"text"
class=
"value"
maxlength=
"100"
>
</li>
</ul>
...
...
@@ -96,7 +96,7 @@
</ul>
</form>
</div>
<div
id=
"openassessment__student
_
info"
class=
"staff-info__student__report"
></div>
<div
id=
"openassessment__student
-
info"
class=
"staff-info__student__report"
></div>
</div>
</div>
</div>
...
...
apps/openassessment/templates/openassessmentblock/staff_debug/student_info.html
View file @
57300f83
{% load i18n %}
{% load tz %}
<div
id=
"openassessment__student
_
info"
class=
"staff-info__student__report"
>
<div
id=
"openassessment__student
-
info"
class=
"staff-info__student__report"
>
{% if submission %}
<h2
class=
"title"
>
<span
class=
"label"
>
{% trans "Student
Workflow
Information" %}
</span>
<span
class=
"label"
>
{% trans "Student Information" %}
</span>
</h2>
<div
class=
"staff-info__content ui-staff__content"
>
...
...
@@ -17,11 +17,11 @@
</div>
<div
class=
"staff-info__status ui-staff__content__section"
>
<h3
class=
"title"
>
{% trans "
Assessments on
Student" %}
</h3>
<h3
class=
"title"
>
{% trans "
Peer Assessments for This
Student" %}
</h3>
{% for assessment in peer_assessments %}
{% with peer_num=forloop.counter %}
<h4
class=
"title--sub"
>
{% trans "Peer" %} {{ peer_num }}:
</h4>
<table
class=
"staff-info__status__table"
summary=
"{% trans "
Assessment
from
Peer
"
%}"
>
<table
class=
"staff-info__status__table"
summary=
"{% trans "
Assessment
"
%}"
>
<thead>
<tr>
<th
abbr=
"Criterion"
scope=
"col"
>
{% trans "Criterion" %}
</th>
...
...
@@ -57,11 +57,11 @@
</div>
<div
class=
"staff-info__status ui-staff__content__section"
>
<h3
class=
"title"
>
{% trans "
Assessments submitted by
Student" %}
</h3>
<h3
class=
"title"
>
{% trans "
Peer Assessments Completed by This
Student" %}
</h3>
{% for assessment in submitted_assessments %}
{% with peer_num=forloop.counter %}
<h4
class=
"title--sub"
>
{% trans "Peer" %} {{ peer_num }}:
</h4>
<table
class=
"staff-info__status__table"
summary=
"{% trans "
Assessment
from
Student
"
%}"
>
<table
class=
"staff-info__status__table"
summary=
"{% trans "
Assessment
"
%}"
>
<thead>
<tr>
<th
abbr=
"Criterion"
scope=
"col"
>
{% trans "Criterion" %}
</th>
...
...
@@ -97,7 +97,7 @@
</div>
<div
class=
"staff-info__status ui-staff__content__section"
>
<h3
class=
"title"
>
{% trans "Student Self Assessment" %}
</h3>
<h3
class=
"title"
>
{% trans "Student
's
Self Assessment" %}
</h3>
<table
class=
"staff-info__status__table"
summary=
"{% trans "
Self
Assessment
"
%}"
>
<thead>
<tr>
...
...
@@ -126,6 +126,6 @@
</div>
</div>
{% else %}
{% trans "
No submission found for
student." %}
{% trans "
Couldn't find a response for this
student." %}
{% endif %}
</div>
\ No newline at end of file
apps/openassessment/xblock/staff_info_mixin.py
View file @
57300f83
...
...
@@ -29,7 +29,7 @@ class StaffInfoMixin(object):
return
self
.
render_error
(
_
(
u"You do not have permission to access staff information"
))
student_item
=
self
.
get_student_item_dict
()
context
=
dict
()
path
=
'openassessmentblock/staff_debug/staff_debug.html'
...
...
@@ -37,7 +37,7 @@ class StaffInfoMixin(object):
status_counts
,
num_submissions
=
self
.
get_workflow_status_counts
()
context
[
'status_counts'
]
=
status_counts
context
[
'num_submissions'
]
=
num_submissions
context
[
'item_id'
]
=
unicode
(
self
.
scope_ids
.
usage_id
)
context
[
'item_id'
]
=
student_item
[
"item_id"
]
# Include release/due dates for each step in the problem
context
[
'step_dates'
]
=
list
()
...
...
@@ -65,15 +65,25 @@ class StaffInfoMixin(object):
with submissions and assessments specific to the student.
Must be course staff to render this view.
"""
# If request does not come from course staff, return nothing.
# This should not be able to happen unless someone attempts to
# explicitly invoke this handler.
if
not
self
.
is_course_staff
or
self
.
in_studio_preview
:
return
self
.
render_error
(
_
(
u"You do not have permission to access student information"
))
u"You do not have permission to access student information."
))
path
,
context
=
self
.
get_student_info_path_and_context
(
data
)
return
self
.
render_assessment
(
path
,
context
)
def
get_student_info_path_and_context
(
self
,
data
):
"""
Get the proper path and context for rendering the the student info
section of the staff debug panel.
"""
student_id
=
data
.
params
.
get
(
'student_id'
,
''
)
submission_uuid
=
None
submission
=
None
...
...
@@ -117,4 +127,4 @@ class StaffInfoMixin(object):
criterion
[
"total_value"
]
=
max_scores
[
criterion
[
"name"
]]
path
=
'openassessmentblock/staff_debug/student_info.html'
return
self
.
render_assessment
(
path
,
context
)
\ No newline at end of file
return
path
,
context
\ No newline at end of file
apps/openassessment/xblock/static/css/openassessment.css
View file @
57300f83
...
...
@@ -2069,25 +2069,31 @@ hr.divider,
background
:
transparent
;
margin
:
40px
40px
;
}
.staff-info__student
.label
{
color
:
whitesmoke
;
margin-bottom
:
10px
;
}
.staff-info__student
.action--submit
{
margin-right
:
10px
;
margin-top
:
10px
;
margin-bottom
:
10px
;
}
.staff-info__student
.title
{
text-align
:
left
;
color
:
whitesmoke
;
margin-bottom
:
10px
;
}
.staff-info__student
.title--sub
{
color
:
whitesmoke
;
margin-top
:
10px
;
margin-bottom
:
10px
;
}
.staff-info__student
.student__answer__display__content
{
border
:
1px
solid
rgba
(
182
,
37
,
104
,
0.25
);
padding
:
10px
20px
10px
20px
;
margin-bottom
:
10px
;
}
.staff-info__student
{
/**
* The follow styles are bound for the "shame" file. This is done to override
* LMS specific styles on HTML elements.
*/
}
.staff-info__student
.label
{
color
:
whitesmoke
;
margin-bottom
:
10px
;
}
.staff-info__student
.action--submit
{
margin
:
10px
10px
10px
10px
;
}
.staff-info__student
.title
{
color
:
whitesmoke
;
margin-bottom
:
10px
;
}
.staff-info__student
.title--sub
{
color
:
whitesmoke
;
margin-top
:
10px
;
margin-bottom
:
10px
;
}
.staff-info__student
.student__answer__display__content
{
border
:
1px
solid
rgba
(
182
,
37
,
104
,
0.25
);
padding
:
10px
20px
10px
20px
;
margin-bottom
:
10px
;
}
.staff-info__student
.openassessment__student-info_list
{
list-style-type
:
none
;
}
.staff-info__student
.student__answer__display__content
p
{
color
:
inherit
;
}
.openassessment
.self-assessment__display__header
,
.openassessment
.peer-assessment__display__header
,
.openassessment
.step__header
{
margin-bottom
:
0
!important
;
...
...
apps/openassessment/xblock/static/js/openassessment.min.js
View file @
57300f83
This diff is collapsed.
Click to expand it.
apps/openassessment/xblock/static/js/src/oa_staff_info.js
View file @
57300f83
...
...
@@ -26,7 +26,7 @@ OpenAssessment.StaffInfoView.prototype = {
this
.
server
.
render
(
'staff_info'
).
done
(
function
(
html
)
{
// Load the HTML and install event handlers
$
(
'#openassessment__staff
_
info'
,
view
.
element
).
replaceWith
(
html
);
$
(
'#openassessment__staff
-
info'
,
view
.
element
).
replaceWith
(
html
);
view
.
installHandlers
();
}
).
fail
(
function
(
errMsg
)
{
...
...
@@ -41,12 +41,12 @@ OpenAssessment.StaffInfoView.prototype = {
**/
loadStudentInfo
:
function
()
{
var
view
=
this
;
var
sel
=
$
(
'#openassessment__staff
_
info'
,
this
.
element
);
var
sel
=
$
(
'#openassessment__staff
-
info'
,
this
.
element
);
var
student_id
=
sel
.
find
(
'#openassessment__student_id'
).
val
();
this
.
server
.
studentInfo
(
student_id
).
done
(
function
(
html
)
{
// Load the HTML and install event handlers
$
(
'#openassessment__student
_
info'
,
view
.
element
).
replaceWith
(
html
);
$
(
'#openassessment__student
-
info'
,
view
.
element
).
replaceWith
(
html
);
}
).
fail
(
function
(
errMsg
)
{
view
.
showLoadError
(
'student_info'
);
...
...
@@ -57,7 +57,7 @@ OpenAssessment.StaffInfoView.prototype = {
Install event handlers for the view.
**/
installHandlers
:
function
()
{
var
sel
=
$
(
'#openassessment__staff
_
info'
,
this
.
element
);
var
sel
=
$
(
'#openassessment__staff
-
info'
,
this
.
element
);
var
view
=
this
;
if
(
sel
.
length
<=
0
)
{
...
...
apps/openassessment/xblock/static/sass/oa/utilities/_developer.scss
View file @
57300f83
...
...
@@ -35,14 +35,11 @@
.action--submit
{
@extend
%btn--secondary
;
@extend
%action-2
;
margin-right
:
(
$baseline-v
/
2
);
margin-top
:
(
$baseline-v
/
2
);
margin-bottom
:
(
$baseline-v
/
2
);
margin
:
(
$baseline-v
/
2
)
(
$baseline-v
/
2
)
(
$baseline-v
/
2
)
(
$baseline-v
/
2
);
}
.title
{
@extend
%hd-2
;
text-align
:
left
;
color
:
$heading-staff-color
;
margin-bottom
:
(
$baseline-v
/
2
);
}
...
...
@@ -58,4 +55,18 @@
padding
:
(
$baseline-v
/
2
)
(
$baseline-h
/
2
)
(
$baseline-v
/
2
)
(
$baseline-h
/
2
);
margin-bottom
:
(
$baseline-v
/
2
);
}
.openassessment__student-info_list
{
list-style-type
:
none
;
}
/**
* The follow styles are bound for the "shame" file. This is done to override
* LMS specific styles on HTML elements.
*/
// 'p' elements in LMS have a color set on them.
.student__answer__display__content
p
{
color
:
inherit
;
}
}
\ No newline at end of file
apps/openassessment/xblock/test/data/peer_only_scenario.xml
0 → 100644
View file @
57300f83
<openassessment>
<title>
Open Assessment Test
</title>
<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.
</prompt>
<rubric>
<prompt>
Read for conciseness, clarity of thought, and form.
</prompt>
<criterion>
<name>
Concise
</name>
<prompt>
How concise is it?
</prompt>
<option
points=
"0"
>
<name>
Neal Stephenson (late)
</name>
<explanation>
Neal Stephenson explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
HP Lovecraft
</name>
<explanation>
HP Lovecraft explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
Robert Heinlein
</name>
<explanation>
Robert Heinlein explanation
</explanation>
</option>
<option
points=
"4"
>
<name>
Neal Stephenson (early)
</name>
<explanation>
Neal Stephenson (early) explanation
</explanation>
</option>
<option
points=
"5"
>
<name>
Earnest Hemingway
</name>
<explanation>
Earnest Hemingway
</explanation>
</option>
</criterion>
<criterion>
<name>
Clear-headed
</name>
<prompt>
How clear is the thinking?
</prompt>
<option
points=
"0"
>
<name>
Yogi Berra
</name>
<explanation>
Yogi Berra explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
Hunter S. Thompson
</name>
<explanation>
Hunter S. Thompson explanation
</explanation>
</option>
<option
points=
"2"
>
<name>
Robert Heinlein
</name>
<explanation>
Robert Heinlein explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
Isaac Asimov
</name>
<explanation>
Isaac Asimov explanation
</explanation>
</option>
<option
points=
"10"
>
<name>
Spock
</name>
<explanation>
Spock explanation
</explanation>
</option>
</criterion>
<criterion>
<name>
Form
</name>
<prompt>
Lastly, how is its form? Punctuation, grammar, and spelling all count.
</prompt>
<option
points=
"0"
>
<name>
lolcats
</name>
<explanation>
lolcats explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
Facebook
</name>
<explanation>
Facebook explanation
</explanation>
</option>
<option
points=
"2"
>
<name>
Reddit
</name>
<explanation>
Reddit explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
metafilter
</name>
<explanation>
metafilter explanation
</explanation>
</option>
<option
points=
"4"
>
<name>
Usenet, 1996
</name>
<explanation>
Usenet, 1996 explanation
</explanation>
</option>
<option
points=
"5"
>
<name>
The Elements of Style
</name>
<explanation>
The Elements of Style explanation
</explanation>
</option>
</criterion>
</rubric>
<assessments>
<assessment
name=
"peer-assessment"
must_grade=
"5"
must_be_graded_by=
"3"
/>
</assessments>
</openassessment>
apps/openassessment/xblock/test/data/self_only_scenario.xml
0 → 100644
View file @
57300f83
<openassessment>
<title>
Open Assessment Test
</title>
<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.
</prompt>
<rubric>
<prompt>
Read for conciseness, clarity of thought, and form.
</prompt>
<criterion>
<name>
Concise
</name>
<prompt>
How concise is it?
</prompt>
<option
points=
"0"
>
<name>
Neal Stephenson (late)
</name>
<explanation>
Neal Stephenson explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
HP Lovecraft
</name>
<explanation>
HP Lovecraft explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
Robert Heinlein
</name>
<explanation>
Robert Heinlein explanation
</explanation>
</option>
<option
points=
"4"
>
<name>
Neal Stephenson (early)
</name>
<explanation>
Neal Stephenson (early) explanation
</explanation>
</option>
<option
points=
"5"
>
<name>
Earnest Hemingway
</name>
<explanation>
Earnest Hemingway
</explanation>
</option>
</criterion>
<criterion>
<name>
Clear-headed
</name>
<prompt>
How clear is the thinking?
</prompt>
<option
points=
"0"
>
<name>
Yogi Berra
</name>
<explanation>
Yogi Berra explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
Hunter S. Thompson
</name>
<explanation>
Hunter S. Thompson explanation
</explanation>
</option>
<option
points=
"2"
>
<name>
Robert Heinlein
</name>
<explanation>
Robert Heinlein explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
Isaac Asimov
</name>
<explanation>
Isaac Asimov explanation
</explanation>
</option>
<option
points=
"10"
>
<name>
Spock
</name>
<explanation>
Spock explanation
</explanation>
</option>
</criterion>
<criterion>
<name>
Form
</name>
<prompt>
Lastly, how is its form? Punctuation, grammar, and spelling all count.
</prompt>
<option
points=
"0"
>
<name>
lolcats
</name>
<explanation>
lolcats explanation
</explanation>
</option>
<option
points=
"1"
>
<name>
Facebook
</name>
<explanation>
Facebook explanation
</explanation>
</option>
<option
points=
"2"
>
<name>
Reddit
</name>
<explanation>
Reddit explanation
</explanation>
</option>
<option
points=
"3"
>
<name>
metafilter
</name>
<explanation>
metafilter explanation
</explanation>
</option>
<option
points=
"4"
>
<name>
Usenet, 1996
</name>
<explanation>
Usenet, 1996 explanation
</explanation>
</option>
<option
points=
"5"
>
<name>
The Elements of Style
</name>
<explanation>
The Elements of Style explanation
</explanation>
</option>
</criterion>
</rubric>
<assessments>
<assessment
name=
"self-assessment"
/>
</assessments>
</openassessment>
apps/openassessment/xblock/test/test_staff_info.py
View file @
57300f83
...
...
@@ -49,10 +49,8 @@ class TestCourseStaff(XBlockHandlerTestCase):
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_course_staff_debug_info
(
self
,
xblock
):
# If we're not course staff, we shouldn't see the debug info
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
anonymous_student_id
=
'test_student'
,
user_is_staff
=
False
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
False
,
"Bob"
)
resp
=
self
.
request
(
xblock
,
'render_staff_info'
,
json
.
dumps
({}))
self
.
assertNotIn
(
"course staff information"
,
resp
.
decode
(
'utf-8'
)
.
lower
())
...
...
@@ -62,15 +60,28 @@ class TestCourseStaff(XBlockHandlerTestCase):
resp
=
self
.
request
(
xblock
,
'render_staff_info'
,
json
.
dumps
({}))
self
.
assertIn
(
"course staff information"
,
resp
.
decode
(
'utf-8'
)
.
lower
())
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_course_student_debug_info
(
self
,
xblock
):
# If we're not course staff, we shouldn't see the debug info
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
False
,
"Bob"
)
resp
=
self
.
request
(
xblock
,
'render_student_info'
,
json
.
dumps
({}))
self
.
assertIn
(
"you do not have permission"
,
resp
.
decode
(
'utf-8'
)
.
lower
())
# If we ARE course staff, then we should see the debug info
xblock
.
xmodule_runtime
.
user_is_staff
=
True
resp
=
self
.
request
(
xblock
,
'render_student_info'
,
json
.
dumps
({}))
self
.
assertIn
(
"couldn
\'
t find a response for this student."
,
resp
.
decode
(
'utf-8'
)
.
lower
())
@scenario
(
'data/basic_scenario.xml'
)
def
test_hide_course_staff_debug_info_in_studio_preview
(
self
,
xblock
):
# If we are in Studio preview mode, don't show the staff debug info
# In this case, the runtime will tell us that we're staff,
# but no user ID will be set.
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
anonymous_student_id
=
'test_student'
,
user_is_staff
=
True
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
resp
=
self
.
request
(
xblock
,
'render_staff_info'
,
json
.
dumps
({}))
self
.
assertNotIn
(
"course staff information"
,
resp
.
decode
(
'utf-8'
)
.
lower
())
...
...
@@ -78,10 +89,8 @@ class TestCourseStaff(XBlockHandlerTestCase):
@scenario
(
'data/staff_dates_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_dates_table
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
anonymous_student_id
=
'test_student'
,
user_is_staff
=
True
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
# Verify that we can render without error
...
...
@@ -101,10 +110,8 @@ class TestCourseStaff(XBlockHandlerTestCase):
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_dates_distant_past_and_future
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
anonymous_student_id
=
'test_student'
,
user_is_staff
=
True
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
# Verify that we can render without error
...
...
@@ -115,25 +122,91 @@ class TestCourseStaff(XBlockHandlerTestCase):
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_student_info_no_submission
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
anonymous_student_id
=
'test_student'
,
user_is_staff
=
True
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
request
=
namedtuple
(
'Request'
,
'params'
)
request
.
params
=
{
"student_id"
:
"test_student"
}
# Verify that we can render without error
resp
=
xblock
.
render_student_info
(
request
)
self
.
assertIn
(
"no submission"
,
resp
.
body
.
lower
())
self
.
assertIn
(
"couldn
\'
t find a response for this student."
,
resp
.
body
.
lower
())
@scenario
(
'data/peer_only_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_student_info_peer_only
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
bob_item
=
STUDENT_ITEM
.
copy
()
bob_item
[
"item_id"
]
=
xblock
.
scope_ids
.
usage_id
# Create a submission for Bob, and corresponding workflow.
submission
=
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
})
peer_api
.
create_peer_workflow
(
submission
[
"uuid"
])
workflow_api
.
create_workflow
(
submission
[
"uuid"
],
[
'peer'
])
# Create a submission for Tim, and corresponding workflow.
tim_item
=
bob_item
.
copy
()
tim_item
[
"student_id"
]
=
"Tim"
tim_sub
=
sub_api
.
create_submission
(
tim_item
,
"Tim Answer"
)
peer_api
.
create_peer_workflow
(
tim_sub
[
"uuid"
])
workflow_api
.
create_workflow
(
tim_sub
[
"uuid"
],
[
'peer'
,
'self'
])
# Bob assesses Tim.
peer_api
.
get_submission_to_assess
(
submission
[
'uuid'
],
1
)
peer_api
.
create_assessment
(
submission
[
"uuid"
],
STUDENT_ITEM
[
"student_id"
],
ASSESSMENT_DICT
[
'options_selected'
],
dict
(),
""
,
{
'criteria'
:
xblock
.
rubric_criteria
},
1
,
)
# Now Bob should be fully populated in the student info view.
request
=
namedtuple
(
'Request'
,
'params'
)
request
.
params
=
{
"student_id"
:
"Bob"
}
# Verify that we can render without error
path
,
context
=
xblock
.
get_student_info_path_and_context
(
request
)
self
.
assertEquals
(
"Bob Answer"
,
context
[
'submission'
][
'answer'
][
'text'
])
self
.
assertIsNone
(
context
[
'self_assessment'
])
self
.
assertEquals
(
"openassessmentblock/staff_debug/student_info.html"
,
path
)
@scenario
(
'data/self_only_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_student_info_self_only
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
bob_item
=
STUDENT_ITEM
.
copy
()
bob_item
[
"item_id"
]
=
xblock
.
scope_ids
.
usage_id
# Create a submission for Bob, and corresponding workflow.
submission
=
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
})
peer_api
.
create_peer_workflow
(
submission
[
"uuid"
])
workflow_api
.
create_workflow
(
submission
[
"uuid"
],
[
'self'
])
# Bob assesses himself.
self_api
.
create_assessment
(
submission
[
'uuid'
],
STUDENT_ITEM
[
"student_id"
],
ASSESSMENT_DICT
[
'options_selected'
],
{
'criteria'
:
xblock
.
rubric_criteria
},
)
# Now Bob should be fully populated in the student info view.
request
=
namedtuple
(
'Request'
,
'params'
)
request
.
params
=
{
"student_id"
:
"Bob"
}
# Verify that we can render without error
path
,
context
=
xblock
.
get_student_info_path_and_context
(
request
)
self
.
assertEquals
(
"Bob Answer"
,
context
[
'submission'
][
'answer'
][
'text'
])
self
.
assertEquals
([],
context
[
'peer_assessments'
])
self
.
assertEquals
(
"openassessmentblock/staff_debug/student_info.html"
,
path
)
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_student_info_full_workflow
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
Mock
(
course_id
=
'test_course'
,
item_id
=
xblock
.
scope_ids
.
usage_id
,
anonymous_student_id
=
'Bob'
,
user_is_staff
=
True
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
"Bob"
)
bob_item
=
STUDENT_ITEM
.
copy
()
...
...
@@ -173,5 +246,16 @@ class TestCourseStaff(XBlockHandlerTestCase):
request
.
params
=
{
"student_id"
:
"Bob"
}
# Verify that we can render without error
resp
=
xblock
.
render_student_info
(
request
)
print
resp
.
body
.
lower
()
self
.
assertIn
(
"bob answer"
,
resp
.
body
.
lower
())
\ No newline at end of file
self
.
assertIn
(
"bob answer"
,
resp
.
body
.
lower
())
def
_create_mock_runtime
(
self
,
item_id
,
is_staff
,
anonymous_user_id
):
mock_runtime
=
Mock
(
course_id
=
'test_course'
,
item_id
=
item_id
,
anonymous_student_id
=
'Bob'
,
user_is_staff
=
is_staff
,
service
=
lambda
self
,
service
:
Mock
(
get_anonymous_student_id
=
lambda
user_id
,
course_id
:
anonymous_user_id
)
)
return
mock_runtime
\ 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