fix: staff debug actions depended on legacy courseware URL (#26658)
The Staff Debug Actions didn't work in the Learning MFE because the underlying JS depended on the URL being formatted as /courses/<course_key>/... in order to parse out the course key. This worked in the legacy experience, but breaks in the chromeless xblock view, which is rendered under the URL /xblock/<usage_key>/... The fix is to explicitly pass the course key into the templated courseware HTML as a data attribute. TNL-7955
This commit is contained in:
@@ -9,7 +9,8 @@ define([
|
||||
var StaffDebug = window.StaffDebug;
|
||||
|
||||
describe('StaffDebugActions', function() {
|
||||
var location = 'i4x://edX/Open_DemoX/edx_demo_course/problem/test_loc';
|
||||
var courseId = 'course-v1:edX+DemoX+1';
|
||||
var location = 'block-v1:edX+DemoX+1+type@problem+block@9518dd51055b40cd82feb01502644c89';
|
||||
var locationName = 'test_loc';
|
||||
var usernameFixtureID = 'sd_fu_' + locationName;
|
||||
var $usernameFixture = $('<input>', {id: usernameFixtureID, placeholder: 'userman'});
|
||||
@@ -24,19 +25,15 @@ define([
|
||||
|
||||
describe('getURL ', function() {
|
||||
it('defines url to courseware ajax entry point', function() {
|
||||
spyOn(StaffDebug, 'getCurrentUrl')
|
||||
.and.returnValue('/courses/edX/Open_DemoX/edx_demo_course/courseware/stuff');
|
||||
expect(StaffDebug.getURL('rescore_problem'))
|
||||
.toBe('/courses/edX/Open_DemoX/edx_demo_course/instructor/api/rescore_problem');
|
||||
expect(StaffDebug.getURL(courseId, 'rescore_problem'))
|
||||
.toBe('/courses/course-v1:edX+DemoX+1/instructor/api/rescore_problem');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getURL ', function() {
|
||||
it('defines that getCurrentUrl works on instructor page as expected', function() {
|
||||
spyOn(StaffDebug, 'getCurrentUrl')
|
||||
.and.returnValue('/courses/edx_demo_course/instructor#view-open_response_assessment');
|
||||
expect(StaffDebug.getURL('rescore_problem'))
|
||||
.toBe('/courses/edx_demo_course/instructor/api/rescore_problem');
|
||||
it('defines url to courseware ajax entry point for deprecated courses', function() {
|
||||
expect(StaffDebug.getURL('edX/DemoX/1', 'rescore_problem'))
|
||||
.toBe('/courses/edX/DemoX/1/instructor/api/rescore_problem');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -87,6 +84,7 @@ define([
|
||||
$('body').append($escapableResultArea);
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var action = {
|
||||
courseId: courseId,
|
||||
locationName: esclocationName,
|
||||
success_msg: 'Successfully reset the attempts for user userman'
|
||||
};
|
||||
@@ -101,6 +99,7 @@ define([
|
||||
$('body').append($escapableResultArea);
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var action = {
|
||||
courseId: courseId,
|
||||
locationName: esclocationName,
|
||||
error_msg: 'Failed to reset attempts for user.'
|
||||
};
|
||||
@@ -115,7 +114,7 @@ define([
|
||||
$('body').append($usernameFixture);
|
||||
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.reset(locationName, location);
|
||||
StaffDebug.reset(courseId, locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
@@ -126,7 +125,7 @@ define([
|
||||
score: undefined
|
||||
});
|
||||
expect($.ajax.calls.mostRecent().args[0].url).toEqual(
|
||||
'/instructor/api/reset_student_attempts'
|
||||
'/courses/course-v1:edX+DemoX+1/instructor/api/reset_student_attempts'
|
||||
);
|
||||
$('#' + usernameFixtureID).remove();
|
||||
});
|
||||
@@ -136,7 +135,7 @@ define([
|
||||
$('body').append($usernameFixture);
|
||||
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.deleteStudentState(locationName, location);
|
||||
StaffDebug.deleteStudentState(courseId, locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
@@ -147,7 +146,7 @@ define([
|
||||
score: undefined
|
||||
});
|
||||
expect($.ajax.calls.mostRecent().args[0].url).toEqual(
|
||||
'/instructor/api/reset_student_attempts'
|
||||
'/courses/course-v1:edX+DemoX+1/instructor/api/reset_student_attempts'
|
||||
);
|
||||
|
||||
$('#' + usernameFixtureID).remove();
|
||||
@@ -158,7 +157,7 @@ define([
|
||||
$('body').append($usernameFixture);
|
||||
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.rescore(locationName, location);
|
||||
StaffDebug.rescore(courseId, locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
@@ -169,7 +168,7 @@ define([
|
||||
score: undefined
|
||||
});
|
||||
expect($.ajax.calls.mostRecent().args[0].url).toEqual(
|
||||
'/instructor/api/rescore_problem'
|
||||
'/courses/course-v1:edX+DemoX+1/instructor/api/rescore_problem'
|
||||
);
|
||||
$('#' + usernameFixtureID).remove();
|
||||
});
|
||||
@@ -179,7 +178,7 @@ define([
|
||||
$('body').append($usernameFixture);
|
||||
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.rescoreIfHigher(locationName, location);
|
||||
StaffDebug.rescoreIfHigher(courseId, locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
@@ -190,7 +189,7 @@ define([
|
||||
score: undefined
|
||||
});
|
||||
expect($.ajax.calls.mostRecent().args[0].url).toEqual(
|
||||
'/instructor/api/rescore_problem'
|
||||
'/courses/course-v1:edX+DemoX+1/instructor/api/rescore_problem'
|
||||
);
|
||||
$('#' + usernameFixtureID).remove();
|
||||
});
|
||||
@@ -201,7 +200,7 @@ define([
|
||||
$('body').append($scoreFixture);
|
||||
$('#' + scoreFixtureID).val('1');
|
||||
spyOn($, 'ajax');
|
||||
StaffDebug.overrideScore(locationName, location);
|
||||
StaffDebug.overrideScore(courseId, locationName, location);
|
||||
|
||||
expect($.ajax.calls.mostRecent().args[0].type).toEqual('POST');
|
||||
expect($.ajax.calls.mostRecent().args[0].data).toEqual({
|
||||
@@ -212,7 +211,7 @@ define([
|
||||
score: '1'
|
||||
});
|
||||
expect($.ajax.calls.mostRecent().args[0].url).toEqual(
|
||||
'/instructor/api/override_problem_score'
|
||||
'/courses/course-v1:edX+DemoX+1/instructor/api/override_problem_score'
|
||||
);
|
||||
$('#' + usernameFixtureID).remove();
|
||||
});
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
/* globals _ */
|
||||
// Build StaffDebug object
|
||||
var StaffDebug = (function() {
|
||||
/* global getCurrentUrl:true */
|
||||
var getURL = function(action) {
|
||||
var pathname = this.getCurrentUrl();
|
||||
var index = pathname.indexOf('/courseware');
|
||||
if (index <= 0) {
|
||||
index = pathname.indexOf('/', '/courses/'.length);
|
||||
}
|
||||
return pathname.substr(0, index) + '/instructor/api/' + action;
|
||||
var getURL = function(courseId, action) {
|
||||
return '/courses/' + courseId + '/instructor/api/' + action;
|
||||
};
|
||||
|
||||
var sanitizeString = function(string) {
|
||||
@@ -43,7 +37,7 @@ var StaffDebug = (function() {
|
||||
};
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: getURL(action.method),
|
||||
url: getURL(action.courseId, action.method),
|
||||
data: pdata,
|
||||
success: function(data) {
|
||||
var text = _.template(action.success_msg, {interpolate: /\{(.+?)\}/g})(
|
||||
@@ -82,8 +76,9 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
var reset = function(locname, location) {
|
||||
var reset = function(courseId, locname, location) {
|
||||
this.doInstructorDashAction({
|
||||
courseId: courseId,
|
||||
locationName: locname,
|
||||
location: location,
|
||||
method: 'reset_student_attempts',
|
||||
@@ -93,8 +88,9 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
var deleteStudentState = function(locname, location) {
|
||||
var deleteStudentState = function(courseId, locname, location) {
|
||||
this.doInstructorDashAction({
|
||||
courseId: courseId,
|
||||
locationName: locname,
|
||||
location: location,
|
||||
method: 'reset_student_attempts',
|
||||
@@ -104,8 +100,9 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
var rescore = function(locname, location) {
|
||||
var rescore = function(courseId, locname, location) {
|
||||
this.doInstructorDashAction({
|
||||
courseId: courseId,
|
||||
locationName: locname,
|
||||
location: location,
|
||||
method: 'rescore_problem',
|
||||
@@ -115,8 +112,9 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
var rescoreIfHigher = function(locname, location) {
|
||||
var rescoreIfHigher = function(courseId, locname, location) {
|
||||
this.doInstructorDashAction({
|
||||
courseId: courseId,
|
||||
locationName: locname,
|
||||
location: location,
|
||||
method: 'rescore_problem',
|
||||
@@ -126,8 +124,9 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
var overrideScore = function(locname, location) {
|
||||
var overrideScore = function(courseId, locname, location) {
|
||||
this.doInstructorDashAction({
|
||||
courseId: courseId,
|
||||
locationName: locname,
|
||||
location: location,
|
||||
method: 'override_problem_score',
|
||||
@@ -137,10 +136,6 @@ var StaffDebug = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
getCurrentUrl = function() {
|
||||
return window.location.pathname;
|
||||
};
|
||||
|
||||
return {
|
||||
reset: reset,
|
||||
deleteStudentState: deleteStudentState,
|
||||
@@ -150,7 +145,6 @@ var StaffDebug = (function() {
|
||||
|
||||
// export for testing
|
||||
doInstructorDashAction: doInstructorDashAction,
|
||||
getCurrentUrl: getCurrentUrl,
|
||||
getURL: getURL,
|
||||
getUser: getUser,
|
||||
getScore: getScore,
|
||||
@@ -160,26 +154,47 @@ var StaffDebug = (function() {
|
||||
|
||||
// Register click handlers
|
||||
$(document).ready(function() {
|
||||
|
||||
var $mainContainer = $('#main');
|
||||
$mainContainer.on('click', '.staff-debug-reset', function() {
|
||||
StaffDebug.reset($(this).parent().data('location-name'), $(this).parent().data('location'));
|
||||
StaffDebug.reset(
|
||||
$(this).parent().data('course-id'),
|
||||
$(this).parent().data('location-name'),
|
||||
$(this).parent().data('location')
|
||||
);
|
||||
return false;
|
||||
});
|
||||
$mainContainer.on('click', '.staff-debug-sdelete', function() {
|
||||
StaffDebug.deleteStudentState($(this).parent().data('location-name'), $(this).parent().data('location'));
|
||||
StaffDebug.deleteStudentState(
|
||||
$(this).parent().data('course-id'),
|
||||
$(this).parent().data('location-name'),
|
||||
$(this).parent().data('location')
|
||||
);
|
||||
return false;
|
||||
});
|
||||
$mainContainer.on('click', '.staff-debug-rescore', function() {
|
||||
StaffDebug.rescore($(this).parent().data('location-name'), $(this).parent().data('location'));
|
||||
StaffDebug.rescore(
|
||||
$(this).parent().data('course-id'),
|
||||
$(this).parent().data('location-name'),
|
||||
$(this).parent().data('location')
|
||||
);
|
||||
return false;
|
||||
});
|
||||
$mainContainer.on('click', '.staff-debug-rescore-if-higher', function() {
|
||||
StaffDebug.rescoreIfHigher($(this).parent().data('location-name'), $(this).parent().data('location'));
|
||||
StaffDebug.rescoreIfHigher(
|
||||
$(this).parent().data('course-id'),
|
||||
$(this).parent().data('location-name'),
|
||||
$(this).parent().data('location')
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
$mainContainer.on('click', '.staff-debug-override-score', function() {
|
||||
StaffDebug.overrideScore($(this).parent().data('location-name'), $(this).parent().data('location'));
|
||||
StaffDebug.overrideScore(
|
||||
$(this).parent().data('course-id'),
|
||||
$(this).parent().data('location-name'),
|
||||
$(this).parent().data('location')
|
||||
);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -76,7 +76,7 @@ ${block_content | n, decode.utf8}
|
||||
<label for="sd_fs_${location.block_id}"> / ${max_problem_score}</label>
|
||||
</div>
|
||||
% endif
|
||||
<div data-location="${location}" data-location-name="${location.block_id}">
|
||||
<div data-location="${location}" data-location-name="${location.block_id}" data-course-id="${location.course_key}">
|
||||
[
|
||||
% if can_reset_attempts:
|
||||
<button type="button" class="btn-link staff-debug-reset">${_('Reset Learner\'s Attempts to Zero')}</button>
|
||||
|
||||
Reference in New Issue
Block a user