Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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-platform
Commits
b3ec4d1b
Commit
b3ec4d1b
authored
May 08, 2014
by
Carson Gee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switching to new dashboard API and adding rescore to actions list
parent
2998a2e9
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
189 additions
and
58 deletions
+189
-58
common/test/acceptance/pages/lms/staff_view.py
+9
-0
common/test/acceptance/tests/test_staff_view.py
+53
-12
lms/static/js/spec/staff_debug_actions_spec.js
+38
-14
lms/static/js/staff_debug_actions.js
+61
-18
lms/static/sass/course/courseware/_courseware.scss
+9
-0
lms/templates/staff_problem_info.html
+19
-14
No files found.
common/test/acceptance/pages/lms/staff_view.py
View file @
b3ec4d1b
...
...
@@ -66,6 +66,15 @@ class StaffDebugPage(PageObject):
self
.
q
(
css
=
'input[id^=sd_fu_]'
)
.
fill
(
user
)
self
.
q
(
css
=
'section.staff-modal a#staff-debug-sdelete'
)
.
click
()
def
rescore
(
self
,
user
=
None
):
"""
This clicks on the reset attempts link with an optionally
specified user.
"""
if
user
:
self
.
q
(
css
=
'input[id^=sd_fu_]'
)
.
first
.
fill
(
user
)
self
.
q
(
css
=
'section.staff-modal a#staff-debug-rescore'
)
.
click
()
@property
def
idash_msg
(
self
):
"""
...
...
common/test/acceptance/tests/test_staff_view.py
View file @
b3ec4d1b
...
...
@@ -16,6 +16,7 @@ class StaffDebugTest(UniqueCourseTest):
Tests that verify the staff debug info.
"""
USERNAME
=
"STAFF_TESTER"
EMAIL
=
"johndoe@example.com"
def
setUp
(
self
):
super
(
StaffDebugTest
,
self
)
.
setUp
()
...
...
@@ -49,7 +50,7 @@ class StaffDebugTest(UniqueCourseTest):
# Auto-auth register for the course.
# Do this as global staff so that you will see the Staff View
AutoAuthPage
(
self
.
browser
,
username
=
self
.
USERNAME
,
AutoAuthPage
(
self
.
browser
,
username
=
self
.
USERNAME
,
email
=
self
.
EMAIL
,
course_id
=
self
.
course_id
,
staff
=
True
)
.
visit
()
def
_goto_staff_page
(
self
):
...
...
@@ -63,15 +64,14 @@ class StaffDebugTest(UniqueCourseTest):
def
test_reset_attempts_empty
(
self
):
"""
Test that we
fail properly
when there is no student state
Test that we
reset even
when there is no student state
"""
staff_debug_page
=
self
.
_goto_staff_page
()
.
open_staff_debug_info
()
staff_debug_page
.
reset_attempts
()
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assertIn
((
u"Found a single student. Found module. Couldn't "
"reset module state for {0}/"
)
.
format
(
self
.
USERNAME
),
msg
)
self
.
assertEqual
(
u'Successfully reset the attempts '
'for user {}'
.
format
(
self
.
USERNAME
),
msg
)
def
test_delete_state_empty
(
self
):
"""
...
...
@@ -80,8 +80,8 @@ class StaffDebugTest(UniqueCourseTest):
staff_debug_page
=
self
.
_goto_staff_page
()
.
open_staff_debug_info
()
staff_debug_page
.
delete_state
()
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assert
In
((
u"Found a single student. Found module. "
"Deleted student module state for"
),
msg
)
self
.
assert
Equal
(
u'Successfully deleted student state '
'for user {}'
.
format
(
self
.
USERNAME
),
msg
)
def
test_reset_attempts_state
(
self
):
"""
...
...
@@ -93,10 +93,25 @@ class StaffDebugTest(UniqueCourseTest):
staff_debug_page
=
staff_page
.
open_staff_debug_info
()
staff_debug_page
.
reset_attempts
()
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assert
In
((
u"Found a single student. Found module. Module "
"state successfully reset!"
),
msg
)
self
.
assert
Equal
(
u'Successfully reset the attempts '
'for user {}'
.
format
(
self
.
USERNAME
),
msg
)
def
test_student_state_state
(
self
):
def
test_rescore_state
(
self
):
"""
Rescore the student
"""
staff_page
=
self
.
_goto_staff_page
()
staff_page
.
answer_problem
()
staff_debug_page
=
staff_page
.
open_staff_debug_info
()
staff_debug_page
.
rescore
()
msg
=
staff_debug_page
.
idash_msg
[
0
]
# Since we aren't running celery stuff, this will fail badly
# for now, but is worth excercising that bad of a response
self
.
assertEqual
(
u'Unsuccessfully rescored problem. '
'Unknown Error Occurred.'
,
msg
)
def
test_student_state_delete
(
self
):
"""
Successfully delete the student state with an answer
"""
...
...
@@ -106,5 +121,31 @@ class StaffDebugTest(UniqueCourseTest):
staff_debug_page
=
staff_page
.
open_staff_debug_info
()
staff_debug_page
.
delete_state
()
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assertIn
((
u"Found a single student. Found module. "
"Deleted student module state for"
),
msg
)
self
.
assertEqual
(
u'Successfully deleted student state '
'for user {}'
.
format
(
self
.
USERNAME
),
msg
)
def
test_student_by_email
(
self
):
"""
Successfully reset the student attempts using their email address
"""
staff_page
=
self
.
_goto_staff_page
()
staff_page
.
answer_problem
()
staff_debug_page
=
staff_page
.
open_staff_debug_info
()
staff_debug_page
.
reset_attempts
(
self
.
EMAIL
)
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assertEqual
(
u'Successfully reset the attempts '
'for user {}'
.
format
(
self
.
EMAIL
),
msg
)
def
test_bad_student
(
self
):
"""
Test negative response with invalid user
"""
staff_page
=
self
.
_goto_staff_page
()
staff_page
.
answer_problem
()
staff_debug_page
=
staff_page
.
open_staff_debug_info
()
staff_debug_page
.
delete_state
(
'INVALIDUSER'
)
msg
=
staff_debug_page
.
idash_msg
[
0
]
self
.
assertEqual
(
u'Unsuccessfully deleted student state. '
'User does not exist.'
,
msg
)
lms/static/js/spec/staff_debug_actions_spec.js
View file @
b3ec4d1b
...
...
@@ -6,7 +6,7 @@ describe('StaffDebugActions', function() {
describe
(
'get_url '
,
function
()
{
it
(
'defines url to courseware ajax entry point'
,
function
()
{
spyOn
(
StaffDebug
,
"get_current_url"
).
andReturn
(
"/courses/edX/Open_DemoX/edx_demo_course/courseware/stuff"
);
expect
(
StaffDebug
.
get_url
(
'
instructor'
)).
toBe
(
'/courses/edX/Open_DemoX/edx_demo_course/instructor
'
);
expect
(
StaffDebug
.
get_url
(
'
rescore_problem'
)).
toBe
(
'/courses/edX/Open_DemoX/edx_demo_course/instructor_dashboard/api/rescore_problem
'
);
});
});
...
...
@@ -26,21 +26,22 @@ describe('StaffDebugActions', function() {
$
(
'#'
+
fixture_id
).
remove
();
});
});
describe
(
'reset'
,
function
()
{
it
(
'makes an ajax call with the expected parameters'
,
function
()
{
$
(
'body'
).
append
(
fixture
);
spyOn
(
$
,
'ajax'
);
StaffDebug
.
reset
(
loc
)
StaffDebug
.
reset
(
loc
)
;
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'type'
]).
toEqual
(
'
POS
T'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'type'
]).
toEqual
(
'
GE
T'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'data'
]).
toEqual
({
'
action'
:
"Reset student's attempts"
,
'
problem_for_student'
:
loc
,
'
unique_student_identifier'
:
'userman'
'
problem_to_reset'
:
loc
,
'
unique_student_identifier'
:
'userman'
,
'
delete_module'
:
false
});
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'url'
]).
toEqual
(
'/instructor'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'url'
]).
toEqual
(
'/instructor_dashboard/api/reset_student_attempts'
);
$
(
'#'
+
fixture_id
).
remove
();
});
});
...
...
@@ -49,17 +50,40 @@ describe('StaffDebugActions', function() {
$
(
'body'
).
append
(
fixture
);
spyOn
(
$
,
'ajax'
);
StaffDebug
.
sdelete
(
loc
)
StaffDebug
.
sdelete
(
loc
)
;
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'type'
]).
toEqual
(
'
POS
T'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'type'
]).
toEqual
(
'
GE
T'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'data'
]).
toEqual
({
'
action'
:
"Delete student state for module"
,
'
problem_for_student'
:
loc
,
'
unique_student_identifier'
:
'userman'
'
problem_to_reset'
:
loc
,
'
unique_student_identifier'
:
'userman'
,
'
delete_module'
:
true
});
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'url'
]).
toEqual
(
'/instructor'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'url'
]).
toEqual
(
'/instructor_dashboard/api/reset_student_attempts'
);
$
(
'#'
+
fixture_id
).
remove
();
});
});
describe
(
'rescore'
,
function
()
{
it
(
'makes an ajax call with the expected parameters'
,
function
()
{
$
(
'body'
).
append
(
fixture
);
spyOn
(
$
,
'ajax'
);
StaffDebug
.
rescore
(
loc
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'type'
]).
toEqual
(
'GET'
);
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'data'
]).
toEqual
({
'problem_to_reset'
:
loc
,
'unique_student_identifier'
:
'userman'
,
'delete_module'
:
false
});
expect
(
$
.
ajax
.
mostRecentCall
.
args
[
0
][
'url'
]).
toEqual
(
'/instructor_dashboard/api/rescore_problem'
);
$
(
'#'
+
fixture_id
).
remove
();
});
});
});
lms/static/js/staff_debug_actions.js
View file @
b3ec4d1b
...
...
@@ -7,7 +7,7 @@ var StaffDebug = (function(){
get_url
=
function
(
action
){
var
pathname
=
this
.
get_current_url
();
var
url
=
pathname
.
substr
(
0
,
pathname
.
indexOf
(
'/courseware'
))
+
'/'
+
action
;
var
url
=
pathname
.
substr
(
0
,
pathname
.
indexOf
(
'/courseware'
))
+
'/
instructor_dashboard/api/
'
+
action
;
return
url
;
}
...
...
@@ -19,50 +19,89 @@ var StaffDebug = (function(){
return
uname
;
}
do_idash_action
=
function
(
locname
,
id
action
){
do_idash_action
=
function
(
action
){
var
pdata
=
{
'
action'
:
idac
tion
,
'
problem_for_student'
:
locname
,
'
unique_student_identifier'
:
get_user
(
locname
)
'
problem_to_reset'
:
action
.
loca
tion
,
'
unique_student_identifier'
:
get_user
(
action
.
location
)
,
'
delete_module'
:
action
.
delete_module
}
$
.
ajax
({
type
:
"
POS
T"
,
url
:
get_url
(
'instructor'
),
type
:
"
GE
T"
,
url
:
get_url
(
action
.
method
),
data
:
pdata
,
success
:
function
(
data
){
var
msg
=
$
(
"#idash_msg"
,
data
);
$
(
"#result_"
+
locname
).
html
(
msg
);
var
text
=
_
.
template
(
gettext
(
'Successfully {action} for user {user}'
),
{
action
:
action
.
description
,
user
:
data
.
student
},
{
interpolate
:
/
\{(
.+
?)\}
/g
}
)
var
html
=
_
.
template
(
'<p id="idash_msg" class="success">{text}</p>'
,
{
text
:
text
},
{
interpolate
:
/
\{(
.+
?)\}
/g
}
)
$
(
"#result_"
+
action
.
location
).
html
(
html
);
},
error
:
function
(
request
,
status
,
error
)
{
var
response_json
;
try
{
response_json
=
$
.
parseJSON
(
request
.
responseText
);
}
catch
(
e
)
{
response_json
=
{
error
:
gettext
(
'Unknown Error Occurred.'
)
};
}
var
text
=
_
.
template
(
gettext
(
'Something has gone wrong with this request.
\
The server replied with a status of: {error}'
),
{
error
:
error
},
gettext
(
'Unsuccessfully {action}. {error}'
),
{
error
:
response_json
.
error
,
action
:
action
.
description
},
{
interpolate
:
/
\{(
.+
?)\}
/g
}
)
var
html
=
_
.
template
(
'<p id="idash_msg"
><font color="red">{text}</font>
</p>'
,
'<p id="idash_msg"
class="error">{text}
</p>'
,
{
text
:
text
},
{
interpolate
:
/
\{(
.+
?)\}
/g
}
)
$
(
"#result_"
+
locname
).
html
(
html
);
$
(
"#result_"
+
action
.
location
).
html
(
html
);
},
dataType
:
'
html
'
dataType
:
'
json
'
});
}
reset
=
function
(
locname
){
do_idash_action
(
locname
,
"Reset student's attempts"
);
this
.
do_idash_action
({
location
:
locname
,
method
:
'reset_student_attempts'
,
description
:
gettext
(
'reset the attempts'
),
delete_module
:
false
});
}
sdelete
=
function
(
locname
){
do_idash_action
(
locname
,
"Delete student state for module"
);
this
.
do_idash_action
({
location
:
locname
,
method
:
'reset_student_attempts'
,
description
:
gettext
(
'deleted student state'
),
delete_module
:
true
});
}
rescore
=
function
(
locname
){
this
.
do_idash_action
({
location
:
locname
,
method
:
'rescore_problem'
,
description
:
gettext
(
'rescored problem'
),
delete_module
:
false
});
}
return
{
reset
:
reset
,
sdelete
:
sdelete
,
rescore
:
rescore
,
do_idash_action
:
do_idash_action
,
get_current_url
:
get_current_url
,
get_url
:
get_url
,
...
...
@@ -80,4 +119,8 @@ $(document).ready(function() {
StaffDebug
.
sdelete
(
$
(
this
).
data
(
'location'
));
return
false
;
});
$
(
'#staff-debug-rescore'
).
click
(
function
()
{
StaffDebug
.
rescore
(
$
(
this
).
data
(
'location'
));
return
false
;
});
});
lms/static/sass/course/courseware/_courseware.scss
View file @
b3ec4d1b
...
...
@@ -191,6 +191,15 @@ div.course-wrapper {
}
}
div
.staff_actions
{
p
.error
{
color
:
$error-red
}
p
.success
{
color
:
$success-color
;
}
}
div
.staff_info
{
display
:
none
;
@include
clearfix
();
...
...
lms/templates/staff_problem_info.html
View file @
b3ec4d1b
...
...
@@ -54,20 +54,25 @@ ${block_content}
<h2>
${_('Staff Debug')}
</h2>
</header>
<hr
/>
<h3>
${_('Actions')}
</h3>
<div>
<label
for=
"sd_fu_${location.name}"
>
${_('For User')}:
</label>
<input
type=
"text"
id=
"sd_fu_${location.name}"
placeholder=
"${user.username}"
/>
</div>
<div>
[
<a
href=
"#"
id=
"staff-debug-reset"
data-location=
"${location.name}"
>
${_('Reset Student Attempts')}
</a>
|
<a
href=
"#"
id=
"staff-debug-sdelete"
data-location=
"${location.name}"
>
${_('Delete Student State')}
</a>
]
</div>
<div
id=
"result_${location.name}"
/>
<hr
/>
<div
class=
"staff_actions"
>
<h3>
${_('Actions')}
</h3>
<div>
<label
for=
"sd_fu_${location.name}"
>
${_('Username')}:
</label>
<input
type=
"text"
id=
"sd_fu_${location.name}"
placeholder=
"${user.username}"
/>
</div>
<div>
[
<a
href=
"#"
id=
"staff-debug-reset"
data-location=
"${location.name}"
>
${_('Reset Student Attempts')}
</a>
|
<a
href=
"#"
id=
"staff-debug-sdelete"
data-location=
"${location.name}"
>
${_('Delete Student State')}
</a>
|
<a
href=
"#"
id=
"staff-debug-rescore"
data-location=
"${location.name}"
>
${_('Rescore Student Submission')}
</a>
]
</div>
<div
id=
"result_${location.name}"
/>
</div>
<div
class=
"staff_info"
style=
"display:block"
>
is_released = ${is_released}
...
...
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