mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
Merge branch 'MDL-46091' of git://github.com/timhunt/moodle
This commit is contained in:
commit
cf003b48bc
@ -368,9 +368,16 @@ class quiz_access_manager {
|
||||
* @return mod_quiz_preflight_check_form the form.
|
||||
*/
|
||||
public function get_preflight_check_form(moodle_url $url, $attemptid) {
|
||||
// This form normally wants POST submissins. However, it also needs to
|
||||
// accept GET submissions. Since formslib is strict, we have to detect
|
||||
// which case we are in, and set the form property appropriately.
|
||||
$method = 'post';
|
||||
if (!empty($_GET['_qf__mod_quiz_preflight_check_form'])) {
|
||||
$method = 'get';
|
||||
}
|
||||
return new mod_quiz_preflight_check_form($url->out_omit_querystring(),
|
||||
array('rules' => $this->rules, 'quizobj' => $this->quizobj,
|
||||
'attemptid' => $attemptid, 'hidden' => $url->params()));
|
||||
'attemptid' => $attemptid, 'hidden' => $url->params()), $method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,7 @@ class mod_quiz_preflight_check_form extends moodleform {
|
||||
|
||||
protected function definition() {
|
||||
$mform = $this->_form;
|
||||
$this->_form->updateAttributes(array('id' => 'mod_quiz_preflight_form'));
|
||||
|
||||
foreach ($this->_customdata['hidden'] as $name => $value) {
|
||||
if ($name === 'sesskey') {
|
||||
@ -54,7 +55,8 @@ class mod_quiz_preflight_check_form extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
$this->add_action_buttons(true, get_string('continue'));
|
||||
$this->add_action_buttons(true, get_string('startattempt', 'quiz'));
|
||||
$mform->setDisableShortforms();
|
||||
}
|
||||
|
||||
public function validation($data, $files) {
|
||||
|
@ -27,5 +27,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$string['confirmstartheader'] = 'Timed quiz';
|
||||
$string['confirmstart'] = 'The quiz has a time limit of {$a}. Time will count down from the moment you start your attempt and you must submit before it expires. Are you sure that you wish to start now?';
|
||||
$string['pluginname'] = 'Time limit quiz access rule';
|
||||
$string['quiztimelimit'] = 'Time limit: {$a}';
|
||||
|
@ -63,6 +63,18 @@ class quizaccess_timelimit extends quiz_access_rule_base {
|
||||
return false;
|
||||
}
|
||||
return $endtime - $timenow;
|
||||
}
|
||||
|
||||
public function is_preflight_check_required($attemptid) {
|
||||
// Warning only required if the attempt is not already started.
|
||||
return $attemptid === null;
|
||||
}
|
||||
|
||||
public function add_preflight_check_form_fields(mod_quiz_preflight_check_form $quizform,
|
||||
MoodleQuickForm $mform, $attemptid) {
|
||||
$mform->addElement('header', 'honestycheckheader',
|
||||
get_string('confirmstartheader', 'quizaccess_timelimit'));
|
||||
$mform->addElement('static', 'honestycheckmessage', '',
|
||||
get_string('confirmstart', 'quizaccess_timelimit', format_time($this->quiz->timelimit)));
|
||||
}
|
||||
}
|
||||
|
1
mod/quiz/amd/build/preflightcheck.min.js
vendored
Normal file
1
mod/quiz/amd/build/preflightcheck.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/yui"],function(a,b){var c={confirmDialogue:null,init:function(a,d,e,f){var g=a;b.use("moodle-core-notification","moodle-core-formchangechecker","io-form",function(){b.one(e)&&(c.confirmDialogue=new M.core.dialogue({headerContent:d,bodyContent:b.one(e),draggable:!0,visible:!1,center:!0,modal:!0,width:null,extraClasses:["mod_quiz_preflight_popup"]}),b.one(a).on("click",c.displayDialogue),b.one("#id_cancel").on("click",c.hideDialogue),g=c.confirmDialogue.get("boundingBox").one('[name="submitbutton"]')),f&&b.one(g).on("click",c.launchQuizPopup,c,f)})},displayDialogue:function(a){a&&a.halt(),c.confirmDialogue.show()},hideDialogue:function(a){a&&a.halt(),c.confirmDialogue.hide(a)},launchQuizPopup:function(a,c){a.halt(),M.core_formchangechecker.reset_form_dirty_state();var d=a.target.ancestor("form");window.openpopup(a,{url:d.get("action")+"?"+b.IO.stringify(d).replace(/\bcancel=/,"x="),windowname:"quizpopup",options:c,fullscreen:!0})}};return c});
|
112
mod/quiz/amd/src/preflightcheck.js
Normal file
112
mod/quiz/amd/src/preflightcheck.js
Normal file
@ -0,0 +1,112 @@
|
||||
// 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 class manages the confirmation pop-up (also called the pre-flight check)
|
||||
* that is sometimes shown when a use clicks the start attempt button.
|
||||
*
|
||||
* This is also responsible for opening the pop-up window, if the quiz requires to be in one.
|
||||
*
|
||||
* @module mod_quiz/preflightcheck
|
||||
* @class preflightcheck
|
||||
* @package mod_quiz
|
||||
* @copyright 2016 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['jquery', 'core/yui'], function($, Y) {
|
||||
|
||||
/**
|
||||
* @alias module:mod_quiz/preflightcheck
|
||||
*/
|
||||
var t = {
|
||||
confirmDialogue: null,
|
||||
|
||||
/**
|
||||
* Initialise the start attempt button.
|
||||
*
|
||||
* @param {String} startButtonId the id of the start attempt button that we will be enhancing.
|
||||
* @param {String} confirmationTitle the title of the dialogue.
|
||||
* @param {String} confirmationForm selector for the confirmation form to show in the dialogue.
|
||||
* @param {String} popupoptions If not null, the quiz should be launced in a pop-up.
|
||||
*/
|
||||
init: function(startButton, confirmationTitle, confirmationForm, popupoptions) {
|
||||
var finalStartButton = startButton;
|
||||
|
||||
Y.use('moodle-core-notification', 'moodle-core-formchangechecker', 'io-form', function () {
|
||||
if (Y.one(confirmationForm)) {
|
||||
t.confirmDialogue = new M.core.dialogue({
|
||||
headerContent: confirmationTitle,
|
||||
bodyContent: Y.one(confirmationForm),
|
||||
draggable: true,
|
||||
visible: false,
|
||||
center: true,
|
||||
modal: true,
|
||||
width: null,
|
||||
extraClasses: ['mod_quiz_preflight_popup']
|
||||
});
|
||||
|
||||
Y.one(startButton).on('click', t.displayDialogue);
|
||||
Y.one('#id_cancel').on('click', t.hideDialogue);
|
||||
|
||||
finalStartButton = t.confirmDialogue.get('boundingBox').one('[name="submitbutton"]');
|
||||
}
|
||||
|
||||
if (popupoptions) {
|
||||
Y.one(finalStartButton).on('click', t.launchQuizPopup, t, popupoptions);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the dialogue.
|
||||
* @param {Y.EventFacade} e the event being responded to, if any.
|
||||
*/
|
||||
displayDialogue: function(e) {
|
||||
if (e) {
|
||||
e.halt();
|
||||
}
|
||||
t.confirmDialogue.show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the dialogue.
|
||||
* @param {Y.EventFacade} e the event being responded to, if any.
|
||||
*/
|
||||
hideDialogue: function(e) {
|
||||
if (e) {
|
||||
e.halt();
|
||||
}
|
||||
t.confirmDialogue.hide(e);
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for the quiz start attempt button.
|
||||
*/
|
||||
launchQuizPopup: function(e, popupoptions) {
|
||||
e.halt();
|
||||
M.core_formchangechecker.reset_form_dirty_state();
|
||||
var form = e.target.ancestor('form');
|
||||
window.openpopup(e, {
|
||||
url: form.get('action') + '?' + Y.IO.stringify(form).replace(/\bcancel=/, 'x='),
|
||||
windowname: 'quizpopup',
|
||||
options: popupoptions,
|
||||
fullscreen: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return t;
|
||||
});
|
@ -371,23 +371,13 @@ class quiz {
|
||||
// Bits of content =========================================================
|
||||
|
||||
/**
|
||||
* @param bool $unfinished whether there is currently an unfinished attempt active.
|
||||
* @return string if the quiz policies merit it, return a warning string to
|
||||
* be displayed in a javascript alert on the start attempt button.
|
||||
* @param bool $notused not used.
|
||||
* @return string an empty string.
|
||||
* @deprecated since 3.1. This sort of functionality is now entirely handled by quiz access rules.
|
||||
*/
|
||||
public function confirm_start_attempt_message($unfinished) {
|
||||
if ($unfinished) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->quiz->timelimit && $this->quiz->attempts) {
|
||||
return get_string('confirmstartattempttimelimit', 'quiz', $this->quiz->attempts);
|
||||
} else if ($this->quiz->timelimit) {
|
||||
return get_string('confirmstarttimelimit', 'quiz');
|
||||
} else if ($this->quiz->attempts) {
|
||||
return get_string('confirmstartattemptlimit', 'quiz', $this->quiz->attempts);
|
||||
}
|
||||
|
||||
public function confirm_start_attempt_message($notused) {
|
||||
debugging('confirm_start_attempt_message is deprecated. ' .
|
||||
'This sort of functionality is now entirely handled by quiz access rules.');
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -202,9 +202,6 @@ $string['confirmclose'] = 'Once you submit, you will no longer be able to change
|
||||
$string['confirmremovequestion'] = 'Are you sure you want to remove this {$a} question?';
|
||||
$string['confirmremovesectionheading'] = 'Are you sure you want to remove the \'{$a}\' section heading?';
|
||||
$string['confirmserverdelete'] = 'Are you sure you want to remove the server <b>{$a}</b> from the list?';
|
||||
$string['confirmstartattemptlimit'] = 'Number of attempts allowed: {$a}. You are about to start a new attempt. Do you wish to proceed?';
|
||||
$string['confirmstartattempttimelimit'] = 'This quiz has a time limit and is limited to {$a} attempt(s). You are about to start a new attempt. Do you wish to proceed?';
|
||||
$string['confirmstarttimelimit'] = 'The quiz has a time limit. Are you sure that you wish to start?';
|
||||
$string['connectionok'] = 'Network connection restored. You may continue safely.';
|
||||
$string['connectionerror'] = 'Network connection lost. (Autosave failed).
|
||||
|
||||
|
@ -272,23 +272,6 @@ M.mod_quiz.secure_window = {
|
||||
e.halt();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for the quiz start attempt button.
|
||||
*/
|
||||
start_attempt_action: function(e, args) {
|
||||
if (args.startattemptwarning == '') {
|
||||
openpopup(e, args);
|
||||
} else {
|
||||
M.util.show_confirm_dialog(e, {
|
||||
message: args.startattemptwarning,
|
||||
callback: function() {
|
||||
openpopup(e, args);
|
||||
},
|
||||
continuelabel: M.util.get_string('startattempt', 'quiz')
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
init_close_button: function(Y, url) {
|
||||
Y.on('click', function(e) {
|
||||
M.mod_quiz.secure_window.close(url, 0)
|
||||
|
@ -422,9 +422,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
$output .= $this->heading(format_string($quizobj->get_quiz_name(), true,
|
||||
array("context" => $quizobj->get_context())));
|
||||
$output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm());
|
||||
ob_start();
|
||||
$mform->display();
|
||||
$output .= ob_get_clean();
|
||||
$output .= $mform->render();
|
||||
$output .= $this->footer();
|
||||
return $output;
|
||||
}
|
||||
@ -798,9 +796,8 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
|
||||
if ($viewobj->buttontext) {
|
||||
$output .= $this->start_attempt_button($viewobj->buttontext,
|
||||
$viewobj->startattempturl, $viewobj->startattemptwarning,
|
||||
$viewobj->startattempturl, $viewobj->preflightcheckform,
|
||||
$viewobj->popuprequired, $viewobj->popupoptions);
|
||||
|
||||
}
|
||||
|
||||
if ($viewobj->showbacktocourse) {
|
||||
@ -815,43 +812,44 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
/**
|
||||
* Generates the view attempt button
|
||||
*
|
||||
* @param int $course The course ID
|
||||
* @param array $quiz Array containging quiz date
|
||||
* @param int $cm The Course Module ID
|
||||
* @param int $context The page Context ID
|
||||
* @param mod_quiz_view_object $viewobj
|
||||
* @param string $buttontext
|
||||
* @param string $buttontext the label to display on the button.
|
||||
* @param moodle_url $url The URL to POST to in order to start the attempt.
|
||||
* @param mod_quiz_preflight_check_form $preflightcheckform deprecated.
|
||||
* @param bool $popuprequired whether the attempt needs to be opened in a pop-up.
|
||||
* @param array $popupoptions the options to use if we are opening a popup.
|
||||
* @return string HTML fragment.
|
||||
*/
|
||||
public function start_attempt_button($buttontext, moodle_url $url,
|
||||
$startattemptwarning, $popuprequired, $popupoptions) {
|
||||
mod_quiz_preflight_check_form $preflightcheckform = null,
|
||||
$popuprequired = false, $popupoptions = null) {
|
||||
|
||||
if (is_string($preflightcheckform)) {
|
||||
// Calling code was not updated since the API change.
|
||||
debugging('The third argument to start_attempt_button should now be the ' .
|
||||
'mod_quiz_preflight_check_form from ' .
|
||||
'quiz_access_manager::get_preflight_check_form, not a warning message string.');
|
||||
}
|
||||
|
||||
$button = new single_button($url, $buttontext);
|
||||
$button->class .= ' quizstartbuttondiv';
|
||||
|
||||
$warning = '';
|
||||
if ($popuprequired) {
|
||||
$this->page->requires->js_module(quiz_get_js_module());
|
||||
$this->page->requires->js('/mod/quiz/module.js');
|
||||
$popupaction = new popup_action('click', $url, 'quizpopup', $popupoptions);
|
||||
|
||||
$button->class .= ' quizsecuremoderequired';
|
||||
$button->add_action(new component_action('click',
|
||||
'M.mod_quiz.secure_window.start_attempt_action', array(
|
||||
'url' => $url->out(false),
|
||||
'windowname' => 'quizpopup',
|
||||
'options' => $popupaction->get_js_options(),
|
||||
'fullscreen' => true,
|
||||
'startattemptwarning' => $startattemptwarning,
|
||||
)));
|
||||
|
||||
$warning = html_writer::tag('noscript', $this->heading(get_string('noscript', 'quiz')));
|
||||
|
||||
} else if ($startattemptwarning) {
|
||||
$button->add_action(new confirm_action($startattemptwarning, null,
|
||||
get_string('startattempt', 'quiz')));
|
||||
$popupjsoptions = null;
|
||||
if ($popuprequired && $popupoptions) {
|
||||
$action = new popup_action('click', $url, 'popup', $popupoptions);
|
||||
$popupjsoptions = $action->get_js_options();
|
||||
}
|
||||
|
||||
return $this->render($button) . $warning;
|
||||
if ($preflightcheckform) {
|
||||
$checkform = $preflightcheckform->render();
|
||||
} else {
|
||||
$checkform = null;
|
||||
}
|
||||
|
||||
$this->page->requires->js_call_amd('mod_quiz/preflightcheck', 'init',
|
||||
array('.quizstartbuttondiv input[type=submit]', get_string('startattempt', 'quiz'),
|
||||
'#mod_quiz_preflight_form', $popupjsoptions));
|
||||
|
||||
return $this->render($button) . $checkform;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1316,10 +1314,11 @@ class mod_quiz_view_object {
|
||||
/** @var string $buttontext caption for the start attempt button. If this is null, show no
|
||||
* button, or if it is '' show a back to the course button. */
|
||||
public $buttontext;
|
||||
/** @var string $startattemptwarning alert to show the user before starting an attempt. */
|
||||
public $startattemptwarning;
|
||||
/** @var moodle_url $startattempturl URL to start an attempt. */
|
||||
public $startattempturl;
|
||||
/** @var moodleform|null $preflightcheckform confirmation form that must be
|
||||
* submitted before an attempt is started, if required. */
|
||||
public $preflightcheckform;
|
||||
/** @var moodle_url $startattempturl URL for any Back to the course button. */
|
||||
public $backtocourseurl;
|
||||
/** @var bool $showbacktocourse should we show a back to the course button? */
|
||||
@ -1330,4 +1329,16 @@ class mod_quiz_view_object {
|
||||
public $popupoptions;
|
||||
/** @var bool $quizhasquestions whether the quiz has any questions. */
|
||||
public $quizhasquestions;
|
||||
|
||||
public function __get($field) {
|
||||
switch ($field) {
|
||||
case 'startattemptwarning':
|
||||
debugging('startattemptwarning has been deprecated. It is now always blank.');
|
||||
return '';
|
||||
|
||||
default:
|
||||
debugging('Unknown property ' . $field);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,8 +125,8 @@ if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS ||
|
||||
}
|
||||
|
||||
// Check access.
|
||||
$output = $PAGE->get_renderer('mod_quiz');
|
||||
if (!$quizobj->is_preview_user() && $messages) {
|
||||
$output = $PAGE->get_renderer('mod_quiz');
|
||||
print_error('attempterror', 'quiz', $quizobj->view_url(),
|
||||
$output->access_messages($messages));
|
||||
}
|
||||
@ -137,7 +137,7 @@ if ($accessmanager->is_preflight_check_required($currentattemptid)) {
|
||||
$quizobj->start_attempt_url($page), $currentattemptid);
|
||||
|
||||
if ($mform->is_cancelled()) {
|
||||
$accessmanager->back_to_view_page($output);
|
||||
$accessmanager->back_to_view_page($PAGE->get_renderer('mod_quiz'));
|
||||
|
||||
} else if (!$mform->get_data()) {
|
||||
|
||||
@ -145,6 +145,7 @@ if ($accessmanager->is_preflight_check_required($currentattemptid)) {
|
||||
$PAGE->set_url($quizobj->start_attempt_url($page));
|
||||
$PAGE->set_title($quizobj->get_quiz_name());
|
||||
$accessmanager->setup_attempt_page($PAGE);
|
||||
$output = $PAGE->get_renderer('mod_quiz');
|
||||
if (empty($quizobj->get_quiz()->showblocks)) {
|
||||
$PAGE->blocks->show_only_fake_blocks();
|
||||
}
|
||||
|
@ -345,6 +345,47 @@ table.quizattemptsummary .noreviewmessage {
|
||||
.jsenabled .quizstartbuttondiv.quizsecuremoderequired input {
|
||||
display: inline;
|
||||
}
|
||||
.quizattempt #mod_quiz_preflight_form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mod_quiz_preflight_form .femptylabel .fitemtitle {
|
||||
display: none;
|
||||
}
|
||||
#mod_quiz_preflight_form .femptylabel .felement {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup {
|
||||
width: 600px;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-wrap {
|
||||
overflow: hidden;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd {
|
||||
padding: 0;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form legend {
|
||||
padding: 0 10px;
|
||||
margin: 0;
|
||||
border: 0 none;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form .fitem {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-bd #mod_quiz_preflight_form #fgroup_id_buttonar {
|
||||
padding: 10px 0 0;
|
||||
margin: 0;
|
||||
}
|
||||
.moodle-dialogue-base .moodle-dialogue.mod_quiz_preflight_popup .moodle-dialogue-content .moodle-dialogue-ft {
|
||||
margin: 0;
|
||||
}
|
||||
/* Standard Moodle rule that needs to be more specific here. */
|
||||
.moodle-dialogue-bd #mod_quiz_preflight_form fieldset.hidden {
|
||||
display: inherit;
|
||||
visibility: inherit;
|
||||
}
|
||||
|
||||
body.path-mod-quiz .gradedattempt,
|
||||
body.path-mod-quiz table tbody tr.gradedattempt > td {
|
||||
|
115
mod/quiz/tests/behat/attempt_begin.feature
Normal file
115
mod/quiz/tests/behat/attempt_begin.feature
Normal file
@ -0,0 +1,115 @@
|
||||
@mod @mod_quiz
|
||||
Feature: The various checks that may happen when an attept is started
|
||||
As a student
|
||||
In order to start a quiz with confidence
|
||||
I need to be waned if there is a time limit, or various similar things
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student | Student | One | student@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student | C1 | student |
|
||||
And the following "question categories" exist:
|
||||
| contextlevel | reference | name |
|
||||
| Course | C1 | Test questions |
|
||||
And the following "questions" exist:
|
||||
| questioncategory | qtype | name | questiontext |
|
||||
| Test questions | truefalse | TF1 | Text of the first question |
|
||||
|
||||
@javascript
|
||||
Scenario: Start a quiz with no time limit
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page |
|
||||
| TF1 | 1 |
|
||||
When I log in as "student"
|
||||
And I follow "Course 1"
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
Then I should see "Text of the first question"
|
||||
|
||||
@javascript
|
||||
Scenario: Start a quiz with time limit and password
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | timelimit | quizpassword |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page |
|
||||
| TF1 | 1 |
|
||||
When I log in as "student"
|
||||
And I follow "Course 1"
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
Then I should see "To attempt this quiz you need to know the quiz password" in the "Start attempt" "dialogue"
|
||||
And I should see "The quiz has a time limit of 1 hour. Time will " in the "Start attempt" "dialogue"
|
||||
And I set the field "Quiz password" to "Frog"
|
||||
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
|
||||
And I should see "Text of the first question"
|
||||
|
||||
@javascript
|
||||
Scenario: Cancel starting a quiz with time limit and password
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | timelimit | quizpassword |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page |
|
||||
| TF1 | 1 |
|
||||
When I log in as "student"
|
||||
And I follow "Course 1"
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
And I click on "Cancel" "button" in the "Start attempt" "dialogue"
|
||||
Then I should see "Quiz 1 description"
|
||||
And "Attempt quiz now" "button" should be visible
|
||||
|
||||
@javascript
|
||||
Scenario: Start a quiz with time limit and password, get the password wrong first time
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | timelimit | quizpassword |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page |
|
||||
| TF1 | 1 |
|
||||
When I log in as "student"
|
||||
And I follow "Course 1"
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
And I set the field "Quiz password" to "Toad"
|
||||
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
|
||||
Then I should see "Quiz 1 description"
|
||||
And I should see "To attempt this quiz you need to know the quiz password"
|
||||
And I should see "The quiz has a time limit of 1 hour. Time will "
|
||||
And I should see "The password entered was incorrect"
|
||||
And I set the field "Quiz password" to "Frog"
|
||||
And I press "Start attempt"
|
||||
And I should see "Text of the first question"
|
||||
|
||||
@javascript
|
||||
Scenario: Start a quiz with time limit and password, get the password wrong first time then cancel
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | timelimit | quizpassword |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 3600 | Frog |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page |
|
||||
| TF1 | 1 |
|
||||
When I log in as "student"
|
||||
And I follow "Course 1"
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
And I set the field "Quiz password" to "Toad"
|
||||
And I click on "Start attempt" "button" in the "Start attempt" "dialogue"
|
||||
And I should see "Quiz 1 description"
|
||||
And I should see "To attempt this quiz you need to know the quiz password"
|
||||
And I should see "The quiz has a time limit of 1 hour. Time will "
|
||||
And I should see "The password entered was incorrect"
|
||||
And I set the field "Quiz password" to "Frog"
|
||||
And I press "Cancel"
|
||||
Then I should see "Quiz 1 description"
|
||||
And "Attempt quiz now" "button" should be visible
|
@ -1,9 +1,18 @@
|
||||
This files describes API changes in the quiz code.
|
||||
|
||||
=== 3.1 ===
|
||||
|
||||
* quiz_attempt::question_print_comment_fields() has been removed. It was broken
|
||||
since at least Moodle 2.0.
|
||||
|
||||
* quiz::confirm_start_attempt_message and mod_quiz_view_object::$startattemptwarning
|
||||
have been deprecated. This functionality is now entirely handled within the
|
||||
quiz access rule plugins.
|
||||
|
||||
* The third argument to mod_quiz_renderer::start_attempt_button has been changed
|
||||
from a warning string to a mod_quiz_preflight_check_form.
|
||||
|
||||
|
||||
=== 2.9 ===
|
||||
|
||||
* There have been changes in classes/output/edit_renderer.php for MDL-40990.
|
||||
@ -100,6 +109,7 @@ This files describes API changes in the quiz code.
|
||||
trigger the event outside this function. Note that the appropriate start event is
|
||||
fired automatically by the quiz_attempt_save_started function.
|
||||
|
||||
|
||||
=== 2.7 ===
|
||||
|
||||
* The old quiz.questions database column (comma-separated list of question ids)
|
||||
@ -130,6 +140,7 @@ This files describes API changes in the quiz code.
|
||||
quiz_delete_empty_page: has had its arguments changed to $quiz and $pagenumber.
|
||||
quiz_has_question_use: now takes $quiz and $slot, not $questionid.
|
||||
|
||||
|
||||
=== 2.6 ===
|
||||
|
||||
* As part of improving the page usability and accessibility, we updated the
|
||||
|
@ -93,6 +93,7 @@ $viewobj->canreviewmine = $canreviewmine;
|
||||
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true);
|
||||
$lastfinishedattempt = end($attempts);
|
||||
$unfinished = false;
|
||||
$unfinishedattemptid = null;
|
||||
if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) {
|
||||
$attempts[] = $unfinishedattempt;
|
||||
|
||||
@ -105,6 +106,7 @@ if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id))
|
||||
if (!$unfinished) {
|
||||
$lastfinishedattempt = $unfinishedattempt;
|
||||
}
|
||||
$unfinishedattemptid = $unfinishedattempt->id;
|
||||
$unfinishedattempt = null; // To make it clear we do not use this again.
|
||||
}
|
||||
$numattempts = count($attempts);
|
||||
@ -177,7 +179,11 @@ $viewobj->canedit = has_capability('mod/quiz:manage', $context);
|
||||
$viewobj->editurl = new moodle_url('/mod/quiz/edit.php', array('cmid' => $cm->id));
|
||||
$viewobj->backtocourseurl = new moodle_url('/course/view.php', array('id' => $course->id));
|
||||
$viewobj->startattempturl = $quizobj->start_attempt_url();
|
||||
$viewobj->startattemptwarning = $quizobj->confirm_start_attempt_message($unfinished);
|
||||
|
||||
if ($accessmanager->is_preflight_check_required($unfinishedattemptid)) {
|
||||
$viewobj->preflightcheckform = $accessmanager->get_preflight_check_form(
|
||||
$viewobj->startattempturl, $unfinishedattemptid);
|
||||
}
|
||||
$viewobj->popuprequired = $accessmanager->attempt_must_be_in_popup();
|
||||
$viewobj->popupoptions = $accessmanager->get_popup_options();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user