MDL-76146 gradereport_grader: Deprecate AJAX grading interface.

Its not stable and not consistent.
This commit is contained in:
Ilya Tregubov
2023-02-17 11:34:08 +08:00
parent a335d50daa
commit 67f2669510
14 changed files with 169 additions and 1570 deletions
-140
View File
@@ -1,140 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file receives ajax callbacks for the grader report
*
* @package gradereport_grader
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->libdir.'/gradelib.php';
require_once $CFG->dirroot.'/grade/lib.php';
// require_once $CFG->dirroot.'/grade/report/grader/ajaxlib.php';
// require_once $CFG->dirroot.'/grade/report/grader/lib.php';
$courseid = required_param('id', PARAM_INT); // course id
$userid = optional_param('userid', false, PARAM_INT);
$itemid = optional_param('itemid', false, PARAM_INT);
$type = optional_param('type', false, PARAM_ALPHA);
$action = optional_param('action', false, PARAM_ALPHA);
$newvalue = optional_param('newvalue', false, PARAM_TEXT);
/// basic access checks
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
$context = context_course::instance($course->id);
require_login($course);
switch ($action) {
case 'update':
if (!confirm_sesskey()) {
break;
}
require_capability('moodle/grade:edit', $context);
if (!empty($userid) && !empty($itemid) && $newvalue !== false && !empty($type)) {
// Save the grade
if (!$grade_item = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$courseid))) { // we must verify course id here!
throw new \moodle_exception('invalidgradeitemid');
}
/**
* Code copied from grade/report/grader/lib.php line 187+
*/
$warnings = array();
$finalvalue = null;
$finalgrade = null;
$json_object = new stdClass();
// Pre-process grade
if ($type == 'value' || $type == 'scale') {
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if ($newvalue == -1) { // -1 means no grade
$finalgrade = null;
} else {
$finalgrade = $newvalue;
}
} else {
$finalgrade = unformat_float($newvalue);
}
$errorstr = '';
// Warn if the grade is out of bounds.
if (is_null($finalgrade)) {
// ok
} else {
$bounded = $grade_item->bounded_grade($finalgrade);
if ($bounded > $finalgrade) {
$errorstr = 'lessthanmin';
} else if ($bounded < $finalgrade) {
$errorstr = 'morethanmax';
}
}
if ($errorstr) {
$userfieldsapi = \core_user\fields::for_name();
$user = $DB->get_record('user', array('id' => $userid), 'id' . $userfieldsapi->get_sql()->selects);
$gradestr = new stdClass();
$gradestr->username = fullname($user);
$gradestr->itemname = $grade_item->get_name();
$json_object->message = get_string($errorstr, 'grades', $gradestr);
$json_object->result = "error";
}
$finalvalue = $finalgrade;
}
if (!empty($json_object->result) && $json_object->result == 'error') {
echo json_encode($json_object);
die();
} else {
$json_object->gradevalue = $finalvalue;
if ($grade_item->update_final_grade($userid, $finalgrade, 'gradebook', false, FORMAT_MOODLE)) {
$json_object->result = 'success';
$json_object->message = false;
} else {
$json_object->result = 'error';
$json_object->message = "TO BE LOCALISED: Failure to update final grade!";
echo json_encode($json_object);
die();
}
// Get row data
$sql = "SELECT gg.id, gi.id AS itemid, gi.scaleid AS scale, gg.userid AS userid, finalgrade, gg.overridden AS overridden "
. "FROM {grade_grades} gg, {grade_items} gi WHERE "
. "gi.courseid = ? AND gg.itemid = gi.id AND gg.userid = ?";
$records = $DB->get_records_sql($sql, array($courseid, $userid));
$json_object->row = $records;
echo json_encode($json_object);
die();
}
} else {
$json_object = new stdClass();
$json_object->result = "error";
$json_object->message = "Missing parameter to ajax UPDATE callback: \n" .
" userid: $userid,\n itemid: $itemid\n, type: $type\n, newvalue: $newvalue";
echo json_encode($json_object);
}
break;
}
@@ -72,7 +72,6 @@ class provider implements
$items->add_user_preference('grade_report_studentsperpage', 'privacy:metadata:preference:grade_report_studentsperpage');
$items->add_user_preference('grade_report_showonlyactiveenrol', 'privacy:metadata:preference:grade_report_showonlyactiveenrol');
$items->add_user_preference('grade_report_aggregationposition', 'privacy:metadata:preference:grade_report_aggregationposition');
$items->add_user_preference('grade_report_enableajax', 'privacy:metadata:preference:grade_report_enableajax');
// There is also one user preference which can be defined on each course.
$items->add_user_preference('grade_report_grader_collapsed_categories', 'privacy:metadata:preference:grade_report_grader_collapsed_categories');
@@ -103,10 +102,6 @@ class provider implements
case 'grade_report_shownumberofgrades':
case 'grade_report_quickgrading':
case 'grade_report_showonlyactiveenrol':
case 'grade_report_enableajax':
$prefname = $name;
$transformedvalue = transform::yesno($value);
break;
case 'grade_report_meanselection':
$prefname = $name;
switch ($value) {
@@ -1,2 +1,8 @@
privacy:metadata:preference:grade_report_showquickfeedback,gradereport_grader
useractivityfeedback,gradereport_grader
privacy:metadata:preference:grade_report_enableajax,gradereport_grader
ajaxclicktoclose,gradereport_grader
ajaxerror,gradereport_grader
ajaxfailedupdate,gradereport_grader
ajaxfieldchanged,gradereport_grader
ajaxchoosescale,gradereport_grader
@@ -23,11 +23,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['ajaxclicktoclose'] = 'Click this box to remove it';
$string['ajaxerror'] = 'Error';
$string['ajaxfailedupdate'] = 'Unable to update [1] for [2]';
$string['ajaxfieldchanged'] = 'The field you are currently editing has changed, would you like to use the updated value?';
$string['ajaxchoosescale'] = 'Choose';
$string['eventgradereportviewed'] = 'Grader report viewed';
$string['grader:manage'] = 'Manage the grader report';
$string['grader:view'] = 'View grader report';
@@ -36,7 +31,6 @@ $string['preferences'] = 'Grader report preferences';
$string['privacy:metadata:preference:grade_report_aggregationposition'] = 'Whether the category and course total columns are displayed first or last in the gradebook reports';
$string['privacy:metadata:preference:grade_report_averagesdecimalpoints'] = 'The number of decimal places to display for each average or whether the overall decimal places setting for the category or grade item is used (inherit).';
$string['privacy:metadata:preference:grade_report_averagesdisplaytype'] = 'Whether the average (mean) is displayed as real grades, percentages or letters, or whether the display type for the category or grade item is used (inherit).';
$string['privacy:metadata:preference:grade_report_enableajax'] = 'Whether to add a layer of AJAX functionality to the grader report, simplifying and speeding up common operations';
$string['privacy:metadata:preference:grade_report_grader_collapsed_categories'] = 'List of gradebook categories to be collapsed';
$string['privacy:metadata:preference:grade_report_meanselection'] = 'Whether cells with no grade should be included when calculating the average (mean) for each category or grade item';
$string['privacy:metadata:preference:grade_report_quickgrading'] = 'Whether to display a text input box for each grade, allowing many grades to be edited at the same time';
@@ -60,4 +54,10 @@ $string['overriddengrade'] = 'Overridden grade';
// Deprecated since Moodle 4.2.
$string['privacy:metadata:preference:grade_report_showquickfeedback'] = 'Whether to display a feedback text input box with a dotted border for each grade, allowing the feedback for many grades to be edited at the same time';
$string['privacy:metadata:preference:grade_report_enableajax'] = 'Whether to add a layer of AJAX functionality to the grader report, simplifying and speeding up common operations';
$string['useractivityfeedback'] = '{$a} feedback';
$string['ajaxclicktoclose'] = 'Click this box to remove it';
$string['ajaxerror'] = 'Error';
$string['ajaxfailedupdate'] = 'Unable to update [1] for [2]';
$string['ajaxfieldchanged'] = 'The field you are currently editing has changed, would you like to use the updated value?';
$string['ajaxchoosescale'] = 'Choose';
+3 -63
View File
@@ -772,18 +772,9 @@ class grade_report_grader extends grade_report {
$strgrade = $this->get_lang_string('gradenoun');
$arrows = $this->get_sort_arrows();
$jsarguments = array(
'cfg' => array('ajaxenabled'=>false),
'items' => array(),
'users' => array(),
'grades' => array()
);
$jsscales = array();
// Get preferences once.
$showactivityicons = $this->get_pref('showactivityicons');
$quickgrading = $this->get_pref('quickgrading');
$enableajax = $this->get_pref('enableajax');
$showanalysisicon = $this->get_pref('showanalysisicon');
// Get strings which are re-used inside the loop.
@@ -912,9 +903,6 @@ class grade_report_grader extends grade_report {
$scale = null;
if (!empty($item->scaleid)) {
$scaleslist[] = $item->scaleid;
$jsarguments['items'][$itemid] = array('id'=>$itemid, 'name'=>$item->get_name(true), 'type'=>'scale', 'scale'=>$item->scaleid, 'decimals'=>$item->get_decimals());
} else {
$jsarguments['items'][$itemid] = array('id'=>$itemid, 'name'=>$item->get_name(true), 'type'=>'value', 'scale'=>false, 'decimals'=>$item->get_decimals());
}
$tabindices[$item->id]['grade'] = $gradetabindex;
$gradetabindex += $numusers * 2;
@@ -924,7 +912,6 @@ class grade_report_grader extends grade_report {
if (!empty($scaleslist)) {
$scalesarray = $DB->get_records_list('scale', 'id', $scaleslist);
}
$jsscales = $scalesarray;
// Get all the grade items if the user can not view hidden grade items.
// It is possible that the user is simply viewing the 'Course total' by switching to the 'Aggregates only' view
@@ -952,7 +939,6 @@ class grade_report_grader extends grade_report {
$itemrow->id = 'user_'.$userid;
$fullname = fullname($user, $viewfullnames);
$jsarguments['users'][$userid] = $fullname;
foreach ($this->gtree->items as $itemid => $unused) {
$item =& $this->gtree->items[$itemid];
@@ -973,15 +959,6 @@ class grade_report_grader extends grade_report {
} else {
$gradeval = $grade->finalgrade;
}
if (!empty($grade->finalgrade)) {
$gradevalforjs = null;
if ($item->scaleid && !empty($scalesarray[$item->scaleid])) {
$gradevalforjs = (int)$gradeval;
} else {
$gradevalforjs = format_float($gradeval, $decimalpoints);
}
$jsarguments['grades'][] = array('user'=>$userid, 'item'=>$itemid, 'grade'=>$gradevalforjs);
}
// MDL-11274
// Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden'
@@ -1123,14 +1100,6 @@ class grade_report_grader extends grade_report {
$itemcell->attributes['class'] .= ' grade_type_text';
}
// Only allow edting if the grade is editable (not locked, not in a unoverridable category, etc).
if ($enableajax && $grade->is_editable()) {
// If a grade item is type text, it can't be edited.
if ($item->gradetype != GRADE_TYPE_TEXT) {
$itemcell->attributes['class'] .= ' clickable';
}
}
if ($item->needsupdate) {
$itemcell->text .= $gradepassicon . "<span class='gradingerror{$hidden}{$gradepass}'>" . $error . "</span>";
} else {
@@ -1148,14 +1117,6 @@ class grade_report_grader extends grade_report {
}
}
// Enable keyboard navigation if the grade is editable (not locked, not in a unoverridable category, etc).
if ($enableajax && $grade->is_editable()) {
// If a grade item is type text, it can't be edited.
if ($item->gradetype != GRADE_TYPE_TEXT) {
$itemcell->attributes['class'] .= ' gbnavigable';
}
}
if (!empty($this->gradeserror[$item->id][$userid])) {
$itemcell->text .= $this->gradeserror[$item->id][$userid];
}
@@ -1165,30 +1126,9 @@ class grade_report_grader extends grade_report {
$rows[] = $itemrow;
}
if ($enableajax) {
$jsarguments['cfg']['ajaxenabled'] = true;
$jsarguments['cfg']['scales'] = array();
foreach ($jsscales as $scale) {
// Trim the scale values, as they may have a space that is ommitted from values later.
$jsarguments['cfg']['scales'][$scale->id] = array_map('trim', explode(',', $scale->scale));
}
// Student grades are already at $jsarguments['grades']
}
$jsarguments['cfg']['isediting'] = !empty($USER->editing);
$jsarguments['cfg']['courseid'] = $this->courseid;
$jsarguments['cfg']['studentsperpage'] = $this->get_students_per_page();
$module = array(
'name' => 'gradereport_grader',
'fullpath' => '/grade/report/grader/module.js',
'requires' => array('base', 'dom', 'event', 'event-mouseenter', 'event-key', 'io-queue', 'json-parse', 'overlay')
);
$PAGE->requires->js_init_call('M.gradereport_grader.init_report', $jsarguments, false, $module);
$PAGE->requires->strings_for_js(array('grade'), 'grades');
$PAGE->requires->strings_for_js(array('ajaxchoosescale', 'ajaxclicktoclose', 'ajaxerror', 'ajaxfailedupdate', 'ajaxfieldchanged'), 'gradereport_grader');
if (!$enableajax && !empty($USER->editing)) {
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['gradereport_grader']);
if (!empty($USER->editing)) {
$PAGE->requires->js_call_amd('core_form/changechecker',
'watchFormById', ['gradereport_grader']);
}
$rows = $this->get_right_range_row($rows);
File diff suppressed because it is too large Load Diff
-1
View File
@@ -106,7 +106,6 @@ class grader_report_preferences_form extends moodleform {
$preferences['prefgeneral']['aggregationposition'] = array(GRADE_REPORT_PREFERENCE_DEFAULT => '*default*',
GRADE_REPORT_AGGREGATION_POSITION_FIRST => get_string('positionfirst', 'grades'),
GRADE_REPORT_AGGREGATION_POSITION_LAST => get_string('positionlast', 'grades'));
$preferences['prefgeneral']['enableajax'] = $checkbox_default;
$preferences['prefshow']['showuserimage'] = $checkbox_default;
$preferences['prefshow']['showactivityicons'] = $checkbox_default;
-3
View File
@@ -46,9 +46,6 @@ if ($ADMIN->fulltree) {
array(GRADE_REPORT_MEAN_ALL => get_string('meanall', 'grades'),
GRADE_REPORT_MEAN_GRADED => get_string('meangraded', 'grades'))));
$settings->add(new admin_setting_configcheckbox('grade_report_enableajax', get_string('enableajax', 'grades'),
get_string('enableajax_help', 'grades'), 0));
$settings->add(new admin_setting_configcheckbox('grade_report_showcalculations',
get_string('showcalculations', 'grades'),
get_string('showcalculations_help', 'grades'), 1));
@@ -1,209 +0,0 @@
@gradereport @gradereport_grader @javascript
Feature: Using the AJAX grading feature of Grader report to update grades
In order to use AJAX grading
As a teacher
I need to be able to update and verify grades
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "custom profile fields" exist:
| datatype | shortname | name |
| text | frog | Favourite frog |
And the following "users" exist:
| username | firstname | lastname | email | idnumber | profile_field_frog |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | |
| student1 | Student | 1 | student1@example.com | s1 | litle yellow frog |
| student2 | Student | 2 | student2@example.com | s2 | prince frog |
| student3 | Student | 3 | student3@example.com | s3 | |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
And the following "scales" exist:
| name | scale |
| Test Scale | Disappointing,Good,Very good,Excellent |
And the following "grade categories" exist:
| fullname | course |
| Grade Cat | C1 |
And the following "grade categories" exist:
| fullname | course | gradecategory |
| Grade Sub Cat | C1 | Grade Cat |
And the following "grade items" exist:
| itemname | course | locked | gradetype | gradecategory |
| Item 1 | C1 | 0 | value | Grade Cat |
| Item VU | C1 | 0 | value | Grade Cat |
| Item VL | C1 | 1 | value | Grade Cat |
| Item TU | C1 | 0 | text | Grade Cat |
| Item TL | C1 | 1 | text | Grade Cat |
| Item 3 | C1 | 0 | value | Grade Cat |
| Calc Item | C1 | 0 | value | Grade Cat |
| Item VUSub | C1 | 0 | value | Grade Sub Cat |
And the following "grade items" exist:
| itemname | course | locked | gradetype | scale | gradecategory |
| Item SU | C1 | 0 | scale | Test Scale | Grade Cat |
| Item SL | C1 | 1 | scale | Test Scale | Grade Cat |
And the following config values are set as admin:
| grade_report_showaverages | 0 |
| grade_report_enableajax | 1 |
Scenario: Use the grader report without editing, with AJAX on
When the following config values are set as admin:
| grade_overridecat | 1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I change window size to "large"
And I click on student "Student 2" for grade item "Item VU"
Then I should see a grade field for "Student 2" and grade item "Item VU"
And I set the field "ajaxgrade" to "33"
And I press the enter key
And I should not see a grade field for "Student 2" and grade item "Item VU"
And I click on student "Student 3" for grade item "Item SU"
And I set the field "ajaxgrade" to "Very good"
And I press the shift tab key
And I press the tab key
And I press the shift tab key
And I click on student "Student 3" for grade item "Item VU"
And I set the field "ajaxgrade" to "50"
And I press the enter key
And I click on student "Student 3" for grade item "Item 1"
And I set the field "ajaxgrade" to "80"
And I press the enter key
And the following should exist in the "user-grades" table:
| -1- | -6- | -7- | -13- | -16- |
| Student 2 | - | 33.00 | - | 33.00 |
| Student 3 | 80.00 | 50.00 | Very good | 133.00 |
And I click on student "Student 3" for grade item "Item VL"
And I should not see a grade field for "Student 3" and grade item "Item VL"
And I click on student "Student 3" for grade item "Item SL"
And I should not see a grade field for "Student 3" and grade item "Item SL"
And I click on student "Student 3" for grade item "Item TU"
And I should not see a grade field for "Student 3" and grade item "Item TU"
And I click on student "Student 1" for grade item "Course total"
And I should see a grade field for "Student 1" and grade item "Course total"
And I set the field "ajaxgrade" to "90"
And I press the enter key
And the following should exist in the "user-grades" table:
| -1- | -16- |
| Student 1 | 90.00 |
And I navigate to "View > Grader report" in the course gradebook
And the following should exist in the "user-grades" table:
| -1- | -6- | -7- | -13- | -16- |
| Student 1 | - | - | - | 90.00 |
| Student 2 | - | 33.00 | - | 33.00 |
| Student 3 | 80.00 | 50.00 | Very good | 133.00 |
Scenario: Use the grader report without editing, with AJAX without category override
When the following config values are set as admin:
| grade_overridecat | 0 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I change window size to "large"
And I click on student "Student 2" for grade item "Item VU"
Then I should see a grade field for "Student 2" and grade item "Item VU"
And I set the field "ajaxgrade" to "33"
And I press the enter key
And I click on student "Student 2" for grade item "Course total"
And I should not see a grade field for "Student 3" and grade item "Course total"
And the following should exist in the "user-grades" table:
| -1- | -7- | -16- |
| Student 2 | 33.00 | 33.00 |
Scenario: Use the grader report with editing, with AJAX with category override
When the following config values are set as admin:
| grade_overridecat | 1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I turn editing mode on
Then I should not see a grade field for "Student 2" and grade item "Item VL"
And I should not see a grade field for "Student 2" and grade item "Item TU"
And I should see a grade field for "Student 2" and grade item "Course total"
And I give the grade "20.00" to the user "Student 2" for the grade item "Item VU"
And I click away from student "Student 2" and grade item "Item VU" value
And I give the grade "30.00" to the user "Student 2" for the grade item "Item 1"
And I give the grade "Very good" to the user "Student 2" for the grade item "Item SU"
And I click away from student "Student 2" and grade item "Item SU" value
And the grade for "Student 2" in grade item "Grade Cat" should match "53.00"
And the grade for "Student 2" in grade item "Course total" should match "53.00"
And I turn editing mode off
And the following should exist in the "user-grades" table:
| -1- | -6- | -7- | -13- | -15- | -16- |
| Student 2 | 30.00 | 20.00 | Very good | 53.00 | 53.00 |
And I click on student "Student 2" for grade item "Item 1"
Scenario: Use the grader report with editing, with AJAX without category override
When the following config values are set as admin:
| grade_overridecat | 0 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I turn editing mode on
And I change window size to "large"
And I set "=[[i1]] + [[i3]] + [[gsc]]" calculation for grade item "Calc Item" with idnumbers:
| Item 1 | i1 |
| Item 3 | i3 |
| Grade Sub Cat | gsc |
Then I should not see a grade field for "Student 2" and grade item "Course total"
And I give the grade "20.00" to the user "Student 2" for the grade item "Item VU"
And I click away from student "Student 2" and grade item "Item VU" value
And the following should exist in the "user-grades" table:
| -1- | -15- | -16- |
| Student 2 | 20.00 | 20.00 |
And I give the grade "30.00" to the user "Student 2" for the grade item "Item 1"
And I click away from student "Student 2" and grade item "Item 1" value
And the following should exist in the "user-grades" table:
| -1- | -15- | -16- |
| Student 2 | 80.00 | 80.00 |
And the field "Student 2 Calc Item grade" matches value "30.00"
And I give the grade "5.00" to the user "Student 2" for the grade item "Item 3"
And I click away from student "Student 2" and grade item "Item 3" value
And the following should exist in the "user-grades" table:
| -1- | -15- | -16- |
| Student 2 | 90.00 | 90.00 |
And the field "Student 2 Calc Item grade" matches value "35.00"
And I give the grade "10.00" to the user "Student 2" for the grade item "Item VUSub"
And I click away from student "Student 2" and grade item "Item VUSub" value
And the following should exist in the "user-grades" table:
| -1- | -5- | -15- | -16- |
| Student 2 | 10.00 | 110.00 | 110.00 |
And the field "Student 2 Calc Item grade" matches value "45.00"
And I turn editing mode off
And the following should exist in the "user-grades" table:
| -1- | -4- | -6- | -7- | -11- | -12- | -15- | -16- |
| Student 2 | 10.00 | 30.00 | 20.00 | 5.00 | 45.00 | 110.00 | 110.00 |
And I click on student "Student 2" for grade item "Item 1"
Scenario: Teacher can see an error when an incorrect grade is given using the grader report with editing and AJAX on
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I turn editing mode on
And I give the grade "66.00" to the user "Student 2" for the grade item "Item VU"
And I click away from student "Student 2" and grade item "Item VU" value
When I give the grade "999.00" to the user "Student 2" for the grade item "Item VU"
And I click away from student "Student 2" and grade item "Item VU" value
Then I should see "The grade entered for Item VU for Student 2 is more than the maximum allowed"
And I click on "The grade entered for Item VU for Student 2 is more than the maximum allowed" "text"
And I should not see "The grade entered for Item VU for Student 2 is more than the maximum allowed"
And the grade for "Student 2" in grade item "Item VU" should match "66.00"
Scenario: Teacher can see user custom filed columns as additional user identity
Given the following config values are set as admin:
| showuseridentity | email,profile_field_frog |
And I log in as "teacher1"
And I am on "Course 1" course homepage
When I navigate to "View > Grader report" in the course gradebook
Then I should see "litle yellow frog" in the "student1" "table_row"
And I should see "prince frog" in the "student2" "table_row"
# Sort by the custom profile field.
And I click on "Favourite frog" "link" in the "gradereport-grader-table" "table"
And "student1" "table_row" should appear before "student2" "table_row"
# Now sort by descending.
And I click on "Favourite frog" "link" in the "gradereport-grader-table" "table"
And "student2" "table_row" should appear before "student1" "table_row"
@@ -37,100 +37,6 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_gradereport_grader extends behat_base {
/**
* Click a given user grade cell.
*
* @Given /^I click on student "([^"]*)" for grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_click_on_student_and_grade_item($student, $itemname) {
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
/**
* Remove focus for a grade value cell.
*
* @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" value$/
* @param string $student
* @param string $itemname
*/
public function i_click_away_from_student_and_grade_value($student, $itemname) {
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::i_take_focus_off_field', array($this->escape($xpath), 'xpath_element'));
}
/**
* Checks grade values with or without a edit box.
*
* @Then /^the grade for "([^"]*)" in grade item "([^"]*)" should match "([^"]*)"$/
* @throws Exception
* @throws ElementNotFoundException
* @param string $student
* @param string $itemname
* @param string $value
*/
public function the_grade_should_match($student, $itemname, $value) {
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$gradefield = $this->getSession()->getPage()->find('xpath', $xpath);
if (!empty($gradefield)) {
// Get the field.
$fieldtype = behat_field_manager::guess_field_type($gradefield, $this->getSession());
if (!$fieldtype) {
throw new Exception('Could not get field type for grade field "' . $itemname . '"');
}
$field = behat_field_manager::get_field_instance($fieldtype, $gradefield, $this->getSession());
if (!$field->matches($value)) {
$fieldvalue = $field->get_value();
throw new ExpectationException(
'The "' . $student . '" and "' . $itemname . '" grade is "' . $fieldvalue . '", "' . $value . '" expected' ,
$this->getSession()
);
}
} else {
// If there isn't a form field, just search for contents.
$valueliteral = behat_context_helper::escape($value);
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$xpath .= "[contains(normalize-space(.)," . $valueliteral . ")]";
$node = $this->getSession()->getDriver()->find($xpath);
if (empty($node)) {
$locatorexceptionmsg = 'Cell for "' . $student . '" and "' . $itemname . '" with value "' . $value . '"';
throw new ElementNotFoundException($this->getSession(), $locatorexceptionmsg, null, $xpath);
}
}
}
/**
* Look for a grade editing field.
*
* @Then /^I should see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_see_grade_field($student, $itemname) {
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_be_visible', array($this->escape($xpath), 'xpath_element'));
}
/**
* Look for a lack of the grade editing field.
*
* @Then /^I should not see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_not_see_grade_field($student, $itemname) {
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_not_exist', array($this->escape($xpath), 'xpath_element'));
}
/**
* Gets the user id from its name.
@@ -157,6 +63,7 @@ class behat_gradereport_grader extends behat_base {
* @return int
*/
protected function get_grade_item_id($itemname) {
global $DB;
if ($id = $DB->get_field('grade_items', 'id', array('itemname' => $itemname))) {
@@ -181,30 +88,4 @@ class behat_gradereport_grader extends behat_base {
throw new Exception('The specified grade_item with name "' . $itemname . '" does not exist');
}
/**
* Gets unique xpath selector for a student/grade item combo.
*
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_cell_selector($student, $itemname) {
$itemid = 'u' . $this->get_user_id($student) . 'i' . $this->get_grade_item_id($itemname);
return "//table[@id='user-grades']//td[@id='" . $itemid . "']";
}
/**
* Gets xpath for a particular student/grade item grade value cell.
*
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_value_selector($student, $itemname) {
$cell = $this->get_student_and_grade_cell_selector($student, $itemname);
return $cell . "//*[contains(@id, 'grade_') or @name='ajaxgrade']";
}
}
@@ -99,4 +99,152 @@ class behat_gradereport_grader_deprecated extends behat_deprecated_base {
return $cell . "//input[contains(@id, 'feedback_') or @name='ajaxfeedback']";
}
/**
* Click a given user grade cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Given /^I click on student "([^"]*)" for grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_click_on_student_and_grade_item($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_click_on_student_and_grade_item']);
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
}
/**
* Remove focus for a grade value cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Given /^I click away from student "([^"]*)" and grade item "([^"]*)" value$/
* @param string $student
* @param string $itemname
*/
public function i_click_away_from_student_and_grade_value($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_click_away_from_student_and_grade_value']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::i_take_focus_off_field', array($this->escape($xpath), 'xpath_element'));
}
/**
* Checks grade values with or without a edit box.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^the grade for "([^"]*)" in grade item "([^"]*)" should match "([^"]*)"$/
* @throws Exception
* @throws ElementNotFoundException
* @param string $student
* @param string $itemname
* @param string $value
*/
public function the_grade_should_match($student, $itemname, $value) {
$this->deprecated_message(['behat_gradereport_grader::the_grade_should_match']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$gradefield = $this->getSession()->getPage()->find('xpath', $xpath);
if (!empty($gradefield)) {
// Get the field.
$fieldtype = behat_field_manager::guess_field_type($gradefield, $this->getSession());
if (!$fieldtype) {
throw new Exception('Could not get field type for grade field "' . $itemname . '"');
}
$field = behat_field_manager::get_field_instance($fieldtype, $gradefield, $this->getSession());
if (!$field->matches($value)) {
$fieldvalue = $field->get_value();
throw new ExpectationException(
'The "' . $student . '" and "' . $itemname . '" grade is "' . $fieldvalue . '", "' . $value . '" expected' ,
$this->getSession()
);
}
} else {
// If there isn't a form field, just search for contents.
$valueliteral = behat_context_helper::escape($value);
$xpath = $this->get_student_and_grade_cell_selector($student, $itemname);
$xpath .= "[contains(normalize-space(.)," . $valueliteral . ")]";
$node = $this->getSession()->getDriver()->find($xpath);
if (empty($node)) {
$locatorexceptionmsg = 'Cell for "' . $student . '" and "' . $itemname . '" with value "' . $value . '"';
throw new ElementNotFoundException($this->getSession(), $locatorexceptionmsg, null, $xpath);
}
}
}
/**
* Look for a grade editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_see_grade_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_see_grade_field']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_be_visible', array($this->escape($xpath), 'xpath_element'));
}
/**
* Look for a lack of the grade editing field.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @Then /^I should not see a grade field for "([^"]*)" and grade item "([^"]*)"$/
* @param string $student
* @param string $itemname
*/
public function i_should_not_see_grade_field($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::i_should_not_see_grade_field']);
$xpath = $this->get_student_and_grade_value_selector($student, $itemname);
$this->execute('behat_general::should_not_exist', array($this->escape($xpath), 'xpath_element'));
}
/**
* Gets unique xpath selector for a student/grade item combo.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_cell_selector($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::get_student_and_grade_cell_selector']);
$itemid = 'u' . $this->get_user_id($student) . 'i' . $this->get_grade_item_id($itemname);
return "//table[@id='user-grades']//td[@id='" . $itemid . "']";
}
/**
* Gets xpath for a particular student/grade item grade value cell.
*
* @deprecated since 4.2 - we don't allow ajax edit on grader report anymore.
* @todo MDL-77107 This will be deleted in Moodle 4.6.
* @throws Exception
* @param string $student
* @param string $itemname
* @return string
*/
protected function get_student_and_grade_value_selector($student, $itemname) {
$this->deprecated_message(['behat_gradereport_grader::get_student_and_grade_value_selector']);
$cell = $this->get_student_and_grade_cell_selector($student, $itemname);
return $cell . "//*[contains(@id, 'grade_') or @name='ajaxgrade']";
}
}
+2
View File
@@ -72,3 +72,5 @@ confirmaddadmin,core_role
confirmdeladmin,core_role
showquickfeedback,core_grades
showquickfeedback_help,core_grades
enableajax,core_grades
enableajax_help,core_grades
+2 -2
View File
@@ -176,8 +176,6 @@ $string['editoutcomes'] = 'Edit outcomes';
$string['editscale'] = 'Edit scale';
$string['edittree'] = 'Setup';
$string['editverbose'] = 'Edit {$a->category} {$a->itemmodule} {$a->itemname}';
$string['enableajax'] = 'Enable AJAX';
$string['enableajax_help'] = 'Adds a layer of AJAX functionality to the grader report, simplifying and speeding up common operations. Depends on Javascript being switched on at the user\'s browser level.';
$string['enableoutcomes'] = 'Enable outcomes';
$string['enableoutcomes_help'] = 'If enabled, grade items may be graded using one or more scales tied to outcome statements.';
$string['encoding'] = 'Encoding';
@@ -914,3 +912,5 @@ $string['showquickfeedback'] = 'Show quick feedback';
$string['showquickfeedback_help'] = 'If enabled, when editing is turned on, a feedback text input box with a dotted border appears for each grade, allowing the feedback for many grades to be edited at the same time. Changes are saved and highlighted when the update button is clicked.
Note that when feedback is edited in the grader report, an overridden flag is set, meaning that the feedback can no longer be changed from within the related activity.';
$string['enableajax'] = 'Enable AJAX';
$string['enableajax_help'] = 'Adds a layer of AJAX functionality to the grader report, simplifying and speeding up common operations. Depends on Javascript being switched on at the user\'s browser level.';
+1
View File
@@ -3,6 +3,7 @@ information provided here is intended especially for developers.
=== 4.2 ===
* 'Enable AJAX' interface has been deprecated for grader report
* 'Quick feedback' interface has been deprecated for grader report
* \single_button constructor signature has been changed to manage more types than just primary buttons.
The boolean "primary" parameter has been deprecated and replaced by a more generic type allowing to use