mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 12:32:08 +02:00
Merge branch 'MDL-79546' of https://github.com/timhunt/moodle
This commit is contained in:
commit
87ec51598d
7
.upgradenotes/MDL-79546-2024061414230136.yml
Normal file
7
.upgradenotes/MDL-79546-2024061414230136.yml
Normal file
@ -0,0 +1,7 @@
|
||||
issueNumber: MDL-79546
|
||||
notes:
|
||||
quiz:
|
||||
- message: >-
|
||||
The functions quiz_overview_report::regrade_attempts and regrade_batch_of_attempts now
|
||||
have a new optional parameter $slots to only regrade some slots in each attempt (default all).
|
||||
type: improved
|
10
mod/quiz/report/overview/amd/build/regrade_modal.min.js
vendored
Normal file
10
mod/quiz/report/overview/amd/build/regrade_modal.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
define("quiz_overview/regrade_modal",["exports","core/modal","core/templates","core/str","core/notification"],(function(_exports,_modal,_templates,_str,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
|
||||
/**
|
||||
* Regrade modal form is used to regrade or dryrun the attempts and questions.
|
||||
*
|
||||
* @module quiz_overview/regrade_modal
|
||||
* @copyright 2024 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal=_interopRequireDefault(_modal),_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification);const SELECTORS_allQuestionsButton="#regradeallquestions",SELECTORS_dryRunButton="#dryrunbutton",SELECTORS_mainTableForm="#attemptsform",SELECTORS_questionCheckbox='[id^="regradeslot"]',SELECTORS_regradeAttemptsButtonId="regradeattempts",SELECTORS_regradeButton="#regradebutton",SELECTORS_reportTableSelectedAttempts='[id^="attemptid_"]:checked',showModal=async e=>{e.preventDefault();try{let hiddenInputs=[];document.querySelectorAll(SELECTORS_mainTableForm+" input[type=hidden]").forEach((hiddenInput=>{hiddenInputs.push({name:hiddenInput.name,value:hiddenInput.value})})),document.querySelectorAll(SELECTORS_reportTableSelectedAttempts).forEach((selectedAttempt=>{hiddenInputs.push({name:selectedAttempt.name,value:selectedAttempt.value})}));const modal=await _modal.default.create({title:(0,_str.getString)("regrade","quiz_overview"),body:_templates.default.render("quiz_overview/regrade_modal_body",{actionurl:document.querySelector(SELECTORS_mainTableForm).action,hasselectedattempts:null!==document.querySelector(SELECTORS_reportTableSelectedAttempts),questions:JSON.parse(document.getElementById(SELECTORS_regradeAttemptsButtonId).dataset.slots),hiddeninputs:hiddenInputs}),isVerticallyCentered:!0,removeOnClose:!0,show:!0});modal.getRoot()[0].addEventListener("change",updateButtonStates),modal.getBodyPromise().then(updateButtonStates).catch(_notification.default.exception),modal.getTitlePromise().then((title=>(title.append(" "+document.getElementById(SELECTORS_regradeAttemptsButtonId).dataset.helpIcon),title[0].querySelector("a").classList.add("align-baseline"),title[0]))).catch(_notification.default.exception)}catch(ex){await _notification.default.exception(ex)}},updateButtonStates=()=>{const allQuestionsButton=document.querySelector(SELECTORS_allQuestionsButton);document.querySelectorAll(SELECTORS_questionCheckbox).forEach((questionCheckbox=>{questionCheckbox.disabled=allQuestionsButton.checked}));const isAnyQuestionSelected=null!==document.querySelector(SELECTORS_questionCheckbox+":checked"),canSubmit=allQuestionsButton.checked||isAnyQuestionSelected;document.querySelector(SELECTORS_regradeButton).disabled=!canSubmit,document.querySelector(SELECTORS_dryRunButton).disabled=!canSubmit};_exports.init=()=>{const regradeButton=document.getElementById(SELECTORS_regradeAttemptsButtonId);regradeButton&®radeButton.addEventListener("click",showModal)}}));
|
||||
|
||||
//# sourceMappingURL=regrade_modal.min.js.map
|
File diff suppressed because one or more lines are too long
113
mod/quiz/report/overview/amd/src/regrade_modal.js
Normal file
113
mod/quiz/report/overview/amd/src/regrade_modal.js
Normal file
@ -0,0 +1,113 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Regrade modal form is used to regrade or dryrun the attempts and questions.
|
||||
*
|
||||
* @module quiz_overview/regrade_modal
|
||||
* @copyright 2024 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import Modal from 'core/modal';
|
||||
import Templates from 'core/templates';
|
||||
import {getString} from 'core/str';
|
||||
import Notification from 'core/notification';
|
||||
|
||||
/**
|
||||
* @type {Object} selectors used in this code.
|
||||
*/
|
||||
const SELECTORS = {
|
||||
'allQuestionsButton': '#regradeallquestions',
|
||||
'dryRunButton': '#dryrunbutton',
|
||||
'mainTableForm': '#attemptsform',
|
||||
'questionCheckbox': '[id^="regradeslot"]',
|
||||
'regradeAttemptsButtonId': 'regradeattempts',
|
||||
'regradeButton': '#regradebutton',
|
||||
'reportTableSelectedAttempts': '[id^="attemptid_"]:checked',
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the regrade modal.
|
||||
*
|
||||
* @param {Event} e click event that opened the modal.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const showModal = async(e) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
let hiddenInputs = [];
|
||||
document.querySelectorAll(SELECTORS.mainTableForm + ' input[type=hidden]').forEach((hiddenInput) => {
|
||||
hiddenInputs.push({'name': hiddenInput.name, 'value': hiddenInput.value});
|
||||
});
|
||||
document.querySelectorAll(SELECTORS.reportTableSelectedAttempts).forEach((selectedAttempt) => {
|
||||
hiddenInputs.push({'name': selectedAttempt.name, 'value': selectedAttempt.value});
|
||||
});
|
||||
const modal = await Modal.create({
|
||||
title: getString('regrade', 'quiz_overview'),
|
||||
body: Templates.render('quiz_overview/regrade_modal_body', {
|
||||
'actionurl': document.querySelector(SELECTORS.mainTableForm).action,
|
||||
'hasselectedattempts': document.querySelector(SELECTORS.reportTableSelectedAttempts) !== null,
|
||||
'questions': JSON.parse(document.getElementById(SELECTORS.regradeAttemptsButtonId).dataset.slots),
|
||||
'hiddeninputs': hiddenInputs,
|
||||
}),
|
||||
isVerticallyCentered: true,
|
||||
removeOnClose: true,
|
||||
show: true,
|
||||
});
|
||||
modal.getRoot()[0].addEventListener('change', updateButtonStates);
|
||||
modal.getBodyPromise().then(updateButtonStates).catch(Notification.exception);
|
||||
|
||||
// TODO MDL-82204 - there is not currently a good way to add a help icon to a modal overall, so we do it this way.
|
||||
modal.getTitlePromise().then((title) => {
|
||||
title.append(' ' + document.getElementById(SELECTORS.regradeAttemptsButtonId).dataset.helpIcon);
|
||||
// The next line is necessary to get a nice layout of the help icon.
|
||||
title[0].querySelector('a').classList.add('align-baseline');
|
||||
return title[0];
|
||||
}).catch(Notification.exception);
|
||||
} catch (ex) {
|
||||
await Notification.exception(ex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables and disables controls when the selected options are changed.
|
||||
*/
|
||||
const updateButtonStates = () => {
|
||||
const allQuestionsButton = document.querySelector(SELECTORS.allQuestionsButton);
|
||||
|
||||
// Question checkboxes enabled only if Selected questions is checked.
|
||||
document.querySelectorAll(SELECTORS.questionCheckbox).forEach((questionCheckbox) => {
|
||||
questionCheckbox.disabled = allQuestionsButton.checked;
|
||||
});
|
||||
|
||||
// State of submit buttons.
|
||||
const isAnyQuestionSelected = document.querySelector(SELECTORS.questionCheckbox + ':checked') !== null;
|
||||
const canSubmit = allQuestionsButton.checked || isAnyQuestionSelected;
|
||||
document.querySelector(SELECTORS.regradeButton).disabled = !canSubmit;
|
||||
document.querySelector(SELECTORS.dryRunButton).disabled = !canSubmit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the regrade button to open the modal.
|
||||
*/
|
||||
export const init = () => {
|
||||
const regradeButton = document.getElementById(SELECTORS.regradeAttemptsButtonId);
|
||||
if (!regradeButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
regradeButton.addEventListener('click', showModal);
|
||||
};
|
7
mod/quiz/report/overview/lang/en/deprecated.txt
Normal file
7
mod/quiz/report/overview/lang/en/deprecated.txt
Normal file
@ -0,0 +1,7 @@
|
||||
regradeall,quiz_overview
|
||||
regradealldry,quiz_overview
|
||||
regradealldrydo,quiz_overview
|
||||
regradealldrydogroup,quiz_overview
|
||||
regradealldrygroup,quiz_overview
|
||||
regradeallgroup,quiz_overview
|
||||
regradeselected,quiz_overview
|
@ -57,16 +57,20 @@ $string['privacy:metadata:preference:quiz_overview_slotmarks'] = 'Whether to sho
|
||||
$string['privacy:preference:slotmarks:yes'] = 'Marks are shown alongside the question slot.';
|
||||
$string['privacy:preference:slotmarks:no'] = 'Marks are not shown alongside the question slot.';
|
||||
$string['regrade'] = 'Regrade';
|
||||
$string['regradeall'] = 'Regrade all';
|
||||
$string['regradealldry'] = 'Dry run a full regrade';
|
||||
$string['regradealldrydo'] = 'Regrade attempts marked as needing regrading ({$a})';
|
||||
$string['regradealldrydogroup'] = 'Regrade attempts ({$a->countregradeneeded}) marked as needing regrading in group \'{$a->groupname}\'';
|
||||
$string['regradealldrygroup'] = 'Dry run a full regrade for group \'{$a->groupname}\'';
|
||||
$string['regradeallgroup'] = 'Full regrade for group \'{$a->groupname}\'';
|
||||
$string['regrade_allattempts'] = 'All attempts';
|
||||
$string['regrade_allquestions'] = 'All questions';
|
||||
$string['regrade_attempts'] = 'Regrade attempts...';
|
||||
$string['regrade_commitregrade'] = 'Commit regrade';
|
||||
$string['regrade_dryrun'] = 'Dry run';
|
||||
$string['regrade_help'] = 'Regrading recalculates the automated grading of attempts, using the current version of each question if possible. A dry-run allows you to preview the grade changes without affecting attempts.';
|
||||
$string['regrade_link'] = 'Quiz_grades_report#Re-grading_attempts';
|
||||
$string['regrade_regradeneedednotificationmessage'] = 'The last dry-run of a regrade found that the re-grade would change the marks for {$a->questions} questions in {$a->attempts} attempts.';
|
||||
$string['regrade_regradenow'] = 'Regrade now';
|
||||
$string['regrade_selectedattempts'] = 'Selected attempts';
|
||||
$string['regrade_selectedquestions'] = 'Selected questions';
|
||||
$string['regradecomplete'] = 'Regrade completed';
|
||||
$string['regradedsuccessfullyxofy'] = 'Finished regrading ({$a->done}/{$a->count})';
|
||||
$string['regradeheader'] = 'Regrading';
|
||||
$string['regradeselected'] = 'Regrade selected attempts';
|
||||
$string['regradingattemptissue'] = 'Slot {$a->slot}: {$a->reason}';
|
||||
$string['regradingattemptxofy'] = 'Regrading attempt ({$a->done}/{$a->count})';
|
||||
$string['regradingattemptxofyproblem'] = 'The following questions could not be regraded in attempt {$a->attemptnum} by {$a->name} (id {$a->attemptid})';
|
||||
@ -78,3 +82,12 @@ $string['showinggraded'] = 'Showing only the attempt graded for each user.';
|
||||
$string['showinggradedandungraded'] = 'Showing graded and ungraded attempts for each user. The one attempt for each user that is graded is highlighted. The grading method for this quiz is {$a}.';
|
||||
$string['studentingroup'] = '\'{$a->coursestudent}\' in group \'{$a->groupname}\'';
|
||||
$string['studentingrouplong'] = '\'{$a->coursestudent}\' in this group';
|
||||
|
||||
// Deprecated since Moodle 4.4.
|
||||
$string['regradeall'] = 'Regrade all';
|
||||
$string['regradealldry'] = 'Dry run a full regrade';
|
||||
$string['regradealldrydo'] = 'Regrade attempts marked as needing regrading ({$a})';
|
||||
$string['regradealldrydogroup'] = 'Regrade attempts ({$a->countregradeneeded}) marked as needing regrading in group \'{$a->groupname}\'';
|
||||
$string['regradealldrygroup'] = 'Dry run a full regrade for group \'{$a->groupname}\'';
|
||||
$string['regradeallgroup'] = 'Full regrade for group \'{$a->groupname}\'';
|
||||
$string['regradeselected'] = 'Regrade selected attempts';
|
||||
|
@ -204,20 +204,28 @@ class quiz_overview_table extends attempts_report_table {
|
||||
}
|
||||
|
||||
protected function submit_buttons() {
|
||||
if (has_capability('mod/quiz:regrade', $this->context)) {
|
||||
$regradebuttonparams = [
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-secondary mr-1',
|
||||
'name' => 'regrade',
|
||||
'value' => get_string('regradeselected', 'quiz_overview'),
|
||||
'data-action' => 'toggle',
|
||||
'data-togglegroup' => $this->togglegroup,
|
||||
'data-toggle' => 'action',
|
||||
'disabled' => true
|
||||
];
|
||||
echo html_writer::empty_tag('input', $regradebuttonparams);
|
||||
}
|
||||
global $PAGE, $OUTPUT;
|
||||
parent::submit_buttons();
|
||||
if (has_capability('mod/quiz:regrade', $this->context)) {
|
||||
$questionslots = [];
|
||||
foreach ($this->questions as $slot => $question) {
|
||||
$questionslots[] = [
|
||||
'slot' => $slot,
|
||||
'name' => get_string('questionno', 'question', $question->number),
|
||||
];
|
||||
}
|
||||
echo html_writer::empty_tag('input', [
|
||||
'type' => 'button',
|
||||
'id' => 'regradeattempts',
|
||||
'class' => 'btn btn-secondary mr-1',
|
||||
'name' => 'regradeattempts',
|
||||
'value' => get_string('regrade_attempts', 'quiz_overview'),
|
||||
'data-slots' => json_encode($questionslots),
|
||||
// There is currently not a good way to render a help icon in a template, so put the required HTML here.
|
||||
'data-help-icon' => $OUTPUT->help_icon('regrade', 'quiz_overview'),
|
||||
]);
|
||||
$PAGE->requires->js_call_amd('quiz_overview/regrade_modal', 'init');
|
||||
}
|
||||
}
|
||||
|
||||
public function col_sumgrades($attempt) {
|
||||
|
@ -25,7 +25,6 @@
|
||||
use mod_quiz\local\reports\attempts_report;
|
||||
use mod_quiz\question\bank\qbank_helper;
|
||||
use mod_quiz\quiz_attempt;
|
||||
use mod_quiz\quiz_settings;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -43,7 +42,7 @@ require_once($CFG->dirroot . '/mod/quiz/report/overview/overview_table.php');
|
||||
class quiz_overview_report extends attempts_report {
|
||||
|
||||
public function display($quiz, $cm, $course) {
|
||||
global $DB, $PAGE;
|
||||
global $DB, $PAGE, $OUTPUT;
|
||||
|
||||
list($currentgroup, $studentsjoins, $groupstudentsjoins, $allowedjoins) = $this->init(
|
||||
'overview', 'quiz_overview_settings_form', $quiz, $cm, $course);
|
||||
@ -93,7 +92,7 @@ class quiz_overview_report extends attempts_report {
|
||||
if ($options->attempts == self::ALL_WITH) {
|
||||
// This option is only available to users who can access all groups in
|
||||
// groups mode, so setting allowed to empty (which means all quiz attempts
|
||||
// are accessible, is not a security porblem.
|
||||
// are accessible, is not a security problem.
|
||||
$allowedjoins = new \core\dml\sql_join();
|
||||
}
|
||||
|
||||
@ -115,49 +114,7 @@ class quiz_overview_report extends attempts_report {
|
||||
if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {
|
||||
// Construct the SQL.
|
||||
$table->setup_sql_queries($allowedjoins);
|
||||
|
||||
if (!$table->is_downloading()) {
|
||||
// Output the regrade buttons.
|
||||
if (has_capability('mod/quiz:regrade', $this->context)) {
|
||||
$regradesneeded = $this->count_question_attempts_needing_regrade(
|
||||
$quiz, $groupstudentsjoins);
|
||||
if ($currentgroup) {
|
||||
$a= new stdClass();
|
||||
$a->groupname = format_string(groups_get_group_name($currentgroup), true, [
|
||||
'context' => $this->context,
|
||||
]);
|
||||
$a->coursestudents = get_string('participants');
|
||||
$a->countregradeneeded = $regradesneeded;
|
||||
$regradealldrydolabel =
|
||||
get_string('regradealldrydogroup', 'quiz_overview', $a);
|
||||
$regradealldrylabel =
|
||||
get_string('regradealldrygroup', 'quiz_overview', $a);
|
||||
$regradealllabel =
|
||||
get_string('regradeallgroup', 'quiz_overview', $a);
|
||||
} else {
|
||||
$regradealldrydolabel =
|
||||
get_string('regradealldrydo', 'quiz_overview', $regradesneeded);
|
||||
$regradealldrylabel =
|
||||
get_string('regradealldry', 'quiz_overview');
|
||||
$regradealllabel =
|
||||
get_string('regradeall', 'quiz_overview');
|
||||
}
|
||||
$displayurl = new moodle_url($options->get_url(), ['sesskey' => sesskey()]);
|
||||
echo '<div class="regradebuttons">';
|
||||
echo '<form action="'.$displayurl->out_omit_querystring().'">';
|
||||
echo '<div>';
|
||||
echo html_writer::input_hidden_params($displayurl);
|
||||
echo '<input type="submit" class="btn btn-secondary" name="regradeall" value="'.$regradealllabel.'"/>';
|
||||
echo '<input type="submit" class="btn btn-secondary ml-1" name="regradealldry" value="' .
|
||||
$regradealldrylabel . '"/>';
|
||||
if ($regradesneeded) {
|
||||
echo '<input type="submit" class="btn btn-secondary ml-1" name="regradealldrydo" value="' .
|
||||
$regradealldrydolabel . '"/>';
|
||||
}
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
echo '</div>';
|
||||
}
|
||||
// Print information on the grading method.
|
||||
if ($strattempthighlight = quiz_report_highlighting_grading_method(
|
||||
$quiz, $this->qmsubselect, $options->onlygraded)) {
|
||||
@ -182,7 +139,8 @@ class quiz_overview_report extends attempts_report {
|
||||
$this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers, false);
|
||||
$this->add_grade_item_columns($options->usercanseegrades, $columns, $headers);
|
||||
|
||||
if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) &&
|
||||
$canregrade = has_capability('mod/quiz:regrade', $this->context);
|
||||
if (!$table->is_downloading() && $canregrade &&
|
||||
$this->has_regraded_questions($table->sql->from, $table->sql->where, $table->sql->params)) {
|
||||
$columns[] = 'regraded';
|
||||
$headers[] = get_string('regrade', 'quiz_overview');
|
||||
@ -206,6 +164,10 @@ class quiz_overview_report extends attempts_report {
|
||||
$table->set_attribute('class', 'generaltable generalbox grades');
|
||||
|
||||
$table->out($options->pagesize, true);
|
||||
|
||||
if ($canregrade && !$table->is_downloading()) {
|
||||
$this->display_commit_regrade_if_required($quiz, $groupstudentsjoins, $options);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$table->is_downloading() && $options->usercanseegrades) {
|
||||
@ -239,9 +201,47 @@ class quiz_overview_report extends attempts_report {
|
||||
echo $output->chart($chart, $graphname, ['dir' => 'ltr']);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a previous dry run regrade had been done, display a message to commit the changes.
|
||||
*
|
||||
* @param stdClass $quiz quiz settings.
|
||||
* @param \core\dml\sql_join $groupstudentsjoins which users' attempts should be considered.
|
||||
* @param quiz_overview_options $options report options.
|
||||
*/
|
||||
protected function display_commit_regrade_if_required(
|
||||
stdClass $quiz,
|
||||
\core\dml\sql_join $groupstudentsjoins,
|
||||
quiz_overview_options $options,
|
||||
) {
|
||||
global $OUTPUT;
|
||||
|
||||
[$attemptcount, $slotcount] = $this->count_attempts_and_questions_needing_regrade($quiz, $groupstudentsjoins);
|
||||
if (!$attemptcount) {
|
||||
return;
|
||||
}
|
||||
|
||||
$commitregradeurl = new moodle_url($options->get_url(), ['sesskey' => sesskey(), 'regradealldrydo' => 1]);
|
||||
|
||||
// We can't use $OUTPUT->notification because is aggressively cleans the message, which strips the button.
|
||||
echo html_writer::div(get_string('regrade_regradeneedednotificationmessage', 'quiz_overview',
|
||||
['attempts' => $attemptcount, 'questions' => $slotcount]) . ' ' .
|
||||
$OUTPUT->single_button($commitregradeurl, get_string('regrade_commitregrade', 'quiz_overview')),
|
||||
'alert alert-info alert-block fade in');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function process_actions($quiz, $cm, $currentgroup, \core\dml\sql_join $groupstudentsjoins,
|
||||
\core\dml\sql_join $allowedjoins, $redirecturl) {
|
||||
parent::process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $redirecturl);
|
||||
|
||||
// Process regrade actions.
|
||||
$this->process_regrade_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $redirecturl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends parent function processing any submitted actions.
|
||||
*
|
||||
@ -249,34 +249,38 @@ class quiz_overview_report extends attempts_report {
|
||||
* @param stdClass $cm
|
||||
* @param int $currentgroup
|
||||
* @param \core\dml\sql_join $groupstudentsjoins (joins, wheres, params)
|
||||
* @param \core\dml\sql_join $allowedjoins (joins, wheres, params)
|
||||
* @param moodle_url $redirecturl
|
||||
*/
|
||||
protected function process_actions($quiz, $cm, $currentgroup, \core\dml\sql_join $groupstudentsjoins,
|
||||
\core\dml\sql_join $allowedjoins, $redirecturl) {
|
||||
parent::process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $redirecturl);
|
||||
protected function process_regrade_actions($quiz, $cm, $currentgroup,
|
||||
\core\dml\sql_join $groupstudentsjoins, moodle_url $redirecturl) {
|
||||
|
||||
if (empty($currentgroup) || $this->hasgroupstudents) {
|
||||
if (optional_param('regrade', 0, PARAM_BOOL) && confirm_sesskey()) {
|
||||
if ($attemptids = optional_param_array('attemptid', [], PARAM_INT)) {
|
||||
$this->start_regrade($quiz, $cm);
|
||||
$this->regrade_attempts($quiz, false, $groupstudentsjoins, $attemptids);
|
||||
$this->finish_regrade($redirecturl);
|
||||
}
|
||||
}
|
||||
if ($currentgroup && !$this->hasgroupstudents) {
|
||||
return;
|
||||
}
|
||||
if (!has_capability('mod/quiz:regrade', $this->context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (optional_param('regradeall', 0, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$this->start_regrade($quiz, $cm);
|
||||
$this->regrade_attempts($quiz, false, $groupstudentsjoins);
|
||||
$this->finish_regrade($redirecturl);
|
||||
$dryrun = optional_param('dryrunregrade', 0, PARAM_BOOL);
|
||||
if ($dryrun || optional_param('regrade', 0, PARAM_BOOL)) {
|
||||
|
||||
} else if (optional_param('regradealldry', 0, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$this->start_regrade($quiz, $cm);
|
||||
$this->regrade_attempts($quiz, true, $groupstudentsjoins);
|
||||
$this->finish_regrade($redirecturl);
|
||||
$attemptids = [];
|
||||
if (optional_param('regradeselectedattempts', 0, PARAM_BOOL)) {
|
||||
$attemptids = optional_param_array('attemptid', [], PARAM_INT);
|
||||
}
|
||||
|
||||
} else if (optional_param('regradealldrydo', 0, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$slots = null;
|
||||
if (optional_param('regradeselectedquestions', 0, PARAM_BOOL)) {
|
||||
$slots = optional_param_array('regradeslot', [], PARAM_INT);
|
||||
}
|
||||
|
||||
$this->start_regrade($quiz, $cm);
|
||||
$this->regrade_attempts($quiz, $dryrun, $groupstudentsjoins, $attemptids, $slots);
|
||||
$this->finish_regrade($redirecturl);
|
||||
}
|
||||
|
||||
// Process commit of a previous dry run.
|
||||
if (optional_param('regradealldrydo', 0, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$this->start_regrade($quiz, $cm);
|
||||
$this->regrade_attempts_needing_it($quiz, $groupstudentsjoins);
|
||||
$this->finish_regrade($redirecturl);
|
||||
@ -329,7 +333,7 @@ class quiz_overview_report extends attempts_report {
|
||||
*
|
||||
* @param stdClass $attempt the quiz attempt to regrade.
|
||||
* @param bool $dryrun if true, do a pretend regrade, otherwise do it for real.
|
||||
* @param array $slots if null, regrade all questions, otherwise, just regrade
|
||||
* @param array|null $slots if null, regrade all questions, otherwise, just regrade
|
||||
* the questions with those slots.
|
||||
* @return array messages array with keys slot number, and values reasons why that slot cannot be regraded.
|
||||
*/
|
||||
@ -408,12 +412,15 @@ class quiz_overview_report extends attempts_report {
|
||||
* for these users.
|
||||
* @param array $attemptids blank for all attempts, otherwise only regrade
|
||||
* attempts whose id is in this list.
|
||||
* @param array|null $slots if null, regrade all questions, otherwise, just regrade
|
||||
* the questions with those slots.
|
||||
*/
|
||||
protected function regrade_attempts($quiz, $dryrun = false,
|
||||
core\dml\sql_join $groupstudentsjoins = null, $attemptids = []) {
|
||||
?\core\dml\sql_join $groupstudentsjoins = null, $attemptids = [], ?array $slots = null) {
|
||||
global $DB;
|
||||
$this->unlock_session();
|
||||
|
||||
// Get the attempts to regrade.
|
||||
$userfieldsapi = \core_user\fields::for_name();
|
||||
$sql = "SELECT quiza.*, " . $userfieldsapi->get_sql('u', false, '', '', false)->selects . "
|
||||
FROM {quiz_attempts} quiza
|
||||
@ -439,15 +446,22 @@ class quiz_overview_report extends attempts_report {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->regrade_batch_of_attempts($quiz, $attempts, $dryrun, $groupstudentsjoins);
|
||||
// If only regrading some slots, put that information where regrade_batch_of_attempts expects.
|
||||
if ($slots) {
|
||||
foreach ($attempts as $attempt) {
|
||||
$attempt->regradeonlyslots = $slots;
|
||||
}
|
||||
}
|
||||
|
||||
$this->regrade_batch_of_attempts($quiz, $attempts, $dryrun, $groupstudentsjoins, $slots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Regrade those questions in those attempts that are marked as needing regrading
|
||||
* in the quiz_overview_regrades table.
|
||||
* Regrade the questions in the attempts that are marked as needing it in quiz_overview_regrades.
|
||||
*
|
||||
* @param stdClass $quiz the quiz settings.
|
||||
* @param \core\dml\sql_join $groupstudentsjoins empty for all attempts, otherwise regrade attempts
|
||||
* for these users.
|
||||
* for these users.
|
||||
*/
|
||||
protected function regrade_attempts_needing_it($quiz, \core\dml\sql_join $groupstudentsjoins) {
|
||||
global $DB;
|
||||
@ -527,12 +541,9 @@ class quiz_overview_report extends attempts_report {
|
||||
$a['attemptnum'] = $attempt->attempt;
|
||||
$a['name'] = fullname($attempt);
|
||||
$a['attemptid'] = $attempt->id;
|
||||
if (!isset($attempt->regradeonlyslots)) {
|
||||
$attempt->regradeonlyslots = null;
|
||||
}
|
||||
$progressbar->update($a['done'], $a['count'],
|
||||
get_string('regradingattemptxofywithdetails', 'quiz_overview', $a));
|
||||
$messages = $this->regrade_attempt($attempt, $dryrun, $attempt->regradeonlyslots);
|
||||
$messages = $this->regrade_attempt($attempt, $dryrun, $attempt->regradeonlyslots ?? null);
|
||||
if ($messages) {
|
||||
$items = [];
|
||||
foreach ($messages as $slot => $message) {
|
||||
@ -553,14 +564,14 @@ class quiz_overview_report extends attempts_report {
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of attempts in need of a regrade.
|
||||
* Count the number of attempts and questions in need of regrading after the last dry run.
|
||||
*
|
||||
* @param stdClass $quiz the quiz settings.
|
||||
* @param \core\dml\sql_join $groupstudentsjoins (joins, wheres, params) If this is given, only data relating
|
||||
* to these users is cleared.
|
||||
* @return int the number of attempts.
|
||||
* @param \core\dml\sql_join $groupstudentsjoins which users' attempts should be considered.
|
||||
* @return array of two elements: the number of different attempts and questions needed to be regraded.
|
||||
*/
|
||||
protected function count_question_attempts_needing_regrade($quiz, \core\dml\sql_join $groupstudentsjoins) {
|
||||
protected function count_attempts_and_questions_needing_regrade($quiz,
|
||||
\core\dml\sql_join $groupstudentsjoins): array {
|
||||
global $DB;
|
||||
|
||||
$userjoin = '';
|
||||
@ -574,7 +585,8 @@ class quiz_overview_report extends attempts_report {
|
||||
}
|
||||
|
||||
$params['cquiz'] = $quiz->id;
|
||||
$sql = "SELECT COUNT(DISTINCT quiza.id)
|
||||
$sql = "SELECT COUNT(DISTINCT quiza.id) AS attemptcount,
|
||||
COUNT(DISTINCT qqr.slot) AS slotcount
|
||||
FROM {quiz_attempts} quiza
|
||||
JOIN {quiz_overview_regrades} qqr ON quiza.uniqueid = qqr.questionusageid
|
||||
$userjoin
|
||||
@ -583,7 +595,8 @@ class quiz_overview_report extends attempts_report {
|
||||
quiza.quiz = :cquiz AND
|
||||
quiza.preview = 0 AND
|
||||
qqr.regraded = 0";
|
||||
return $DB->count_records_sql($sql, $params);
|
||||
$counts = $DB->get_record_sql($sql, $params);
|
||||
return [$counts->attemptcount, $counts->slotcount];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,93 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template quiz_overview/regrade_modal_body
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"actionurl": "https://example.com/moodle/mod/quiz/report.php?mode=overview?id=123",
|
||||
"hasselectedattempts": false,
|
||||
"questions": [
|
||||
{"slot": 3, "name": "Question 1"},
|
||||
{"slot": 5, "name": "Question 2"}
|
||||
],
|
||||
"hiddeninputs": [
|
||||
{"name": "cmid", "value": 123}
|
||||
]
|
||||
}
|
||||
}}
|
||||
<form action="{{actionurl}}" method="post">
|
||||
{{#hiddeninputs}}
|
||||
<input type="hidden" name="{{name}}" value="{{value}}">
|
||||
{{/hiddeninputs}}
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="regradeselectedattempts"
|
||||
id="regradeallattempts" value="0" {{^hasselectedattempts}}checked{{/hasselectedattempts}}>
|
||||
<label class="form-check-label" for="regradeallattempts">
|
||||
{{# str }} regrade_allattempts, quiz_overview {{/str}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="regradeselectedattempts"
|
||||
id="regradeselectedattempts" value="1" {{#hasselectedattempts}}checked{{/hasselectedattempts}}
|
||||
{{^hasselectedattempts}}disabled{{/hasselectedattempts}}>
|
||||
<label class="form-check-label" for="regradeselectedattempts">
|
||||
{{# str }} regrade_selectedattempts, quiz_overview {{/str}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mt-2">
|
||||
<div class="col">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="regradeselectedquestions"
|
||||
id="regradeallquestions" value="0" checked>
|
||||
<label class="form-check-label" for="regradeallquestions">
|
||||
{{# str }} regrade_allquestions, quiz_overview {{/str}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="regradeselectedquestions"
|
||||
id="regradeselectedquestions" value="1">
|
||||
<label class="form-check-label" for="regradeselectedquestions">
|
||||
{{# str }} regrade_selectedquestions, quiz_overview {{/str}}
|
||||
</label>
|
||||
</div>
|
||||
<fieldset>
|
||||
{{#questions}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="regradeslot[]"
|
||||
id="regradeslot{{slot}}" value="{{slot}}" disabled>
|
||||
<label class="form-check-label" for="regradeslot{{slot}}">
|
||||
{{name}}
|
||||
</label>
|
||||
</div>
|
||||
{{/questions}}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer mt-2 pb-0" data-region="footer">
|
||||
<input type="submit" class="btn btn-primary" id="regradebutton" name="regrade" value="{{#str}} regrade_regradenow, quiz_overview {{/str}}">
|
||||
<input type="submit" class="btn btn-primary" id="dryrunbutton" name="dryrunregrade" value="{{#str}} regrade_dryrun, quiz_overview {{/str}}">
|
||||
</div>
|
||||
</form>
|
@ -101,8 +101,6 @@ Feature: Basic use of the Grades report
|
||||
|
||||
# Verify groups are displayed correctly.
|
||||
And I set the field "Visible groups" to "English"
|
||||
And "Full regrade for group 'English'" "button" should exist
|
||||
And "Dry run a full regrade for group 'English'" "button" should exist
|
||||
And I should see "Number of students in group 'English' achieving grade ranges"
|
||||
|
||||
@javascript
|
||||
|
@ -43,11 +43,11 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
| 1 | True |
|
||||
| 2 | toad |
|
||||
|
||||
Scenario: Regrade all attempts
|
||||
Scenario: Regrade all attempts and all questions.
|
||||
Given I am on the "Quiz for testing regrading" "quiz activity" page logged in as teacher
|
||||
And I navigate to "Results" in current page administration
|
||||
When I press "Regrade all"
|
||||
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
# Note, the order is not defined, so we can only check part of the message.
|
||||
# Also, nothing has changed in the quiz, so the regrade won't alter any scores,
|
||||
# but this is still a useful test that the regrade process completes without errors.
|
||||
@ -60,12 +60,12 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Overall number of students achieving grade ranges"
|
||||
|
||||
Scenario: Regrade selected attempts
|
||||
Scenario: Regrade selected attempts and all questions.
|
||||
Given I am on the "Quiz for testing regrading" "quiz activity" page logged in as teacher
|
||||
And I navigate to "Results" in current page administration
|
||||
When I click on "Select attempt" "checkbox" in the "Student Two" "table_row"
|
||||
|
||||
And I press "Regrade selected attempts"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
@ -75,7 +75,58 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Overall number of students achieving grade ranges"
|
||||
|
||||
Scenario: Dry-run a full regrade, then regrade the attempts that will need it.
|
||||
Scenario: Regrade all attempts and selected questions.
|
||||
Given I am on the "Quiz for testing regrading" "mod_quiz > edit" page logged in as teacher
|
||||
When I follow "Edit question SA"
|
||||
And I set the field "id_fraction_1" to "50%"
|
||||
And I press "id_submitbutton"
|
||||
And I follow "Edit question TF"
|
||||
And I set the field "Correct answer" to "False"
|
||||
And I press "id_submitbutton"
|
||||
And I follow "Attempts: 2"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Selected questions" "radio"
|
||||
And I click on "Question 1" "checkbox"
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (2/2)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
And "Student OneReview attempt" row "Q. 1/50.00Sort by Q. 1/50.00 Ascending" column of "attempts" table should contain "50.00/0.00"
|
||||
And "Student TwoReview attempt" row "Q. 1/50.00Sort by Q. 1/50.00 Ascending" column of "attempts" table should contain "50.00/0.00"
|
||||
And "Student OneReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "100.00/50.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/40.00"
|
||||
|
||||
Scenario: Regrade selected attempts and selected questions.
|
||||
Given I am on the "Quiz for testing regrading" "mod_quiz > edit" page logged in as teacher
|
||||
When I follow "Edit question SA"
|
||||
And I set the field "id_fraction_1" to "50%"
|
||||
And I press "id_submitbutton"
|
||||
And I follow "Edit question TF"
|
||||
And I set the field "Correct answer" to "False"
|
||||
And I press "id_submitbutton"
|
||||
And I follow "Attempts: 2"
|
||||
And I click on "Select attempt" "checkbox" in the "Student Two" "table_row"
|
||||
And I press "Regrade attempts..."
|
||||
And the "Question 1" "checkbox" should be disabled
|
||||
And the "Question 2" "checkbox" should be disabled
|
||||
And I click on "Selected questions" "radio"
|
||||
And the "Question 1" "checkbox" should be enabled
|
||||
And the "Question 2" "checkbox" should be enabled
|
||||
And the "Regrade now" "button" should be disabled
|
||||
And the "Dry run" "button" should be disabled
|
||||
And I click on "Question 1" "checkbox"
|
||||
And the "Regrade now" "button" should be enabled
|
||||
And the "Dry run" "button" should be enabled
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
And "Student TwoReview attempt" row "Q. 1/50.00Sort by Q. 1/50.00 Ascending" column of "attempts" table should contain "50.00/0.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/40.00"
|
||||
|
||||
Scenario: Dry-run all attempts, then regrade all attempts.
|
||||
Given I am on the "Quiz for testing regrading" "mod_quiz > edit" page logged in as teacher
|
||||
And I follow "Edit question SA"
|
||||
And I set the field "id_fraction_1" to "50%"
|
||||
@ -83,8 +134,8 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I set the field "version" in the "TF" "list_item" to "v1"
|
||||
And I set the field "version" in the "SA" "list_item" to "v2 (latest)"
|
||||
And I follow "Attempts: 2"
|
||||
And I press "Dry run a full regrade"
|
||||
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Dry run" "button" in the "Regrade" "dialogue"
|
||||
# Note, the order is not defined, so we can only check part of the message.
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (2/2)"
|
||||
@ -97,7 +148,42 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
# At this point, it is showing what would change.
|
||||
And "Student TwoReview attempt" row "Q. 2/50.00Sort by Q. 2/50.00 Ascending" column of "attempts" table should contain "40.00/25.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/75.00"
|
||||
And I press "Regrade attempts marked as needing regrading (1)"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (2/2)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
# These next tests just serve to check we got back to the report.
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Overall number of students achieving grade ranges"
|
||||
# Now, both old-score strike-through and new score plain, are still shown, but now it indicates what did change.
|
||||
And "Student TwoReview attempt" row "Q. 2/50.00Sort by Q. 2/50.00 Ascending" column of "attempts" table should contain "40.00/25.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/75.00"
|
||||
|
||||
Scenario: Dry-run a full regrade, then regrade the commit regrade.
|
||||
Given I am on the "Quiz for testing regrading" "mod_quiz > edit" page logged in as teacher
|
||||
When I follow "Edit question SA"
|
||||
And I set the field "id_fraction_1" to "50%"
|
||||
And I press "id_submitbutton"
|
||||
And I set the field "version" in the "TF" "list_item" to "v1"
|
||||
And I set the field "version" in the "SA" "list_item" to "v2 (latest)"
|
||||
And I follow "Attempts: 2"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Dry run" "button" in the "Regrade" "dialogue"
|
||||
# Note, the order is not defined, so we can only check part of the message.
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (2/2)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
And "Student One" row "Regrade" column of "attempts" table should not contain "Needed"
|
||||
And "Student TwoReview attempt" row "Regrade" column of "attempts" table should contain "Needed"
|
||||
# In the following, the first number is strike-through, and the second is not, but Behat can't see that.
|
||||
# At this point, it is showing what would change.
|
||||
And "Student TwoReview attempt" row "Q. 2/50.00Sort by Q. 2/50.00 Ascending" column of "attempts" table should contain "40.00/25.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/75.00"
|
||||
Then I should see "The last dry-run of a regrade found that the re-grade would change the marks for 1 questions in 1 attempts."
|
||||
And I press "Commit regrade"
|
||||
And I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
@ -109,12 +195,13 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
# Now, both old-score strike-through and new score plain, are still shown, but now it indicates what did change.
|
||||
And "Student TwoReview attempt" row "Q. 2/50.00Sort by Q. 2/50.00 Ascending" column of "attempts" table should contain "40.00/25.00"
|
||||
And "Student TwoReview attempt" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "attempts" table should contain "90.00/75.00"
|
||||
And "Regrade attempts marked as needing regrading" "button" should not exist
|
||||
And I should not see "The last dry-run of a regrade found that the re-grade would change the marks for 1 questions in 1 attempts."
|
||||
|
||||
Scenario: Regrade all attempts works against quiz selected question version
|
||||
Given I am on the "Quiz for testing regrading" "quiz activity" page logged in as teacher
|
||||
And I navigate to "Results" in current page administration
|
||||
When I press "Dry run a full regrade"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Dry run" "button" in the "Regrade" "dialogue"
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "Finished regrading (2/2)"
|
||||
And I should see "Regrade completed"
|
||||
@ -129,12 +216,14 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I am on the "Quiz for testing regrading" "mod_quiz > edit" page
|
||||
And I set the field "version" in the "TF" "list_item" to "v2 (latest)"
|
||||
And I navigate to "Results" in current page administration
|
||||
And I press "Dry run a full regrade"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Dry run" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
And "student1@example.com" row "Regrade" column of "attempts" table should contain "Needed"
|
||||
And "Correct" "icon" should appear before "50.00/0.00" "text"
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
Then "student1@example.com" row "Regrade" column of "attempts" table should contain "Done"
|
||||
@ -173,7 +262,8 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I am on the "Quiz for testing regrading" "mod_quiz > edit" page
|
||||
And I set the field "version" in the "TF" "list_item" to "Always latest"
|
||||
And I navigate to "Results" in current page administration
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
@ -212,7 +302,8 @@ Feature: Regrading quiz attempts using the Grades report
|
||||
And I navigate to "Results" in current page administration
|
||||
And "student3@example.com" row "Q. 1/100.00Sort by Q. 1/100.00 Ascending" column of "attempts" table should contain "100.00"
|
||||
And "Correct" "icon" should be visible
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
|
@ -42,7 +42,8 @@ Feature: Quiz regrade when not possible
|
||||
|
||||
# Try a regrade, and verify what happened is reported.
|
||||
When I am on the "Quiz for testing regrading" "mod_quiz > grades report" page
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
|
||||
Then I should see "Quiz for testing regrading"
|
||||
And I should see "The following questions could not be regraded in attempt 1 by Student One"
|
||||
|
@ -51,12 +51,14 @@ Feature: Allow students to redo questions in a practice quiz, without starting a
|
||||
And I click on "Check" "button" in the "First question" "question"
|
||||
And I press "Try another question like this one"
|
||||
And I am on the "Quiz 1" "mod_quiz > Grades report" page logged in as "teacher"
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
Then I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
And I press "Continue"
|
||||
# Regrade a second time, to ensure the first regrade did not corrupt any data.
|
||||
And I press "Regrade all"
|
||||
And I press "Regrade attempts..."
|
||||
And I click on "Regrade now" "button" in the "Regrade" "dialogue"
|
||||
And I should see "Finished regrading (1/1)"
|
||||
And I should see "Regrade completed"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user