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
e3fe2cbf
Commit
e3fe2cbf
authored
Jan 05, 2015
by
muzaffaryousaf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changing the student anonymous_user_id to student name.
TNL-836
parent
d11f3139
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
99 additions
and
58 deletions
+99
-58
openassessment/templates/openassessmentblock/staff_debug/staff_debug.html
+3
-3
openassessment/xblock/openassessmentblock.py
+27
-3
openassessment/xblock/staff_info_mixin.py
+31
-30
openassessment/xblock/static/js/openassessment-lms.min.js
+0
-0
openassessment/xblock/static/js/openassessment-studio.min.js
+0
-0
openassessment/xblock/static/js/src/lms/oa_staff_info.js
+3
-3
openassessment/xblock/static/js/src/oa_server.js
+2
-2
openassessment/xblock/test/test_staff_info.py
+33
-17
No files found.
openassessment/templates/openassessmentblock/staff_debug/staff_debug.html
View file @
e3fe2cbf
...
...
@@ -129,15 +129,15 @@
<form
id=
"openassessment_student_info_form"
>
<ul>
<li
class=
"openassessment__student-info_list"
>
<label
for=
"openassessment__student_
id
"
class=
"label"
>
{% trans "Get Student Info" %}
</label>
<label
for=
"openassessment__student_
username
"
class=
"label"
>
{% trans "Get Student Info" %}
</label>
</li>
<li
class=
"openassessment__student-info_list"
>
<input
id=
"openassessment__student_
id
"
type=
"text"
class=
"value"
maxlength=
"255"
>
<input
id=
"openassessment__student_
username
"
type=
"text"
class=
"value"
maxlength=
"255"
>
</li>
</ul>
<ul
class=
"list list--actions"
>
<li
class=
"list--actions__item"
>
<a
aria-role=
"button"
href=
""
id=
"submit_student_
id
"
class=
"action--submit"
><span
class=
"copy"
>
{% trans "Submit" %}
</span></a>
<a
aria-role=
"button"
href=
""
id=
"submit_student_
username
"
class=
"action--submit"
><span
class=
"copy"
>
{% trans "Submit" %}
</span></a>
</li>
</ul>
</form>
...
...
openassessment/xblock/openassessmentblock.py
View file @
e3fe2cbf
...
...
@@ -90,6 +90,7 @@ def load(path):
return
data
.
decode
(
"utf8"
)
@XBlock.needs
(
"i18n"
)
@XBlock.needs
(
"user"
)
class
OpenAssessmentBlock
(
MessageMixin
,
SubmissionMixin
,
...
...
@@ -200,22 +201,45 @@ class OpenAssessmentBlock(
help
=
"Indicates whether or not there are peers to grade."
)
def
get_student_item_dict
(
self
):
@property
def
course_id
(
self
):
return
self
.
_serialize_opaque_key
(
self
.
xmodule_runtime
.
course_id
)
# pylint:disable=E1101
def
get_anonymous_user_id
(
self
,
username
,
course_id
):
"""
Get the anonymous user id from Xblock user service.
Args:
username(str): user's name entered by staff to get info.
course_id(str): course id.
Returns:
A unique id for (user, course) pair
"""
return
self
.
runtime
.
service
(
self
,
'user'
)
.
get_anonymous_user_id
(
username
,
course_id
)
def
get_student_item_dict
(
self
,
anonymous_user_id
=
None
):
"""Create a student_item_dict from our surrounding context.
See also: submissions.api for details.
Args:
anonymous_user_id(str):
Returns:
(dict): The student item associated with this XBlock instance. This
includes the student id, item id, and course id.
"""
item_id
=
self
.
_serialize_opaque_key
(
self
.
scope_ids
.
usage_id
)
# This is not the real way course_ids should work, but this is a
# temporary expediency for LMS integration
if
hasattr
(
self
,
"xmodule_runtime"
):
course_id
=
self
.
_serialize_opaque_key
(
self
.
xmodule_runtime
.
course_id
)
# pylint:disable=E1101
student_id
=
self
.
xmodule_runtime
.
anonymous_student_id
# pylint:disable=E1101
course_id
=
self
.
course_id
# pylint:disable=E1101
if
anonymous_user_id
:
student_id
=
anonymous_user_id
else
:
student_id
=
self
.
xmodule_runtime
.
anonymous_student_id
# pylint:disable=E1101
else
:
course_id
=
"edX/Enchantment_101/April_1"
if
self
.
scope_ids
.
user_id
is
None
:
...
...
openassessment/xblock/staff_info_mixin.py
View file @
e3fe2cbf
...
...
@@ -208,58 +208,59 @@ class StaffInfoMixin(object):
"""
Renders all relative information for a specific student's workflow.
Given a student's
ID
, we can render a staff-only section of the page
Given a student's
username
, we can render a staff-only section of the page
with submissions and assessments specific to the student.
Must be course staff to render this view.
"""
try
:
student_
id
=
data
.
params
.
get
(
'student_id
'
,
''
)
path
,
context
=
self
.
get_student_info_path_and_context
(
student_
id
)
student_
username
=
data
.
params
.
get
(
'student_username
'
,
''
)
path
,
context
=
self
.
get_student_info_path_and_context
(
student_
username
)
return
self
.
render_assessment
(
path
,
context
)
except
PeerAssessmentInternalError
:
return
self
.
render_error
(
self
.
_
(
u"Error finding assessment workflow cancellation."
))
def
get_student_info_path_and_context
(
self
,
student_
id
):
def
get_student_info_path_and_context
(
self
,
student_
username
):
"""
Get the proper path and context for rendering the the student info
section of the staff debug panel.
Args:
student_
id (unicode): The ID
of the student to report.
student_
username (unicode): The username
of the student to report.
"""
submission_uuid
=
None
submission
=
None
assessment_steps
=
self
.
assessment_steps
if
student_id
:
student_item
=
self
.
get_student_item_dict
()
student_item
[
'student_id'
]
=
student_id
# If there is a submission available for the requested student, present
# it. If not, there will be no other information to collect.
submissions
=
submission_api
.
get_submissions
(
student_item
,
1
)
if
submissions
:
submission_uuid
=
submissions
[
0
][
'uuid'
]
submission
=
submissions
[
0
]
if
'file_key'
in
submission
.
get
(
'answer'
,
{}):
file_key
=
submission
[
'answer'
][
'file_key'
]
try
:
submission
[
'image_url'
]
=
file_api
.
get_download_url
(
file_key
)
except
file_api
.
FileUploadError
:
# Log the error, but do not prevent the rest of the student info
# from being displayed.
msg
=
(
u"Could not retrieve image URL for staff debug page. "
u"The student ID is '{student_id}', and the file key is {file_key}"
)
.
format
(
student_id
=
student_id
,
file_key
=
file_key
)
logger
.
exception
(
msg
)
if
student_username
:
anonymous_user_id
=
self
.
get_anonymous_user_id
(
student_username
,
self
.
course_id
)
student_item
=
self
.
get_student_item_dict
(
anonymous_user_id
=
anonymous_user_id
)
if
anonymous_user_id
:
# If there is a submission available for the requested student, present
# it. If not, there will be no other information to collect.
submissions
=
submission_api
.
get_submissions
(
student_item
,
1
)
if
submissions
:
submission_uuid
=
submissions
[
0
][
'uuid'
]
submission
=
submissions
[
0
]
if
'file_key'
in
submission
.
get
(
'answer'
,
{}):
file_key
=
submission
[
'answer'
][
'file_key'
]
try
:
submission
[
'image_url'
]
=
file_api
.
get_download_url
(
file_key
)
except
file_api
.
FileUploadError
:
# Log the error, but do not prevent the rest of the student info
# from being displayed.
msg
=
(
u"Could not retrieve image URL for staff debug page. "
u"The student username is '{student_username}', and the file key is {file_key}"
)
.
format
(
student_username
=
student_username
,
file_key
=
file_key
)
logger
.
exception
(
msg
)
example_based_assessment
=
None
self_assessment
=
None
...
...
openassessment/xblock/static/js/openassessment-lms.min.js
View file @
e3fe2cbf
This diff is collapsed.
Click to expand it.
openassessment/xblock/static/js/openassessment-studio.min.js
View file @
e3fe2cbf
This diff is collapsed.
Click to expand it.
openassessment/xblock/static/js/src/lms/oa_staff_info.js
View file @
e3fe2cbf
...
...
@@ -48,8 +48,8 @@ OpenAssessment.StaffInfoView.prototype = {
loadStudentInfo
:
function
()
{
var
view
=
this
;
var
sel
=
$
(
'#openassessment__staff-info'
,
this
.
element
);
var
student_
id
=
sel
.
find
(
'#openassessment__student_id
'
).
val
();
this
.
server
.
studentInfo
(
student_
id
).
done
(
var
student_
username
=
sel
.
find
(
'#openassessment__student_username
'
).
val
();
this
.
server
.
studentInfo
(
student_
username
).
done
(
function
(
html
)
{
// Load the HTML and install event handlers
$
(
'#openassessment__student-info'
,
view
.
element
).
replaceWith
(
html
);
...
...
@@ -96,7 +96,7 @@ OpenAssessment.StaffInfoView.prototype = {
);
// Install a click handler for requesting student info
sel
.
find
(
'#submit_student_
id
'
).
click
(
sel
.
find
(
'#submit_student_
username
'
).
click
(
function
(
eventObject
)
{
eventObject
.
preventDefault
();
view
.
loadStudentInfo
();
...
...
openassessment/xblock/static/js/src/oa_server.js
View file @
e3fe2cbf
...
...
@@ -121,14 +121,14 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
/**
Load the Student Info section in Staff Info.
**/
studentInfo
:
function
(
student_
id
)
{
studentInfo
:
function
(
student_
username
)
{
var
url
=
this
.
url
(
'render_student_info'
);
return
$
.
Deferred
(
function
(
defer
)
{
$
.
ajax
({
url
:
url
,
type
:
"POST"
,
dataType
:
"html"
,
data
:
{
student_
id
:
student_id
}
data
:
{
student_
username
:
student_username
}
}).
done
(
function
(
data
)
{
defer
.
resolveWith
(
this
,
[
data
]);
}).
fail
(
function
(
data
)
{
...
...
openassessment/xblock/test/test_staff_info.py
View file @
e3fe2cbf
...
...
@@ -5,6 +5,8 @@ import datetime
import
urllib
from
mock
import
Mock
,
patch
from
django.test.utils
import
override_settings
import
ddt
from
openassessment.assessment.api
import
peer
as
peer_api
from
openassessment.assessment.api
import
self
as
self_api
from
openassessment.assessment.api
import
ai
as
ai_api
...
...
@@ -13,6 +15,7 @@ from openassessment.assessment.errors.ai import AIError, AIGradingInternalError
from
openassessment.fileupload.api
import
FileUploadInternalError
from
submissions
import
api
as
sub_api
from
openassessment.xblock.test.base
import
scenario
,
XBlockHandlerTestCase
from
xblock.core
import
XBlock
ALGORITHM_ID
=
'fake'
...
...
@@ -43,6 +46,14 @@ ASSESSMENT_DICT = {
}
class
NullUserService
(
object
):
"""
A simple implementation of the runtime "user" service.
"""
def
get_anonymous_user_id
(
self
,
username
,
course_id
):
return
username
class
TestCourseStaff
(
XBlockHandlerTestCase
):
"""
Tests for course staff debug panel.
...
...
@@ -66,7 +77,7 @@ 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
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
False
,
False
,
"Bob"
)
resp
=
self
.
request
(
xblock
,
'render_staff_info'
,
json
.
dumps
({}))
...
...
@@ -80,7 +91,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
@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
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
False
,
False
,
"Bob"
)
resp
=
self
.
request
(
xblock
,
'render_student_info'
,
json
.
dumps
({}))
...
...
@@ -96,7 +107,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
# 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
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
...
...
@@ -112,7 +123,7 @@ 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
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
...
...
@@ -137,7 +148,7 @@ 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
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
...
...
@@ -149,7 +160,7 @@ 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
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
request
=
namedtuple
(
'Request'
,
'params'
)
...
...
@@ -161,14 +172,15 @@ class TestCourseStaff(XBlockHandlerTestCase):
@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
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
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"
})
submission
=
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
})
peer_api
.
on_start
(
submission
[
"uuid"
])
workflow_api
.
create_workflow
(
submission
[
"uuid"
],
[
'peer'
])
...
...
@@ -201,11 +213,11 @@ class TestCourseStaff(XBlockHandlerTestCase):
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
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"
})
submission
=
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
})
peer_api
.
on_start
(
submission
[
"uuid"
])
workflow_api
.
create_workflow
(
submission
[
"uuid"
],
[
'self'
])
...
...
@@ -237,6 +249,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
bob_item
=
STUDENT_ITEM
.
copy
()
bob_item
[
"item_id"
]
=
xblock
.
scope_ids
.
usage_id
...
...
@@ -296,13 +309,14 @@ class TestCourseStaff(XBlockHandlerTestCase):
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
bob_item
=
STUDENT_ITEM
.
copy
()
bob_item
[
"item_id"
]
=
xblock
.
scope_ids
.
usage_id
# Create an image submission for Bob
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
,
'text'
:
"Bob Answer"
,
'file_key'
:
"test_key"
})
...
...
@@ -318,23 +332,24 @@ class TestCourseStaff(XBlockHandlerTestCase):
self
.
assertEquals
(
'http://www.example.com/image.jpeg'
,
context
[
'submission'
][
'image_url'
])
# Check the fully rendered template
payload
=
urllib
.
urlencode
({
"student_
id
"
:
"Bob"
})
payload
=
urllib
.
urlencode
({
"student_
username
"
:
"Bob"
})
resp
=
self
.
request
(
xblock
,
"render_student_info"
,
payload
)
self
.
assertIn
(
"http://www.example.com/image.jpeg"
,
resp
)
@scenario
(
'data/self_only_scenario.xml'
,
user_id
=
'Bob'
)
def
test_staff_debug_student_info_file_download_url_error
(
self
,
xblock
):
# Simulate that we are course staff
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
bob_item
=
STUDENT_ITEM
.
copy
()
bob_item
[
"item_id"
]
=
xblock
.
scope_ids
.
usage_id
# Create an image submission for Bob
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
,
'text'
:
"Bob Answer"
,
'file_key'
:
"test_key"
})
...
...
@@ -348,7 +363,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
self
.
assertNotIn
(
'image_url'
,
context
[
'submission'
])
# Check the fully rendered template
payload
=
urllib
.
urlencode
({
"student_
id
"
:
"Bob"
})
payload
=
urllib
.
urlencode
({
"student_
username
"
:
"Bob"
})
resp
=
self
.
request
(
xblock
,
"render_student_info"
,
payload
)
self
.
assertIn
(
"Bob Answer"
,
resp
)
...
...
@@ -359,6 +374,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
xblock
.
xmodule_runtime
=
self
.
_create_mock_runtime
(
xblock
.
scope_ids
.
usage_id
,
True
,
False
,
"Bob"
)
xblock
.
runtime
.
_services
[
'user'
]
=
NullUserService
()
# Commonly chosen options for assessments
options_selected
=
{
...
...
@@ -377,7 +393,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
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"
})
submission
=
sub_api
.
create_submission
(
bob_item
,
{
'text'
:
"Bob Answer"
})
peer_api
.
on_start
(
submission
[
"uuid"
])
workflow_api
.
create_workflow
(
submission
[
"uuid"
],
[
'peer'
,
'self'
])
...
...
@@ -410,7 +426,7 @@ class TestCourseStaff(XBlockHandlerTestCase):
# Now Bob should be fully populated in the student info view.
request
=
namedtuple
(
'Request'
,
'params'
)
request
.
params
=
{
"student_
id
"
:
"Bob"
}
request
.
params
=
{
"student_
username
"
:
"Bob"
}
# Verify that we can render without error
resp
=
xblock
.
render_student_info
(
request
)
self
.
assertIn
(
"bob answer"
,
resp
.
body
.
lower
())
...
...
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