Compare commits

..

70 Commits

Author SHA1 Message Date
Jake Dallimore 84d3ae1b08 Moodle release 3.9.15 2022-07-08 11:28:28 +08:00
Jun Pataleta 71f83af13c weekly release 3.9.14+ 2022-07-07 21:33:14 +08:00
Víctor Déniz d587d8b242 Merge branch 'MDL-74835-M39_update-nodejs-version-in-travis-integration-to-lts-gallium' of https://github.com/ziegenberg/moodle into MOODLE_39_STABLE 2022-07-06 12:13:40 +01:00
stevando f1b1570b02 MDL-72171 tool_mobile: Ensure auto login URL is always local 2022-07-06 14:29:10 +08:00
Mihail Geshoski f9ca67a78d MDL-71921 scorm: Sanitize element names before outputting track details 2022-07-01 12:47:18 +02:00
Alex Morris c8f9140e70 MDL-75044 assignfeedback_editpdf: Add SAFER option to GS command
Adds the SAFER option to the Ghostscript command to limit interaction
with IO and OS commands
2022-07-01 12:47:18 +02:00
Huong Nguyen 47c211ba0e MDL-72029 Lesson: Prevent arbitrary file read when importing lesson questions in blackboard format 2022-07-01 12:47:18 +02:00
Huong Nguyen 9f270d956e MDL-72029 lib: Prevent path traversal for clean_param with PARAM_SAFEPATH 2022-07-01 12:47:18 +02:00
Laurent David 32ee8e3d34 MDL-74473 core_analytics: Upgrade ML Backend to 2.6.6 2022-07-01 12:47:18 +02:00
Jake Dallimore 77a1413fa0 MDL-72299 mod_lti: fix html escaping when reposting cross site posts 2022-07-01 12:47:18 +02:00
Víctor Déniz 14760d9787 weekly release 3.9.14+ 2022-07-01 11:28:53 +01:00
Jun Pataleta 03b6b93589 Merge branch 'MDL-74613-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 20:23:48 +08:00
Noel De Martin 47402416fd MDL-74613 grade: Fix undefined behat step 2022-06-30 11:32:35 +02:00
Andrew Nicols 0087cede97 Merge branch 'MDL-75084-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:14:09 +08:00
Andrew Nicols 264c405192 Merge branch 'MDL-74613-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:05:38 +08:00
Andrew Nicols 1742e0c27c Merge branch 'MDL-74220-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:00:59 +08:00
Andrew Nicols 7371cb4838 Merge branch 'MDL-74744-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-06-30 10:56:19 +08:00
Andrew Nicols c1512e8d89 Merge branch 'MDL-74841-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-06-30 10:45:12 +08:00
Jake Dallimore e5aaeed609 Merge branch 'MDL-74674-39' of https://github.com/alfonso-salces/moodle into MOODLE_39_STABLE 2022-06-29 16:45:23 +08:00
Alfonso Salces a950ed04a7 MDL-74674 core: create notification generators 2022-06-29 10:29:33 +02:00
Noel De Martin 964c98c8d9 MDL-75084 blog: Implement behat generators 2022-06-29 09:38:55 +02:00
Jake Dallimore 635389b235 Merge branch 'MDL-74864-39' of https://github.com/dpalou/moodle into MOODLE_39_STABLE 2022-06-29 13:41:31 +08:00
Dani Palou 1385e3bc09 MDL-74864 forum: Allow specifying group in discussions generator 2022-06-28 07:00:18 +02:00
Jun Pataleta 2dc581f717 weekly release 3.9.14+ 2022-06-17 15:30:38 +08:00
Víctor Déniz 4f8369c3f1 Merge branch 'MDL-74242-39-randomize_update_check' of https://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2022-06-14 09:48:51 +01:00
Jun Pataleta 730b405d68 Merge branch 'MDL-74816-39' of https://github.com/dpalou/moodle into MOODLE_39_STABLE 2022-06-14 13:58:29 +08:00
Angelia Dela Cruz 87c04f1e0b MDL-74841 behat: Label behat generators use UI
Replace steps that manually add Label instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-06-10 13:58:46 +08:00
Andrew Nicols f4df13fb6c weekly release 3.9.14+ 2022-06-03 11:06:38 +08:00
Paul Holden 4a8abf77ac MDL-71276 message_email: include alternate email in privacy export. 2022-06-01 18:48:11 +02:00
Noel De Martin 7e48ec1820 MDL-74613 grade: Add missing generators 2022-05-31 18:15:23 +02:00
Jake Dallimore 05087afd40 weekly release 3.9.14+ 2022-05-27 10:02:16 +08:00
Noel De Martin 56afed9678 MDL-74220 data: Implement behat generators 2022-05-26 10:39:38 +02:00
Paul Holden af8c168f78 MDL-73801 backup: set predictably ordered backup next start time.
Prior to this change, the testcase would assert ordering based on
identical fields which could lead to random failures. Set distinct
next start time of course backup, and also remove random ordering
by sorting on defined course order (all other fields being equal).
2022-05-26 12:10:49 +08:00
Dani Palou 4c52746b41 MDL-74816 mod_resource: Allow specify default file name in generator 2022-05-25 10:41:43 +02:00
Angelia Dela Cruz 7768a35366 MDL-74744 behat: Quiz behat generators use UI
Replace steps that manually add Quiz instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-05-24 11:23:21 +08:00
Daniel Ziegenberg 05847affc1 MDL-74835 ci: Update nodejs version in travis integration to lts/gallium
In MDL-73915 the nodejs version was switched to lts/gallium but the
travis integration was not updated.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-05-22 23:55:08 +02:00
Jun Pataleta a63efe42d1 Moodle release 3.9.14 2022-05-07 19:34:47 +08:00
Eloy Lafuente (stronk7) f4b45aa02c weekly release 3.9.13+ 2022-05-06 15:58:44 +02:00
Víctor Déniz 0a2fdafe37 Merge branch 'MDL-74612-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2022-05-05 13:27:03 +01:00
Jake Dallimore fa855204af MDL-73736 core_auth: Fix concurrency issue in login_attempt_failed()
This patch wraps the login_failed_count logic in a resource lock and
forces a user preferences cache reload. Each thread must wait for the
lock and must fetch the current count before incrementing it. This
ensures that login_failed_count is correct across threads and that the
lockout threshold is correctly honoured.

Co-Authored-By: Sujith Haridasan <sujith@moodle.com>
2022-05-04 16:27:58 +06:00
Michael Hawkins 70cf2159d4 MDL-74333 badges: Check profile criteria valid when reviewing 2022-05-04 12:58:43 +08:00
Ferran Recio 55e08c48c7 MDL-71623 core_search: fix user document visibility 2022-05-02 16:42:02 +06:00
Amaia Anabitarte 8f954b91f4 MDL-74318 core_user: Description field as hidden on profile 2022-05-02 12:27:15 +02:00
Paul Holden bbd4540075 MDL-74204 mod_assign: escape identity fields in allocate marker form. 2022-05-02 12:27:15 +02:00
Víctor Déniz 780a8aa0aa Merge branch 'MDL-73951-39' of https://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2022-05-02 11:13:46 +01:00
Paul Holden c55b5aa305 MDL-74612 cohort: use data generator for populating cohort members. 2022-04-29 16:23:43 +01:00
Michael Hawkins bb822f465a MDL-73951 core: Updated security.txt expiry date
Also updated expiry date format to meet latest standard.
2022-04-29 19:03:10 +08:00
Ilya Tregubov ec1282cd7f weekly release 3.9.13+ 2022-04-08 16:39:57 +06:00
Víctor Déniz 9d0ac7d6ed Merge branch 'MDL-74189-39' of https://github.com/mihailges/moodle into MOODLE_39_STABLE 2022-04-06 22:57:26 +01:00
Mihail Geshoski 9164c896c4 MDL-74189 tool_moodlenet: Add upgrade step to remove irrelevant data
Upgrade step to identify all existing cases where users have linked
their MoodleNet profile on the site and remove the related data from
the database. Due to some recent changes on the MoodleNet platform,
this data is now irrelevant and can no longer be used to authenticate
on the MoodleNet platform.
2022-04-06 23:40:49 +08:00
Mihail Geshoski 398bcbce55 MDL-74189 tool_moodlenet: Update language strings
Updates the existing language strings in order to provide more accurate
instructions on how users can link existing their MoodleNet profile on
the site.
2022-04-06 23:40:49 +08:00
Sara Arjona 7890567fad weekly release 3.9.13+ 2022-04-05 13:24:53 +02:00
Jun Pataleta 41b456e1a2 Merge branch 'MDL-70014_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-04-04 13:56:00 +08:00
Jun Pataleta ce9c32a016 Merge branch 'MDL-74096-39' of https://github.com/ilyatregubov/moodle into MOODLE_39_STABLE 2022-04-04 13:05:21 +08:00
Ilya Tregubov 600b2f01fa MDL-74096 mlbackend_python: Update mlbackend version. 2022-04-04 09:16:44 +06:00
Eloy Lafuente (stronk7) c94868ba12 MDL-70014 tool_customlang: Workaround to make behat happier
This is a BEHAT_RUNNING only hack, so it doesn't affect normal
operations at all. What it achieves is to reduce the number of
strings loaded when customising a lang pack from current 31K ones
to the just needed ones for Behat testing purposes.

That way we avoid the random failures that are happening more and
more (while the "en" lang pack grows) and also save some precious
minutes in every behat run.

Also, unrelated, a couple of tiny changes:
- Modified constant (that was really outdated) to current number
  of lang strings (so the progress bar behaves better).
- Remove an elseif occurrence because it was hurting my eyes.
2022-04-01 23:57:26 +02:00
Sara Arjona db6f627bad weekly release 3.9.13+ 2022-04-01 16:40:51 +02:00
Andrew Nicols c61c666667 Merge branch 'MDL-72446_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-03-31 22:34:20 +08:00
Eloy Lafuente (stronk7) b41d588695 MDL-72446 behat: Ensure that the day reset happens on enabled element
Before this change we were setting the month day to 1 unconditionally
and that was working ok for enabled by default elements.

But in a number or cases we were doing that against disabled elements
so the day reset was not happening. Now we wait for the element to
be enabled and only then proceed with the day reset.

Backed with tests using disabled form elements, so we have now
both enabled and disabled fields covered.
2022-03-31 12:22:52 +02:00
Víctor Déniz 48b4929c23 weekly release 3.9.13+ 2022-03-25 15:00:37 +00:00
Sara Arjona 501a4fc35c MDL-74184 behat: Unrelated, remove the @skip_interim tag
This commit is UNRELATED to the MDL-74184, but we need the
@skip_interim tag removed to a couple of scenarios that were
causing lots of noise and failures @ci infrastructure.
MDL-74265 was created to deal with this issue but these jobs
are now passing, and nothing has been changed...

So we are using MDL-74184 (this extra commit) to remove that
tag (sorry for the noise).
2022-03-22 17:24:08 +01:00
David Mudrák f652a2b613 MDL-74242 task: Fix calculation of random minute in the task schedule
The random minute was incorrectly set to a random value from the range
0 - 23 instead of 0 - 59 due to this copy & paste mistake.

This is a backport of MDL-73765 already present in 3.11.
2022-03-20 17:06:51 +01:00
David Mudrák 04d4cbde78 MDL-74242 admin: Check for available updates daily on random time
It's been a mistake to make every Moodle site out there to check for
available update every two hours, on the hour. We are experiencing
server load peaks that are harder and harder to deal with.

The patch addresses this by (1) checking for available updates just once
a day and (2) distributing the checking times randomly around the clock.

This is a backport of MDL-73748 already present in 3.11.
2022-03-20 17:06:51 +01:00
Sara Arjona e9f0baf90e weekly release 3.9.13+ 2022-03-18 16:28:22 +01:00
Sara Arjona 9ce9388c8d MDL-74116 behat: Unrelated, add the @skip_interim tag
This commit is UNRELATED to the MDL-74116, but we need the
@skip_interim tag added to a couple of scenarios that are
causing lots of noise and failures  @CI infrastructure.
MDL-74265 has been created to deal with this issue.

So we are using MDL-74116 (this extra commit) to add that tag
(sorry for the noise).
2022-03-18 13:46:49 +01:00
Eloy Lafuente (stronk7) 497f4ee8b9 Merge branch 'MDL-74116-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-03-16 22:19:50 +01:00
Andrew Nicols 6955a9b618 MDL-74116 behat: Fix browser instantiation for Selenium 4 2022-03-16 22:28:29 +08:00
Sara Arjona b75b238591 Merge branch 'MDL-74130_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2022-03-15 12:19:35 +01:00
Tim Hunt 47acac9180 MDL-74130 question behat: Update tests to use the new navigation steps 2022-03-10 12:13:44 +00:00
Tim Hunt 351ad0c0e9 MDL-74130 question behat: support I am on ... page or key qbank pages 2022-03-10 09:31:59 +00:00
128 changed files with 1812 additions and 997 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ jobs:
- php: 7.2
env: DB=none TASK=CITEST
- php: 7.2
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
env: DB=none TASK=GRUNT NVM_VERSION='lts/gallium'
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.2
@@ -52,7 +52,7 @@ jobs:
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 7.4
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
env: DB=none TASK=GRUNT NVM_VERSION='lts/gallium'
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 7.4
+4 -2
View File
@@ -14,6 +14,10 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
And the following "cohorts" exist:
| name | idnumber |
| Cohort 1 | CH1 |
And the following "cohort members" exist:
| user | cohort |
| user2 | CH1 |
| user3 | CH1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
@@ -23,8 +27,6 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
| user2 | C1 | student |
| user3 | C1 | student |
And I log in as "admin"
And I add "User Two (two@example.com)" user to "CH1" cohort members
And I add "User Three (three@example.com)" user to "CH1" cohort members
And I navigate to "Users > Accounts > Browse list of users" in site administration
Scenario: Filter user accounts by role and cohort
@@ -20,9 +20,10 @@ Feature: Forms manipulation
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1"
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Quiz 1 |
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
When I expand all fieldsets
Then I should see "Close the quiz"
And I should see "Group mode"
+15 -2
View File
@@ -36,7 +36,7 @@ class tool_customlang_utils {
* Rough number of strings that are being processed during a full checkout.
* This is used to estimate the progress of the checkout.
*/
const ROUGH_NUMBER_OF_STRINGS = 16500;
const ROUGH_NUMBER_OF_STRINGS = 30000;
/** @var array cache of {@link self::list_components()} results */
private static $components = null;
@@ -91,9 +91,22 @@ class tool_customlang_utils {
public static function checkout($lang, progress_bar $progressbar = null) {
global $DB;
// For behat executions we are going to load only a few components in the
// language customisation structures. Using the whole "en" langpack is
// too much slow (leads to Selenium 30s timeouts, especially on slow
// environments) and we don't really need the whole thing for tests. So,
// apart from escaping from the timeouts, we are also saving some good minutes
// in tests. See MDL-70014 and linked issues for more info.
$behatneeded = ['core', 'core_langconfig', 'tool_customlang'];
// make sure that all components are registered
$current = $DB->get_records('tool_customlang_components', null, 'name', 'name,version,id');
foreach (self::list_components() as $component) {
// Filter out unwanted components when running behat.
if (defined('BEHAT_SITE_RUNNING') && !in_array($component, $behatneeded)) {
continue;
}
if (empty($current[$component])) {
$record = new stdclass();
$record->name = $component;
@@ -103,7 +116,7 @@ class tool_customlang_utils {
$record->version = $version;
}
$DB->insert_record('tool_customlang_components', $record);
} elseif ($version = get_component_version($component)) {
} else if ($version = get_component_version($component)) {
if (is_null($current[$component]->version) or ($version > $current[$component]->version)) {
$DB->set_field('tool_customlang_components', 'version', $version, array('id' => $current[$component]->id));
}
+2 -1
View File
@@ -27,7 +27,8 @@ require_once($CFG->libdir . '/externallib.php');
$userid = required_param('userid', PARAM_INT); // The user id the key belongs to (for double-checking).
$key = required_param('key', PARAM_ALPHANUMEXT); // The key generated by the tool_mobile_external::get_autologin_key() external function.
$urltogo = optional_param('urltogo', $CFG->wwwroot, PARAM_URL); // URL to redirect.
$urltogo = optional_param('urltogo', $CFG->wwwroot, PARAM_LOCALURL); // URL to redirect.
$urltogo = $urltogo ?: $CFG->wwwroot;
$context = context_system::instance();
$PAGE->set_context($context);
@@ -0,0 +1,45 @@
<?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/>.
declare(strict_types=1);
namespace tool_moodlenet\task;
use core\message\message;
/**
* Ad-hoc task to send a notification to admin stating that the user data related to the linked MoodleNet profiles has
* been removed.
*
* @package tool_moodlenet
* @copyright 2022 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class send_mnet_profiles_data_removed_notification extends \core\task\adhoc_task {
public function execute(): void {
$message = new message();
$message->component = 'moodle';
$message->name = 'notices';
$message->userfrom = \core_user::get_noreply_user();
$message->userto = get_admin();
$message->notification = 1;
$message->subject = get_string('removedmnetprofilenotification_subject', 'tool_moodlenet');
$message->fullmessageformat = FORMAT_HTML;
$message->fullmessagehtml = get_string('removedmnetprofilenotification', 'tool_moodlenet');
$message->smallmessage = strip_tags($message->fullmessagehtml);
message_send($message);
}
}
+19
View File
@@ -123,5 +123,24 @@ function xmldb_tool_moodlenet_upgrade(int $oldversion) {
upgrade_plugin_savepoint(true, 2020061503, 'tool', 'moodlenet');
}
if ($oldversion < 2020061504) {
$selectsql = "moodlenetprofile IS NOT NULL AND moodlenetprofile != ''";
// If there are any users with MoodleNet profile set.
if ($DB->count_records_select('user', $selectsql)) {
// Remove the value set for the MoodleNet profile as this format can no longer be used to authenticate
// MoodleNet users.
$DB->set_field_select('user', 'moodlenetprofile', '', $selectsql);
// Use an adhoc task to send a notification to admin stating that the user data related to the linked
// MoodleNet profiles has been removed.
$notificationtask = new tool_moodlenet\task\send_mnet_profiles_data_removed_notification();
core\task\manager::queue_adhoc_task($notificationtask);
}
upgrade_plugin_savepoint(true, 2020061504, 'tool', 'moodlenet');
}
return true;
}
@@ -26,7 +26,7 @@
defined('MOODLE_INTERNAL') || die();
$string['addingaresource'] = 'Adding content from MoodleNet';
$string['aria:enterprofile'] = "Enter your MoodleNet profile URL";
$string['aria:enterprofile'] = "Enter your MoodleNet profile ID";
$string['aria:footermessage'] = "Browse for content on MoodleNet";
$string['browsecontentmoodlenet'] = "Or browse for content on MoodleNet";
$string['clearsearch'] = "Clear search";
@@ -39,11 +39,11 @@ $string['defaultmoodlenetname_desc'] = 'The name of the MoodleNet instance avail
$string['enablemoodlenet'] = 'Enable MoodleNet integration';
$string['enablemoodlenet_desc'] = 'If enabled, a user with the capability to create and manage activities can browse MoodleNet via the activity chooser and import MoodleNet resources into their course. In addition, a user with the capability to restore backups can select a backup file on MoodleNet and restore it into Moodle.';
$string['errorduringdownload'] = 'An error occurred while downloading the file: {$a}';
$string['forminfo'] = 'Your MoodleNet profile will be automatically saved in your profile on this site.';
$string['forminfo'] = 'Your MoodleNet profile ID will be automatically saved in your profile on this site.';
$string['footermessage'] = "Or browse for content on";
$string['instancedescription'] = "MoodleNet is an open social media platform for educators, with a focus on the collaborative curation of collections of open resources. ";
$string['instanceplaceholder'] = '@yourprofile@moodle.net';
$string['inputhelp'] = 'Or if you have a MoodleNet account already, enter your MoodleNet profile:';
$string['instanceplaceholder'] = 'a1b2c3d4e5f6-example@moodle.net';
$string['inputhelp'] = 'Or if you have a MoodleNet account already, copy the ID from your MoodleNet profile and paste it here:';
$string['invalidmoodlenetprofile'] = '$userprofile is not correctly formatted';
$string['importconfirm'] = 'You are about to import the content "{$a->resourcename} ({$a->resourcetype})" into the course "{$a->coursename}". Are you sure you want to continue?';
$string['importconfirmnocourse'] = 'You are about to import the content "{$a->resourcename} ({$a->resourcetype})" into your site. Are you sure you want to continue?';
@@ -56,12 +56,15 @@ $string['mnetprofiledesc'] = '<p>Enter your MoodleNet profile details here to be
$string['moodlenetsettings'] = 'MoodleNet settings';
$string['moodlenetnotenabled'] = 'The MoodleNet integration must be enabled in Site administration / MoodleNet before resource imports can be processed.';
$string['notification'] = 'You are about to import the content "{$a->name} ({$a->type})" into your site. Select the course in which it should be added, or <a href="{$a->cancellink}">cancel</a>.';
$string['removedmnetprofilenotification'] = '<p>Due to some recent changes on the MoodleNet platform, users that have previously saved their MoodleNet profile on the site can no longer use this data to authenticate on the MoodleNet platform. The related data has now been removed as it is no longer useful.</p>
<p>The users will need to reset this information on the site by linking their MoodleNet profile ID which can be found on their MoodleNet profile.</p>';
$string['removedmnetprofilenotification_subject'] = 'Linked MoodleNet profiles removed.';
$string['searchcourses'] = "Search courses";
$string['selectpagetitle'] = 'Select page';
$string['pluginname'] = 'MoodleNet';
$string['privacy:metadata'] = "The MoodleNet tool only facilitates communication with MoodleNet. It stores no data.";
$string['profilevalidationerror'] = 'There was a problem trying to validate your profile';
$string['profilevalidationfail'] = 'Please enter a valid MoodleNet profile';
$string['profilevalidationerror'] = 'There was a problem trying to validate your MoodleNet profile ID';
$string['profilevalidationfail'] = 'Please enter a valid MoodleNet profile ID';
$string['profilevalidationpass'] = 'Looks good!';
$string['saveandgo'] = "Save and go";
$string['uploadlimitexceeded'] = 'The file size {$a->filesize} exceeds the user upload limit of {$a->uploadlimit} bytes.';
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_moodlenet';
$plugin->version = 2020061503;
$plugin->version = 2020061504;
$plugin->requires = 2020060900;
$plugin->maturity = MATURITY_ALPHA;
@@ -19,14 +19,13 @@ Feature: Backup user data
And the following config values are set as admin:
| coursebinenable | 1 | tool_recyclebin |
| autohide | 0 | tool_recyclebin |
And the following "activities" exist:
| activity | course | section | name | intro |
| quiz | C1 | 1 | Quiz 1 | Test quiz description |
@javascript
Scenario: Delete and restore a quiz with user data
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1" and I fill the form with:
| Name | Quiz 1 |
| Description | Test quiz description |
Given I am on the "Quiz 1" "quiz activity" page logged in as teacher1
And I add a "True/False" question to the "Quiz 1" quiz with:
| Question name | TF1 |
| Question text | First question |
@@ -41,6 +40,8 @@ Feature: Backup user data
| Correct answer | False |
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
And I set the field "maxgrade" to "10.0"
And I press "savechanges"
And I log out
When I am on the "Quiz 1" "quiz activity" page logged in as student1
And I press "Attempt quiz now"
@@ -77,6 +77,7 @@ abstract class backup_cron_automated_helper {
* First backup courses that do not have an entry in backup_courses first,
* as they are likely new and never been backed up. Do the oldest modified courses first.
* Then backup courses that have previously been backed up starting with the oldest next start time.
* Finally, all else being equal, defer to the sortorder of the courses.
*
* @param null|int $now timestamp to use in course selection.
* @return moodle_recordset The recordset of matching courses.
@@ -93,7 +94,8 @@ abstract class backup_cron_automated_helper {
LEFT JOIN {backup_courses} bc ON bc.courseid = c.id
WHERE bc.nextstarttime IS NULL OR bc.nextstarttime < ?
ORDER BY nextstarttime ASC,
c.timemodified DESC';
c.timemodified DESC,
c.sortorder';
$params = array(
$now, // Only get courses where the backup start time is in the past.
+1 -1
View File
@@ -383,7 +383,7 @@ class backup_cron_helper_testcase extends advanced_testcase {
$backupcourse3 = new stdClass;
$backupcourse3->courseid = $course3->id;
$backupcourse3->laststatus = testable_backup_cron_automated_helper::BACKUP_STATUS_OK;
$backupcourse3->nextstarttime = 1554858160;
$backupcourse3->nextstarttime = 1554822160;
$DB->insert_record('backup_courses', $backupcourse3);
$backupcourse4 = new stdClass;
+2 -2
View File
@@ -206,8 +206,8 @@ class award_criteria_profile extends award_criteria {
$join .= " LEFT JOIN {user_info_data} uid{$idx} ON uid{$idx}.userid = u.id AND uid{$idx}.fieldid = :fieldid{$idx} ";
$sqlparams["fieldid{$idx}"] = $param['field'];
$whereparts[] = "uid{$idx}.id IS NOT NULL";
} else {
// This is a field from {user} table.
} else if (in_array($param['field'], $this->allowed_default_fields)) {
// This is a valid field from {user} table.
if ($param['field'] == 'picture') {
// The picture field is numeric and requires special handling.
$whereparts[] = "u.{$param['field']} != 0";
+8 -6
View File
@@ -401,6 +401,12 @@ Feature: Award badges based on cohort
| user1 | First | User | first@example.com |
| user2 | Second | User | second@example.com |
| user3 | Third | User | third@example.com |
And the following "cohort members" exist:
| user | cohort |
| user1 | CH1 |
| user1 | CH2 |
| user2 | CH2 |
| user2 | CH3 |
And I log in as "admin"
And I navigate to "Badges > Add a new badge" in site administration
And I set the following fields to these values:
@@ -415,7 +421,7 @@ Feature: Award badges based on cohort
And I press "Save"
And I press "Enable access"
When I press "Continue"
And I should see "Recipients (0)"
And I should see "Recipients (1)"
And I navigate to "Badges > Add a new badge" in site administration
And I set the following fields to these values:
| Name | Site Badge 2 |
@@ -429,11 +435,7 @@ Feature: Award badges based on cohort
And I press "Save"
And I press "Enable access"
And I press "Continue"
Then I navigate to "Users > Accounts >Cohorts" in site administration
And I add "First User (first@example.com)" user to "CH1" cohort members
And I add "First User (first@example.com)" user to "CH2" cohort members
And I add "Second User (second@example.com)" user to "CH2" cohort members
And I add "Second User (second@example.com)" user to "CH3" cohort members
And I should see "Recipients (1)"
And I log out
And I log in as "user1"
And I follow "Profile" in the user menu
+3 -9
View File
@@ -9,6 +9,9 @@ Feature: Comment on a blog entry
| username | firstname | lastname | email |
| testuser | Test | User | moodle@example.com |
| testuser2 | Test2 | User2 | moodle2@example.com |
And the following "core_blog > entries" exist:
| subject | body | user |
| Blog post from user 1 | User 1 blog post content | testuser |
And I log in as "admin"
And I am on site homepage
And I turn editing mode on
@@ -19,15 +22,6 @@ Feature: Comment on a blog entry
| Page contexts | Display throughout the entire site |
And I press "Save changes"
And I log out
And I log in as "testuser"
And I click on "Site pages" "list_item" in the "Navigation" "block"
And I click on "Site blogs" "link" in the "Navigation" "block"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post from user 1 |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I log out
@javascript
Scenario: Commenting on my own blog entry
+4 -11
View File
@@ -8,6 +8,10 @@ Feature: Delete a blog entry
Given the following "users" exist:
| username | firstname | lastname | email |
| testuser | Test | User | moodle@example.com |
And the following "core_blog > entries" exist:
| subject | body | user |
| Blog post one | User 1 blog post content | testuser |
| Blog post two | User 1 blog post content | testuser |
And I log in as "admin"
And I am on site homepage
And I turn editing mode on
@@ -19,17 +23,6 @@ Feature: Delete a blog entry
And I press "Save changes"
And I log out
And I log in as "testuser"
And I click on "Site blogs" "link" in the "Navigation" "block"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post one |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post two |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I am on site homepage
And I click on "Site blogs" "link" in the "Navigation" "block"
@@ -0,0 +1,51 @@
<?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/>.
/**
* Behat data generator for core_blog.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Behat data generator for core_blog.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_core_blog_generator extends behat_generator_base {
/**
* Get a list of the entities that can be created.
*
* @return array entity name => information about how to generate.
*/
protected function get_creatable_entities(): array {
return [
'entries' => [
'singular' => 'entry',
'datagenerator' => 'entry',
'required' => ['subject', 'body'],
'switchids' => ['user' => 'userid'],
],
];
}
}
+55
View File
@@ -0,0 +1,55 @@
<?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/>.
/**
* Generator for blog area.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/blog/locallib.php');
/**
* Blog module test data generator class
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_blog_generator extends component_generator_base {
/**
* Create a blog entry
*
* @param array $data Entry data.
* @return blog_entry Entry instance.
*/
public function create_entry(array $data = []): blog_entry {
$data['publishstate'] = $data['publishstate'] ?? 'site';
$data['summary'] = $data['summary'] ?? $data['body'];
$entry = new blog_entry(null, $data);
$entry->add();
return $entry;
}
}
@@ -34,9 +34,9 @@ Feature: Restrict sections availability through completion or grade conditions
And I set the following fields to these values:
| Enable completion tracking | Yes |
And I press "Save and display"
And I add a "Label" to section "1" and I fill the form with:
| Label text | Test label |
| Completion tracking | Students can manually mark the activity as completed |
And the following "activities" exist:
| activity | course | section | intro | completion | idnumber |
| label | C1 | 1 | Test label | 1 | 1 |
And I add a "Page" to section "2" and I fill the form with:
| Name | Test page name |
| Description | Test page description |
@@ -12,7 +12,7 @@ Feature: We can change what we are viewing on the grader report
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 1 | student2@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
@@ -26,19 +26,15 @@ Feature: We can change what we are viewing on the grader report
| assign | user | onlinetext |
| Test assignment name 1 | student1 | This is a submission for assignment 1 |
| Test assignment name 2 | student1 | This is a submission for assignment 2 |
And I am on the "Test assignment name 1" "assign activity" page logged in as student1
Then I should see "Submitted for grading"
And I am on the "Test assignment name 2" "assign activity" page
Then I should see "Submitted for grading"
And I log out
And the following "grade items" exist:
| itemname | grademin | grademax | course |
| Manual grade | 20 | 40 | C1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name 1 | student1 | 80 |
| Test assignment name 2 | student1 | 90 |
| Manual grade | student1 | 30 |
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 give the grade "80.00" to the user "Student 1" for the grade item "Test assignment name 1"
And I give the grade "90.00" to the user "Student 1" for the grade item "Test assignment name 2"
And I press "Save changes"
And I turn editing mode off
@javascript
Scenario: View and minimise the grader report containing hidden activities
@@ -49,13 +45,15 @@ Feature: We can change what we are viewing on the grader report
And I navigate to "View > Grader report" in the course gradebook
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | 90 | 170 |
| -1- | -4- | -5- | -6- | -7- |
| Student 1 | 80 | 90 | 30 | 170 |
And I click on "Change to aggregates only" "link"
And I should not see "Test assignment name 1"
And I should not see "Test assignment name 2"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- |
@@ -63,10 +61,11 @@ Feature: We can change what we are viewing on the grader report
And I click on "Change to grades only" "link"
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- |
| Student 1 | 80 | 90 |
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | 90 | 30 |
@javascript @skip_chrome_zerosize
Scenario: View and minimise the grader report containing hidden activities without the 'moodle/grade:viewhidden' capability
@@ -84,21 +83,24 @@ Feature: We can change what we are viewing on the grader report
And I navigate to "View > Grader report" in the course gradebook
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | - | 80 |
| -1- | -4- | -5- | -6- | -7- |
| Student 1 | 80 | - | 30 | 105.71 |
And I click on "Change to aggregates only" "link"
And I should not see "Test assignment name 1"
And I should not see "Test assignment name 2"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- |
| Student 1 | 80 |
| Student 1 | 105.71 |
And I click on "Change to grades only" "link"
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- |
| Student 1 | 80 | - |
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | - | 30 |
+2 -2
View File
@@ -36,8 +36,8 @@ $string['filtersetmatchdescription'] = 'How multiple filters should be combined'
$string['filtertype'] = 'Filter type';
$string['match'] = 'Match';
$string['matchofthefollowing'] = 'of the following:';
$string['moodlenetprofile'] = 'MoodleNet profile';
$string['moodlenetprofile_help'] = 'This field is to link your MoodleNet profile to Moodle. It expects a WebFinger compliant URI';
$string['moodlenetprofile'] = 'MoodleNet profile ID';
$string['moodlenetprofile_help'] = 'This field represents your MoodleNet profile ID which is used to link your MoodleNet profile to Moodle. It expects a WebFinger-compliant URI.';
$string['placeholdertypeorselect'] = 'Type or select...';
$string['placeholdertype'] = 'Type...';
$string['privacy:courserequestpath'] = 'Requested courses';
+43 -19
View File
@@ -875,6 +875,7 @@ function login_attempt_valid($user) {
/**
* To be called after failed user login.
* @param stdClass $user
* @throws moodle_exception
*/
function login_attempt_failed($user) {
global $CFG;
@@ -886,30 +887,53 @@ function login_attempt_failed($user) {
return;
}
$count = get_user_preferences('login_failed_count', 0, $user);
$last = get_user_preferences('login_failed_last', 0, $user);
$sincescuccess = get_user_preferences('login_failed_count_since_success', $count, $user);
$sincescuccess = $sincescuccess + 1;
set_user_preference('login_failed_count_since_success', $sincescuccess, $user);
// Force user preferences cache reload to ensure the most up-to-date login_failed_count is fetched.
// This is perhaps overzealous but is the documented way of reloading the cache, as per the test method
// 'test_check_user_preferences_loaded'.
unset($user->preference);
if (empty($CFG->lockoutthreshold)) {
// No threshold means no lockout.
// Always unlock here, there might be some race conditions or leftovers when switching threshold.
login_unlock_account($user);
return;
}
$resource = 'user:' . $user->id;
$lockfactory = \core\lock\lock_config::get_lock_factory('core_failed_login_count_lock');
if (!empty($CFG->lockoutwindow) and time() - $last > $CFG->lockoutwindow) {
$count = 0;
}
// Get a new lock for the resource, waiting for it for a maximum of 10 seconds.
if ($lock = $lockfactory->get_lock($resource, 10)) {
try {
$count = get_user_preferences('login_failed_count', 0, $user);
$last = get_user_preferences('login_failed_last', 0, $user);
$sincescuccess = get_user_preferences('login_failed_count_since_success', $count, $user);
$sincescuccess = $sincescuccess + 1;
set_user_preference('login_failed_count_since_success', $sincescuccess, $user);
$count = $count+1;
if (empty($CFG->lockoutthreshold)) {
// No threshold means no lockout.
// Always unlock here, there might be some race conditions or leftovers when switching threshold.
login_unlock_account($user);
$lock->release();
return;
}
set_user_preference('login_failed_count', $count, $user);
set_user_preference('login_failed_last', time(), $user);
if (!empty($CFG->lockoutwindow) and time() - $last > $CFG->lockoutwindow) {
$count = 0;
}
if ($count >= $CFG->lockoutthreshold) {
login_lock_account($user);
$count = $count + 1;
set_user_preference('login_failed_count', $count, $user);
set_user_preference('login_failed_last', time(), $user);
if ($count >= $CFG->lockoutthreshold) {
login_lock_account($user);
}
// Release locks when we're done.
$lock->release();
} catch (Exception $e) {
// Always release the lock on a failure.
$lock->release();
}
} else {
// We did not get access to the resource in time, give up.
throw new moodle_exception('locktimeout');
}
}
@@ -150,6 +150,12 @@ class behat_core_generator extends behat_generator_base {
'required' => ['fullname', 'course'],
'switchids' => ['course' => 'courseid', 'gradecategory' => 'parent'],
],
'grade grades' => [
'singular' => 'grade grade',
'datagenerator' => 'grade_grade',
'required' => ['gradeitem'],
'switchids' => ['user' => 'userid', 'gradeitem' => 'itemid'],
],
'grade items' => [
'singular' => 'grade item',
'datagenerator' => 'grade_item',
@@ -275,11 +281,33 @@ class behat_core_generator extends behat_generator_base {
'required' => ['user', 'course', 'lastaccess'],
'switchids' => ['user' => 'userid', 'course' => 'courseid'],
],
'notifications' => [
'singular' => 'notification',
'datagenerator' => 'notification',
'required' => ['subject', 'userfrom', 'userto'],
'switchids' => ['userfrom' => 'userfromid', 'userto' => 'usertoid'],
],
];
return $entities;
}
/**
* Get the grade item id using a name.
*
* @param string $name
* @return int The grade item id
*/
protected function get_gradeitem_id(string $name): int {
global $DB;
if (!$id = $DB->get_field('grade_items', 'id', ['itemname' => $name])) {
throw new Exception('The specified grade item with name "' . $name . '" could not be found.');
}
return $id;
}
/**
* Remove any empty custom fields, to avoid errors when creating the course.
*
@@ -1009,6 +1037,39 @@ class behat_core_generator extends behat_generator_base {
$DB->insert_record('badge_backpack', $backpack);
}
/**
* Creates notifications to specific user.
*
* @param array $data
* @return void
*/
protected function process_notification(array $data) {
global $DB;
$notification = new stdClass();
$notification->useridfrom = $data['userfromid'];
$notification->useridto = $data['usertoid'];
$notification->subject = $data['subject'];
$notification->fullmessage = $data['subject'] . ' description';
$notification->smallmessage = $data['subject'] . ' description';
$notification->fullmessagehtml = $data['subject'] . ' description';
if ($data['timecreated'] !== 'null') {
$notification->timecreated = $data['timecreated'];
}
if ($data['timeread'] !== 'null') {
$notification->timeread = $data['timeread'];
}
if (!empty($data)) {
$popupnotification = new stdClass();
$popupnotification->notificationid = $DB->insert_record('notifications', $notification);
$DB->insert_record('message_popup_notifications', $popupnotification);
}
}
/**
* Creates user last access data within given courses.
*
@@ -316,6 +316,36 @@ abstract class behat_generator_base {
return $id;
}
/**
* Gets the user id from it's username.
* @throws Exception
* @param string $username
* @return int
*/
protected function get_userfrom_id(string $username) {
global $DB;
if (!$id = $DB->get_field('user', 'id', ['username' => $username])) {
throw new Exception('The specified user with username "' . $username . '" does not exist');
}
return $id;
}
/**
* Gets the user id from it's username.
* @throws Exception
* @param string $username
* @return int
*/
protected function get_userto_id(string $username) {
global $DB;
if (!$id = $DB->get_field('user', 'id', ['username' => $username])) {
throw new Exception('The specified user with username "' . $username . '" does not exist');
}
return $id;
}
/**
* Gets the role id from it's shortname.
* @throws Exception
@@ -41,10 +41,31 @@ class WebDriverFactory extends UpstreamFactory implements DriverFactory {
$extracapabilities = $config['capabilities']['extra_capabilities'];
unset($config['capabilities']['extra_capabilities']);
// Ensure that the capabilites.browser is set correctly.
$config['capabilities']['browser'] = $config['browser'];
// Normalise the Edge browser name.
if ($config['browser'] === 'edge') {
$config['browser'] = 'MicrosoftEdge';
}
$capabilities = array_replace($this->guessCapabilities(), $extracapabilities, $config['capabilities']);
// Ensure that the capabilites.browserName is set correctly.
$config['capabilities']['browserName'] = $config['browser'];
$capabilities = array_replace($extracapabilities, $config['capabilities']);
// Incorrect top level capabilities lead to invalid Selenium browser selection.
// See https://github.com/SeleniumHQ/selenium/issues/10410 for more information.
// If any of these settings are mentioned then additional empty Capability options are created and a random
// browser is chosen.
$filteredcapabilities = [
'tags',
'ignoreZoomSetting',
'marionette',
'browser',
'name',
];
foreach ($filteredcapabilities as $capabilityname) {
unset($capabilities[$capabilityname]);
}
// Build driver definition.
return new Definition(WebDriver::class, [
+10 -8
View File
@@ -56,17 +56,19 @@ class behat_form_date extends behat_form_group {
// Disable the given date selector field.
$this->set_child_field_value('enabled', false);
} else if (is_numeric($value)) { // The value is numeric (unix timestamp).
// First, reset the day always to an existing one (1st). Without that
// undesired modifications (JS) happens when changing of month and day if
// the interim combination doesn't exists (for example, 31 March => 01 April).
// Note that instead of always setting the day to 1, this could be a little more
// clever, for example only changing when the day > 28, or only when the
// months (current or changed) have less days that the other. But that would
// require more complex calculations than the simpler line below.
$this->set_child_field_value('day', 1);
// Assign the mapped values to each form element in the date selector field.
foreach ($this->get_mapped_fields($value) as $childname => $childvalue) {
$this->set_child_field_value($childname, $childvalue);
if ($childname === 'enabled') {
// As soon as the form is enabled, reset the day to an existing one (1st). Without that
// undesired modifications (JS) happens when changing of month and day if
// the interim combination doesn't exists (for example, 31 March => 01 April).
// Note that instead of always setting the day to 1, this could be a little more
// clever, for example only changing when the day > 28, or only when the
// months (current or changed) have less days that the other. But that would
// require more complex calculations than the simpler line below.
$this->set_child_field_value('day', 1);
}
}
} else { // Invalid value.
// Get the name of the field.
+1 -1
View File
@@ -111,7 +111,7 @@ abstract class scheduled_task extends task_base {
*/
public function set_minute($minute, $expandr = true) {
if ($minute === 'R' && $expandr) {
$minute = mt_rand(self::HOURMIN, self::HOURMAX);
$minute = mt_rand(self::MINUTEMIN, self::MINUTEMAX);
}
$this->minute = $minute;
}
+2 -2
View File
@@ -242,8 +242,8 @@ $tasks = array(
array(
'classname' => 'core\task\check_for_updates_task',
'blocking' => 0,
'minute' => '0',
'hour' => '*/2',
'minute' => 'R',
'hour' => 'R',
'day' => '*',
'dayofweek' => '*',
'month' => '*'
+1 -1
View File
@@ -38,7 +38,7 @@ class processor implements \core_analytics\classifier, \core_analytics\regresso
/**
* The required version of the python package that performs all calculations.
*/
const REQUIRED_PIP_PACKAGE_VERSION = '2.6.4';
const REQUIRED_PIP_PACKAGE_VERSION = '2.6.6';
/**
* The python package is installed in a server.
+12 -2
View File
@@ -978,8 +978,18 @@ function clean_param($param, $type) {
return preg_replace('/[^a-zA-Z0-9_-]/i', '', $param);
case PARAM_SAFEPATH:
// Remove everything not a-zA-Z0-9/_- .
return preg_replace('/[^a-zA-Z0-9\/_-]/i', '', $param);
// Replace MS \ separators.
$param = str_replace('\\', '/', $param);
// Remove any number of ../ to prevent path traversal.
$param = preg_replace('/\.\.+\//', '', $param);
// Remove everything not a-zA-Z0-9/:_- .
$param = preg_replace('/[^a-zA-Z0-9\/:_-]/i', '', $param);
// Remove leading slash.
$param = ltrim($param, '/');
if ($param === '.') {
$param = '';
}
return $param;
case PARAM_FILE:
// Strip all suspicious characters from filename.
+51
View File
@@ -1002,6 +1002,57 @@ EOD;
return $gradecategory->get_record_data();
}
/**
* Create a grade_grade.
*
* @param array $record
* @return grade_grade the grade record
*/
public function create_grade_grade(?array $record = null): grade_grade {
global $DB, $USER;
$item = $DB->get_record('grade_items', ['id' => $record['itemid']]);
$userid = $record['userid'] ?? $USER->id;
unset($record['itemid']);
unset($record['userid']);
if ($item->itemtype === 'mod') {
$cm = get_coursemodule_from_instance($item->itemmodule, $item->iteminstance);
$module = new $item->itemmodule(context_module::instance($cm->id), $cm, false);
$record['attemptnumber'] = $record['attemptnumber'] ?? 0;
$module->save_grade($userid, (object) $record);
$grade = grade_grade::fetch(['userid' => $userid, 'itemid' => $item->id]);
} else {
$grade = grade_grade::fetch(['userid' => $userid, 'itemid' => $item->id]);
$record['rawgrade'] = $record['rawgrade'] ?? $record['grade'] ?? null;
$record['finalgrade'] = $record['finalgrade'] ?? $record['grade'] ?? null;
unset($record['grade']);
if ($grade) {
$fields = $grade->required_fields + array_keys($grade->optional_fields);
foreach ($fields as $field) {
$grade->{$field} = $record[$field] ?? $grade->{$field};
}
$grade->update();
} else {
$record['userid'] = $userid;
$record['itemid'] = $item->id;
$grade = new grade_grade($record, false);
$grade->insert();
}
}
return $grade;
}
/**
* Create a grade_item.
*
+28 -1
View File
@@ -5,7 +5,7 @@ Feature: Any day / month / year combination in date form elements works ok.
Any day / month / year combination must work ok
@javascript
Scenario Outline: Verify that setting any date / datetime is possible
Scenario Outline: Verify that setting any date / datetime is possible with enabled fields
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
@@ -29,3 +29,30 @@ Feature: Any day / month / year combination in date form elements works ok.
| 1709186400 | 1740808800 | Saturday, 1 March 2025, 2:00 | |
| 1577858400 | 1577772000 | Tuesday, 31 December 2019, 2:00 | change of year, back and forth |
| 1577772000 | 1577858400 | Wednesday, 1 January 2020, 2:00 | |
@javascript
Scenario Outline: Verify that setting any date / datetime is possible with disabled fields
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "activity" exist:
| activity | name | intro | course | idnumber |
| assign | Assignment 01 | Assign activity to test some dates | C1 | assign01 |
And I am on the "Assignment 01" "assign activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Due date" to "<initial_date>"
And I set the field "Due date" to "disabled"
And I set the field "Due date" to "<final_date>"
When I press "Save and display"
Then I should see "<date_result>" in the "Due date" "table_row"
Examples:
| initial_date | final_date | date_result | case_explanation (times Australia/Perth) |
| ##today## | ##tomorrow noon## | ##tomorrow noon##%A, %d %B %Y, %I:%M## | change of day, any day, back and forth |
| ##tomorrow## | ##today noon## | ##today noon##%A, %d %B %Y, %I:%M## | |
| 1617256800 | 1617170400 | Wednesday, 31 March 2021, 2:00 | change of month, back and forth |
| 1617170400 | 1617256800 | Thursday, 1 April 2021, 2:00 | |
| 1740808800 | 1709186400 | Thursday, 29 February 2024, 2:00 | change of month, leap year, back and forth |
| 1709186400 | 1740808800 | Saturday, 1 March 2025, 2:00 | |
| 1577858400 | 1577772000 | Tuesday, 31 December 2019, 2:00 | change of year, back and forth |
| 1577772000 | 1577858400 | Wednesday, 1 January 2020, 2:00 | |
+34
View File
@@ -839,6 +839,40 @@ class core_moodlelib_testcase extends advanced_testcase {
}
}
/**
* Provide some tested base url and expected results.
*
* @return array Array of tested base url and expected results.
*/
public function clean_param_safepath_provider(): array {
return [
// MS separator test.
['c:\temp', 'c:/temp'],
// Leading slash test.
['/tmp/', 'tmp/'],
// Path traversal test.
['../../../../../etc/', 'etc/'],
['../', ''],
['.../...//', ''],
['.', '']
];
}
/**
* Test clean_param() method with PARAM_SAFEPATH type.
*
* @dataProvider clean_param_safepath_provider
* @covers ::clean_param
* @param string $path
* @param string $expected
*/
public function test_clean_param_safepath(string $path, string $expected) {
$result = clean_param($path, PARAM_SAFEPATH);
$this->assertSame($expected, $result);
}
public function test_validate_param() {
try {
$param = validate_param('11a', PARAM_INT);
@@ -30,6 +30,7 @@ use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\contextlist;
use \core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\userlist;
use core_privacy\local\request\writer;
use \core_privacy\local\request\approved_userlist;
/**
@@ -42,6 +43,7 @@ use \core_privacy\local\request\approved_userlist;
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\user_preference_provider,
\core_privacy\local\request\plugin\provider {
/**
@@ -125,4 +127,21 @@ class provider implements
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
}
/**
* Export all user preferences for the plugin
*
* @param int $userid
*/
public static function export_user_preferences(int $userid) {
$preference = get_user_preferences('message_processor_email_email', null, $userid);
if (!empty($preference)) {
writer::export_user_preference(
'message_email',
'email',
$preference,
get_string('privacy:preference:email', 'message_email')
);
}
}
}
@@ -43,6 +43,7 @@ $string['privacy:metadata:replyto'] = 'The email address to reply to.';
$string['privacy:metadata:replytoname'] = 'Name of reply to recipient.';
$string['privacy:metadata:subject'] = 'The subject line of the message.';
$string['privacy:metadata:userfrom'] = 'The user sending the message.';
$string['privacy:preference:email'] = 'Preferred email notification address';
$string['tasksendemail'] = 'Messages digest mailings';
// Deprecated since Moodle 3.9.
+44 -12
View File
@@ -13,28 +13,27 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Base class for unit tests for message_email.
*
* @package message_email
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
namespace message_email\privacy;
use context_system;
use core_message_external;
use core_privacy\local\request\writer;
use core_privacy\tests\provider_testcase;
use \core_privacy\tests\provider_testcase;
/**
* Unit tests for message\output\email\classes\privacy\provider.php
*
* @package message_email
* @covers \message_email\privacy\provider
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class message_email_testcase extends provider_testcase {
class provider_test extends provider_testcase {
/**
* Basic setup for these tests.
*/
public function setUp() {
public function setUp(): void {
$this->resetAfterTest(true);
}
@@ -56,5 +55,38 @@ class message_email_testcase extends provider_testcase {
$contextlist = \message_email\privacy\provider::get_contexts_for_userid($user->id);
$this->assertEmpty($contextlist);
}
}
/**
* Test exporting user preferences
*/
public function test_export_user_preferences(): void {
global $CFG;
require_once("{$CFG->dirroot}/message/externallib.php");
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
// Submit configuration form, which adds the preferences..
core_message_external::message_processor_config_form($user->id, 'email', [
[
'name' => 'email_email',
'value' => 'alternate@example.com',
],
]);
// Switch to admin user (so we can validate preferences of the correct user are being exported).
$this->setAdminUser();
provider::export_user_preferences($user->id);
$writer = writer::with_context(context_system::instance());
$this->assertTrue($writer->has_any_data());
$preferences = $writer->get_user_preferences('message_email');
$this->assertNotEmpty($preferences->email);
$this->assertEquals('alternate@example.com', $preferences->email->value);
$this->assertEquals(get_string('privacy:preference:email', 'message_email'), $preferences->email->description);
}
}
@@ -5,61 +5,41 @@ Feature: Notification popover unread notifications
I am notified about relevant events in Moodle
Background:
# This will make sure popup notifications are enabled and create
# two assignment notifications. One for the student submitting their
# assignment and another for the teacher grading it.
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
# Make sure the popup notifications are enabled for assignments.
And the following config values are set as admin:
| popup_provider_mod_assign_assign_notification_permitted | permitted | message |
| message_provider_mod_assign_assign_notification_loggedin | popup | message |
| message_provider_mod_assign_assign_notification_loggedoff | popup | message |
And the following "users" exist:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment name |
| assignsubmission_onlinetext_enabled | 1 |
| assignsubmission_file_enabled | 0 |
| submissiondrafts | 0 |
# This should generate a notification.
And the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name | student1 | I'm the student1 submission |
| student2 | Student | 2 | student2@example.com |
# This should generate some notifications
And the following "notifications" exist:
| subject | userfrom | userto | timecreated | timeread |
| Test 01 | student2 | student1 | 1654587996 | null |
| Test 02 | student2 | student1 | 1654587997 | null |
Scenario: Notification popover shows correct unread count
When I log in as "student1"
Given I log in as "student1"
# Confirm the popover is saying 1 unread notifications.
Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
And I should see "2" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
# Open the popover.
And I open the notification popover
# Confirm the submission notification is visible.
And I should see "You have submitted your assignment submission for Test assignment name" in the "#nav-notification-popover-container" "css_element"
When I open the notification popover
# Confirm the notifications are visible.
Then I should see "Test 01" in the "#nav-notification-popover-container" "css_element"
And I should see "Test 02" in the "#nav-notification-popover-container" "css_element"
@_bug_phantomjs
Scenario: Clicking a notification marks it as read
When I log in as "student1"
# Open the popover.
Given I log in as "student1"
# Open the notifications.
When I open the notification popover
And I follow "Test 01"
And I open the notification popover
# Click on the submission notification.
And I follow "You have submitted your assignment submission for Test assignment name"
And I follow "Test 02"
# Confirm the count element is hidden (i.e. there are no unread notifications).
Then "[data-region='count-container']" "css_element" in the "#nav-notification-popover-container" "css_element" should not be visible
Scenario: Mark all notifications as read
When I log in as "student1"
# Open the popover.
And I open the notification popover
# Click the mark all as read button.
Given I log in as "student1"
When I open the notification popover
And I click on "Mark all as read" "link" in the "#nav-notification-popover-container" "css_element"
# Refresh the page to make sure we send a new request for the unread count.
And I reload the page
+1 -1
View File
@@ -632,7 +632,7 @@ class pdf extends TcpdfFpdi {
$gsexec = \escapeshellarg($CFG->pathtogs);
$tempdstarg = \escapeshellarg($tempdst);
$tempsrcarg = \escapeshellarg($tempsrc);
$command = "$gsexec -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile=$tempdstarg $tempsrcarg";
$command = "$gsexec -q -sDEVICE=pdfwrite -dSAFER -dBATCH -dNOPAUSE -sOutputFile=$tempdstarg $tempsrcarg";
exec($command);
if (!file_exists($tempdst)) {
// Something has gone wrong in the conversion.
+1 -1
View File
@@ -164,7 +164,7 @@ class mod_assign_renderer extends plugin_renderer_base {
$fullname = fullname($summary->user, $summary->viewfullnames);
$extrainfo = array();
foreach ($summary->extrauserfields as $extrafield) {
$extrainfo[] = $summary->user->$extrafield;
$extrainfo[] = s($summary->user->$extrafield);
}
if (count($extrainfo)) {
$fullname .= ' (' . implode(', ', $extrainfo) . ')';
+17 -22
View File
@@ -24,32 +24,27 @@ Feature: Users can view and search database entries
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Test database name | Database intro | C1 | data1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I add a "Text input" field to "Test database name" database and I fill the form with:
| Field name | Test field name |
| Field description | Test field description |
And I add a "Text input" field to "Test database name" database and I fill the form with:
| Field name | Test field 2 name |
| Field description | Test field 2 description |
# To generate the default templates.
And I follow "Templates"
And I log out
And the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Test field name | Test field description |
| data1 | text | Test field 2 name | Test field 2 description |
And the following "mod_data > templates" exist:
| database | name |
| data1 | singletemplate |
| data1 | listtemplate |
| data1 | addtemplate |
| data1 | asearchtemplate |
| data1 | rsstemplate |
Scenario: Students can add view, list and search entries
Given I log in as "student1"
Given the following "mod_data > entries" exist:
| database | Test field name | Test field 2 name |
| data1 | Student entry 1 | |
| data1 | Student entry 2 | |
| data1 | Student entry 3 | |
When I log in as "student1"
And I am on "Course 1" course homepage
And I follow "Test database name"
And I add an entry to "Test database name" database with:
| Test field name | Student entry 1 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
| Test field name | Student entry 2 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
| Test field name | Student entry 3 |
And I press "Save and view"
And I follow "Test database name"
Then I should see "Student entry 1"
And I should see "Student entry 2"
And I should see "Student entry 3"
@@ -0,0 +1,136 @@
<?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/>.
/**
* Behat data generator for mod_data.
*
* @package mod_data
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_mod_data_generator extends behat_generator_base {
/**
* Get a list of the entities that Behat can create using the generator step.
*
* @return array
*/
protected function get_creatable_entities(): array {
return [
'entries' => [
'singular' => 'entry',
'datagenerator' => 'entry',
'required' => ['database'],
'switchids' => ['database' => 'databaseid'],
],
'fields' => [
'singular' => 'field',
'datagenerator' => 'field',
'required' => ['database', 'type', 'name'],
'switchids' => ['database' => 'databaseid'],
],
'templates' => [
'singular' => 'template',
'datagenerator' => 'template',
'required' => ['database', 'name'],
'switchids' => ['database' => 'databaseid'],
],
];
}
/**
* Get the database id using an activity idnumber.
*
* @param string $idnumber
* @return int The database id
*/
protected function get_database_id(string $idnumber): int {
$cm = $this->get_cm_by_activity_name('data', $idnumber);
return $cm->instance;
}
/**
* Add an entry.
*
* @param array $data Entry data.
*/
public function process_entry(array $data): void {
global $DB;
$database = $DB->get_record('data', ['id' => $data['databaseid']], '*', MUST_EXIST);
unset($data['databaseid']);
$data = array_reduce(array_keys($data), function ($fields, $fieldname) use ($data, $database) {
global $DB;
$field = $DB->get_record('data_fields', ['name' => $fieldname, 'dataid' => $database->id], 'id', MUST_EXIST);
$fields[$field->id] = $data[$fieldname];
return $fields;
}, []);
$this->get_data_generator()->create_entry($database, $data);
}
/**
* Add a field.
*
* @param array $data Field data.
*/
public function process_field(array $data): void {
global $DB;
$database = $DB->get_record('data', ['id' => $data['databaseid']], '*', MUST_EXIST);
unset($data['databaseid']);
$this->get_data_generator()->create_field((object) $data, $database);
}
/**
* Add a template.
*
* @param array $data Template data.
*/
public function process_template(array $data): void {
global $DB;
$database = $DB->get_record('data', ['id' => $data['databaseid']], '*', MUST_EXIST);
if (empty($data['content'])) {
data_generate_default_template($database, $data['name']);
} else {
$newdata = new stdClass();
$newdata->id = $database->id;
$newdata->{$data['name']} = $data['content'];
$DB->update_record('data', $newdata);
}
}
/**
* Get the module data generator.
*
* @return mod_data_generator Database data generator.
*/
protected function get_data_generator(): mod_data_generator {
return $this->componentdatagenerator;
}
}
@@ -42,15 +42,36 @@ Feature: Posting to all groups in a separate group discussion is restricted to u
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| forum | Standard forum name | Standard forum description | C1 | sepgroups | 1 |
And the following "mod_forum > discussions" exist:
| forum | name | subject | message | group |
| sepgroups | Initial Disc ALL | Initial Disc ALL | Disc ALL content | All participants |
| sepgroups | Initial Disc G1 | Initial Disc G1 | Disc G1 content | G1 |
| sepgroups | Initial Disc G2 | Initial Disc G2 | Disc G2 content | G2 |
| sepgroups | Initial Disc G3 | Initial Disc G3 | Disc G3 content | G3 |
Scenario: Teacher with accessallgroups can view all groups
Given I log in as "teacher1"
And I am on "Course 1" course homepage
When I follow "Standard forum name"
Then the "Separate groups" select box should contain "All participants"
Then the "Separate groups" select box should contain "Group A"
Then the "Separate groups" select box should contain "Group B"
Then the "Separate groups" select box should contain "Group C"
And the "Separate groups" select box should contain "Group A"
And the "Separate groups" select box should contain "Group B"
And the "Separate groups" select box should contain "Group C"
And I select "All participants" from the "Separate groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
And I should see "Initial Disc G2"
And I should see "Initial Disc G2"
And I select "Group A" from the "Separate groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
But I should not see "Initial Disc G2"
And I should not see "Initial Disc G3"
And I select "Group B" from the "Separate groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G2"
But I should not see "Initial Disc G1"
And I should not see "Initial Disc G3"
Scenario: Teacher with accessallgroups can select any group when posting
Given I log in as "teacher1"
@@ -249,14 +270,7 @@ Feature: Posting to all groups in a separate group discussion is restricted to u
And I should see "Post a copy to all groups"
Scenario: Students can view all participants discussions in separate groups mode
Given I log in as "teacher1"
Given I log in as "student1"
And I am on "Course 1" course homepage
When I add a new discussion to "Standard forum name" forum with:
| Subject | Forum post to all participants |
| Message | This is the body |
| Group | All participants |
And I log out
And I log in as "student1"
And I am on "Course 1" course homepage
And I follow "Standard forum name"
Then I should see "Forum post to all participants"
When I follow "Standard forum name"
Then I should see "Initial Disc ALL"
@@ -33,15 +33,36 @@ Feature: Posting to all groups in a visible group discussion is restricted to us
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| forum | Standard forum name | Standard forum description | C1 | groups | 2 |
And the following "mod_forum > discussions" exist:
| forum | name | subject | message | group |
| groups | Initial Disc ALL | Initial Disc ALL | Disc ALL content | All participants |
| groups | Initial Disc G1 | Initial Disc G1 | Disc G1 content | G1 |
| groups | Initial Disc G2 | Initial Disc G2 | Disc G2 content | G2 |
| groups | Initial Disc G3 | Initial Disc G3 | Disc G3 content | G3 |
Scenario: Teacher with accessallgroups can view all groups
Given I log in as "teacher1"
And I am on "Course 1" course homepage
When I follow "Standard forum name"
Then the "Visible groups" select box should contain "All participants"
Then the "Visible groups" select box should contain "Group A"
Then the "Visible groups" select box should contain "Group B"
Then the "Visible groups" select box should contain "Group C"
And the "Visible groups" select box should contain "Group A"
And the "Visible groups" select box should contain "Group B"
And the "Visible groups" select box should contain "Group C"
And I select "All participants" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
And I should see "Initial Disc G2"
And I should see "Initial Disc G2"
And I select "Group A" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
But I should not see "Initial Disc G2"
And I should not see "Initial Disc G3"
And I select "Group B" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G2"
But I should not see "Initial Disc G1"
And I should not see "Initial Disc G3"
Scenario: Teacher with accessallgroups can select any group when posting
Given I log in as "teacher1"
@@ -150,9 +171,24 @@ Feature: Posting to all groups in a visible group discussion is restricted to us
And I am on "Course 1" course homepage
When I follow "Standard forum name"
Then the "Visible groups" select box should contain "All participants"
Then the "Visible groups" select box should contain "Group A"
Then the "Visible groups" select box should contain "Group B"
Then the "Visible groups" select box should contain "Group C"
And the "Visible groups" select box should contain "Group A"
And the "Visible groups" select box should contain "Group B"
And the "Visible groups" select box should contain "Group C"
And I select "All participants" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
And I should see "Initial Disc G2"
And I should see "Initial Disc G2"
And I select "Group A" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G1"
But I should not see "Initial Disc G2"
And I should not see "Initial Disc G3"
And I select "Group B" from the "Visible groups" singleselect
And I should see "Initial Disc ALL"
And I should see "Initial Disc G2"
But I should not see "Initial Disc G1"
And I should not see "Initial Disc G3"
Scenario: Students in one group can only post in their group
Given I log in as "student1"
@@ -35,7 +35,7 @@ class behat_mod_forum_generator extends behat_generator_base {
'singular' => 'discussion',
'datagenerator' => 'discussion',
'required' => ['forum'],
'switchids' => ['forum' => 'forumid', 'user' => 'userid'],
'switchids' => ['forum' => 'forumid', 'user' => 'userid', 'group' => 'groupid'],
],
'posts' => [
'singular' => 'post',
@@ -62,6 +62,21 @@ class behat_mod_forum_generator extends behat_generator_base {
return $id;
}
/**
* Gets the group id from it's idnumber. It allows using 'All participants' as idnumber.
*
* @throws Exception
* @param string $idnumber
* @return int
*/
protected function get_group_id($idnumber): int {
if ($idnumber === 'All participants') {
return -1;
}
return parent::get_group_id($idnumber);
}
/**
* Preprocess discussion data.
*
+5 -11
View File
@@ -5,7 +5,6 @@ Feature: set label idnumber
As a teacher
I should create label activity and set an ID number
@javascript
Scenario: label ID number input box should be shown.
Given the following "courses" exist:
| fullname | shortname | category |
@@ -18,12 +17,11 @@ Feature: set label idnumber
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
Given I log in as "teacher"
And the following "activities" exist:
| activity | course | section | intro | idnumber |
| label | C1 | 1 | Label with ID number set | C1LABEL1 |
When I log in as "teacher"
And I am on "Test" course homepage with editing mode on
When I add a "label" to section "1" and I fill the form with:
| Label text | Label with ID number set |
| Availability | Show on course page |
| ID number | C1LABEL1 |
Then "Label with ID number set" activity should be visible
And I turn editing mode off
And "Label with ID number set" activity should be visible
@@ -32,11 +30,7 @@ Feature: set label idnumber
And I am on "Test" course homepage
And I should see "Label with ID number set"
And I log out
And I log in as "teacher"
And I am on "Test" course homepage
And I turn editing mode on
And I open "Label with ID number set" actions menu
And I click on "Edit settings" "link" in the "Label with ID number set" activity
And I am on the "Label with ID number set" "label activity editing" page logged in as teacher
And I expand all fieldsets
And I should see "ID number" in the "Common module settings" "fieldset"
And the field "ID number" matches value "C1LABEL1"
+13 -40
View File
@@ -5,8 +5,7 @@ Feature: Check label visibility works
As a teacher
I should create label activity
@javascript
Scenario: Hidden label activity should be show as hidden.
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Test | C1 | 0 |
@@ -18,38 +17,26 @@ Feature: Check label visibility works
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
And the following "activities" exist:
| activity | course | section | intro | idnumber | visible |
| label | C1 | 1 | Swanky label | 1 | 1 |
| label | C1 | 1 | Swanky label 2 | 2 | 0 |
Scenario: Hidden label activity should be show as hidden.
Given I log in as "teacher"
And I am on "Test" course homepage with editing mode on
When I add a "label" to section "1" and I fill the form with:
| Label text | Swanky label |
| Availability | Hide from students |
Then "Swanky label" activity should be hidden
When I am on "Test" course homepage with editing mode on
Then "Swanky label 2" activity should be hidden
And I turn editing mode off
And "Swanky label" activity should be hidden
Then "Swanky label 2" activity should be hidden
And I log out
And I log in as "student"
And I am on "Test" course homepage
And I should not see "Swanky label"
And I should not see "Swanky label 2"
And I log out
@javascript
Scenario: Visible label activity should be shown as visible.
Given the following "courses" exist:
| fullname | shortname | category |
| Test | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher | Teacher | Frist | teacher1@example.com |
| student | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
Given I log in as "teacher"
And I am on "Test" course homepage with editing mode on
When I add a "label" to section "1" and I fill the form with:
| Label text | Swanky label |
| Availability | Show on course page |
When I am on "Test" course homepage with editing mode on
Then "Swanky label" activity should be visible
And I log out
And I log in as "student"
@@ -59,23 +46,9 @@ Feature: Check label visibility works
@javascript
Scenario: Teacher can not show label inside the hidden section
Given the following "courses" exist:
| fullname | shortname | category |
| Test | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher | Teacher | Frist | teacher1@example.com |
| student | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
Given I log in as "teacher"
And I am on "Test" course homepage with editing mode on
When I add a "label" to section "1" and I fill the form with:
| Label text | Swanky label |
| Availability | Show on course page |
And I hide section "1"
When I hide section "1"
Then "Swanky label" activity should be dimmed
And I open "Swanky label" actions menu
And "Swanky label" actions menu should not have "Show" item
@@ -56,7 +56,7 @@ class repost_crosssite_page implements renderable, templatable {
*/
public function __construct(string $url, array $post) {
$this->params = array_map(function($k) use ($post) {
return ["key" => $k, "value" => str_replace("\"", "&quot;", $post[$k])];
return ["key" => $k, "value" => $post[$k]];
}, array_keys($post));
$this->url = $url;
}
+2 -2
View File
@@ -37,9 +37,9 @@
}
}}
<form action="{{{url}}}" method="POST" id="autopostme">
<form action="{{url}}" method="POST" id="autopostme">
{{#params}}
<input type="hidden" name="{{{key}}}" value="{{{value}}}">
<input type="hidden" name="{{key}}" value="{{value}}">
{{/params}}
<input type="hidden" name="repost" value="true">
</form>
@@ -5,12 +5,12 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And I log in as "admin"
And I am on "Course 1" course homepage
And I turn editing mode on
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Quiz 1 |
Scenario: Quiz setting "Require the use of Safe Exam Browser" has all types, except "Use an existing template".
When I add a "Quiz" to section "1"
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And the "Require the use of Safe Exam Browser" select box should contain "Yes Configure manually"
And the "Require the use of Safe Exam Browser" select box should not contain "Yes Use an existing template"
@@ -22,7 +22,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And the "Require the use of Safe Exam Browser" select box should contain "Yes Configure manually"
And the "Require the use of Safe Exam Browser" select box should contain "Yes Use an existing template"
@@ -34,7 +34,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "No"
Then I should not see "Upload Safe Exam Browser config file"
@@ -66,7 +66,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "Yes Use SEB client config"
Then I should see "Show Safe Exam Browser download button"
@@ -98,7 +98,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "Yes Upload my own config"
Then I should see "Upload Safe Exam Browser config file"
@@ -130,7 +130,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "Yes Use an existing template"
Then I should see "Safe Exam Browser config template"
@@ -164,7 +164,7 @@ Feature: Safe Exam Browser settings in quiz edit form
Given the following "quizaccess_seb > seb templates" exist:
| name |
| Template 1 |
When I add a "Quiz" to section "1"
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "Yes Configure manually"
Then I should see "Show Safe Exam Browser download button"
@@ -18,39 +18,39 @@ Feature: Settings form fields disabled if not required
| teacher | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "teacher"
And I am on "Course 1" course homepage with editing mode on
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Test quiz 1 |
@javascript
Scenario: Depending on the number of attempts, different form fields are disabled.
When I add a "Quiz" to section "1"
When I am on the "Test quiz 1" "quiz activity editing" page logged in as teacher
And I expand all fieldsets
And I set the field "Name" to "Test quiz"
And I set the field "Attempts allowed" to "1"
Then the "Grading method" "field" should be disabled
And the "Each attempt builds on the last" "field" should be disabled
And the "id_delay1_enabled" "field" should be disabled
And the "id_delay2_enabled" "field" should be disabled
When I set the field "Attempts allowed" to "2"
Then the "Grading method" "field" should be enabled
And I set the field "Attempts allowed" to "2"
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
And the "id_delay1_enabled" "field" should be enabled
And the "id_delay2_enabled" "field" should be disabled
When I set the field "Attempts allowed" to "3"
Then the "Grading method" "field" should be enabled
And I set the field "Attempts allowed" to "3"
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
And the "id_delay1_enabled" "field" should be enabled
And the "id_delay2_enabled" "field" should be enabled
When I set the field "Attempts allowed" to "Unlimited"
Then the "Grading method" "field" should be enabled
And I set the field "Attempts allowed" to "Unlimited"
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
# And the "id_delay1_enabled" "field" should be enabled
# And the "id_delay2_enabled" "field" should be enabled
When I press "Save and display"
And I press "Save and display"
And I navigate to "User overrides" in current page administration
And I press "Add user override"
And I set the following fields to these values:
@@ -61,12 +61,12 @@ Feature: Settings form fields disabled if not required
And I navigate to "Edit settings" in current page administration
And I expand all fieldsets
And I set the field "Attempts allowed" to "1"
Then the "Grading method" "field" should be enabled
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
And the "id_delay1_enabled" "field" should be enabled
And the "id_delay2_enabled" "field" should be enabled
When I press "Save and display"
And I press "Save and display"
And I navigate to "User overrides" in current page administration
And I click on "Edit" "link" in the "region-main" "region"
And I set the field "Attempts allowed" to "2"
@@ -75,12 +75,12 @@ Feature: Settings form fields disabled if not required
And I navigate to "Edit settings" in current page administration
And I expand all fieldsets
And I set the field "Attempts allowed" to "1"
Then the "Grading method" "field" should be enabled
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
And the "id_delay1_enabled" "field" should be enabled
And the "id_delay2_enabled" "field" should be disabled
When I press "Save and display"
And I press "Save and display"
And I navigate to "User overrides" in current page administration
And I press "Add user override"
And I set the following fields to these values:
@@ -91,28 +91,31 @@ Feature: Settings form fields disabled if not required
And I navigate to "Edit settings" in current page administration
And I expand all fieldsets
And I set the field "Attempts allowed" to "1"
Then the "Grading method" "field" should be enabled
And the "Grading method" "field" should be enabled
And the "Each attempt builds on the last" "field" should be enabled
And the "id_delay1_enabled" "field" should be enabled
And the "id_delay2_enabled" "field" should be enabled
@javascript
Scenario: Depending on whether there is a close date, some review options are disabled.
When I add a "Quiz" to section "1"
When I log in as "teacher"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1"
And I expand all fieldsets
And I set the field "Name" to "Test quiz"
Then the "id_attemptclosed" "checkbox" should be disabled
Then the "id_correctnessclosed" "checkbox" should be disabled
Then the "id_marksclosed" "checkbox" should be disabled
Then the "id_specificfeedbackclosed" "checkbox" should be disabled
Then the "id_generalfeedbackclosed" "checkbox" should be disabled
Then the "id_rightanswerclosed" "checkbox" should be disabled
Then the "id_overallfeedbackclosed" "checkbox" should be disabled
And the "id_correctnessclosed" "checkbox" should be disabled
And the "id_marksclosed" "checkbox" should be disabled
And the "id_specificfeedbackclosed" "checkbox" should be disabled
And the "id_generalfeedbackclosed" "checkbox" should be disabled
And the "id_rightanswerclosed" "checkbox" should be disabled
And the "id_overallfeedbackclosed" "checkbox" should be disabled
And I set the field "id_timeclose_enabled" to "1"
Then the "id_attemptclosed" "checkbox" should be enabled
Then the "id_correctnessclosed" "checkbox" should be enabled
Then the "id_marksclosed" "checkbox" should be enabled
Then the "id_specificfeedbackclosed" "checkbox" should be enabled
Then the "id_generalfeedbackclosed" "checkbox" should be enabled
Then the "id_rightanswerclosed" "checkbox" should be enabled
Then the "id_overallfeedbackclosed" "checkbox" should be enabled
And the "id_attemptclosed" "checkbox" should be enabled
And the "id_correctnessclosed" "checkbox" should be enabled
And the "id_marksclosed" "checkbox" should be enabled
And the "id_specificfeedbackclosed" "checkbox" should be enabled
And the "id_generalfeedbackclosed" "checkbox" should be enabled
And the "id_rightanswerclosed" "checkbox" should be enabled
And the "id_overallfeedbackclosed" "checkbox" should be enabled
And I should not see "Repaginate now"
+6 -4
View File
@@ -39,7 +39,8 @@ class mod_resource_generator extends testing_module_generator {
* text file.
*
* @param array|stdClass $record data for module being generated. Requires 'course' key
* (an id or the full object). Also can have any fields from add module form.
* (an id or the full object). Also can have any fields from add module form, and a
* 'defaultfilename' to set the name of the file created if no draft ID is supplied.
* @param null|array $options general options for course module. Since 2.6 it is
* possible to omit this argument by merging options into $record
* @return stdClass record from module-defined table with additional field
@@ -72,16 +73,17 @@ class mod_resource_generator extends testing_module_generator {
throw new coding_exception('resource generator requires a current user');
}
$usercontext = context_user::instance($USER->id);
$filename = $record->defaultfilename ?? 'resource' . ($this->instancecount + 1) . '.txt';
// Pick a random context id for specified user.
$record->files = file_get_unused_draft_itemid();
// Add actual file there.
$filerecord = array('component' => 'user', 'filearea' => 'draft',
$filerecord = ['component' => 'user', 'filearea' => 'draft',
'contextid' => $usercontext->id, 'itemid' => $record->files,
'filename' => 'resource' . ($this->instancecount+1) . '.txt', 'filepath' => '/');
'filename' => $filename, 'filepath' => '/'];
$fs = get_file_storage();
$fs->create_file_from_string($filerecord, 'Test resource ' . ($this->instancecount+1) . ' file');
$fs->create_file_from_string($filerecord, 'Test resource ' . $filename . ' file');
}
// Do work to actually add the instance.
+16 -1
View File
@@ -70,6 +70,21 @@ class mod_resource_generator_testcase extends advanced_testcase {
// Check that generated resource module contains a file.
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_resource', 'content', false, '', false);
$this->assertEquals(1, count($files));
$file = array_values($files)[0];
$this->assertCount(1, $files);
$this->assertEquals('resource3.txt', $file->get_filename());
$this->assertEquals('Test resource resource3.txt file', $file->get_content());
// Create a new resource specifying the file name.
$resource = $generator->create_instance(['course' => $SITE->id, 'defaultfilename' => 'myfile.pdf']);
// Check that generated resource module contains a file with the specified name.
$cm = get_coursemodule_from_instance('resource', $resource->id);
$context = \context_module::instance($cm->id);
$files = $fs->get_area_files($context->id, 'mod_resource', 'content', false, '', false);
$file = array_values($files)[0];
$this->assertCount(1, $files);
$this->assertEquals('myfile.pdf', $file->get_filename());
$this->assertEquals('Test resource myfile.pdf file', $file->get_content());
}
}
+1 -1
View File
@@ -496,7 +496,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) {
$report .= html_writer::start_tag('li').html_writer::start_tag('ul', array('class' => $liststyle));
foreach ($usertrack as $element => $value) {
if (substr($element, 0, 3) == 'cmi') {
$report .= html_writer::tag('li', $element.' => '.s($value));
$report .= html_writer::tag('li', s($element) . ' => ' . s($value));
}
}
$report .= html_writer::end_tag('ul').html_writer::end_tag('li');
+2 -2
View File
@@ -144,9 +144,9 @@ foreach ($trackdata as $element => $value) {
}
if (empty($string) || $table->is_downloading()) {
$row[] = $element;
$row[] = s($element);
} else {
$row[] = $element.$OUTPUT->help_icon($string, 'scorm');
$row[] = s($element) . $OUTPUT->help_icon($string, 'scorm');
}
if (strpos($element, '_time') === false) {
$row[] = s($value);
+2 -1
View File
@@ -152,7 +152,8 @@ class qformat_blackboard_six extends qformat_blackboard_six_base {
}
if ($examfile->getAttribute('type') == 'assessment/x-bb-pool') {
if ($examfile->getAttribute('baseurl')) {
$fileobj->filebase = $this->tempdir. '/' . $examfile->getAttribute('baseurl');
$fileobj->filebase = clean_param($this->tempdir . '/'
. $examfile->getAttribute('baseurl'), PARAM_SAFEPATH);
}
if ($content = $this->get_filecontent($examfile->getAttribute('file'))) {
$fileobj->filetype = self::FILETYPE_POOL;
@@ -0,0 +1,120 @@
<?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/>.
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/behat_question_base.php');
use Behat\Gherkin\Node\TableNode as TableNode;
use Behat\Mink\Exception\ExpectationException as ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
/**
* Behat navigation hooks for core_question.
*
* @package core_question
* @category test
* @copyright 2022 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_core_question extends behat_question_base {
/**
* Convert page names to URLs for steps like 'When I am on the "[page name]" page'.
*
* Recognised page names are:
* | None so far! | |
*
* @param string $page name of the page, with the component name removed e.g. 'Admin notification'.
* @return moodle_url the corresponding URL.
* @throws Exception with a meaningful error message if the specified page cannot be found.
*/
protected function resolve_page_url(string $page): moodle_url {
switch (strtolower($page)) {
default:
throw new Exception('Unrecognised core_question page type "' . $page . '."');
}
}
/**
* Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'.
*
* Recognised page names are:
* | pagetype | name meaning | description |
* | course question bank | Course name | The question bank for a course |
* | course question import | Course name | The import questions screen for a course |
* | course question export | Course name | The export questions screen for a course |
* | preview | Question name | The screen to preview a question |
* | edit | Question name | The screen to edit a question |
*
* @param string $type identifies which type of page this is, e.g. 'Preview'.
* @param string $identifier identifies the particular page, e.g. 'My question'.
* @return moodle_url the corresponding URL.
* @throws Exception with a meaningful error message if the specified page cannot be found.
*/
protected function resolve_page_instance_url(string $type, string $identifier): moodle_url {
switch (strtolower($type)) {
case 'course question bank':
return new moodle_url('/question/edit.php',
['courseid' => $this->get_course_id($identifier)]);
case 'course question import':
return new moodle_url('/question/import.php',
['courseid' => $this->get_course_id($identifier)]);
case 'course question export':
return new moodle_url('/question/export.php',
['courseid' => $this->get_course_id($identifier)]);
case 'preview':
[$questionid, $otheridtype, $otherid] = $this->find_question_by_name($identifier);
return new moodle_url('/question/preview.php',
['id' => $questionid, $otheridtype => $otherid]);
case 'edit':
[$questionid, $otheridtype, $otherid] = $this->find_question_by_name($identifier);
return new moodle_url('/question/question.php',
['id' => $questionid, $otheridtype => $otherid]);
default:
throw new Exception('Unrecognised core_question page type "' . $type . '."');
}
}
/**
* Find a question, and where it is, from the question name.
*
* This is a helper used by resolve_page_instance_url.
*
* @param string $questionname
* @return array with three elemnets, int question id, a string 'cmid' or 'courseid',
* and int either cmid or courseid as applicable.
*/
protected function find_question_by_name(string $questionname): array {
global $DB;
$questionid = $DB->get_field('question', 'id', ['name' => $questionname], MUST_EXIST);
$question = question_bank::load_question_data($questionid);
$context = context_helper::instance_by_id($question->contextid);
if ($context->contextlevel == CONTEXT_MODULE) {
return [$questionid, 'cmid', $context->instanceid];
} else if ($context->contextlevel == CONTEXT_COURSE) {
return [$questionid, 'courseid', $context->instanceid];
} else {
throw new coding_exception('Unsupported context level ' . $context->contextlevel);
}
}
}
@@ -6,21 +6,19 @@ Feature: Test creating a drag and drop onto image question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: Create a drag and drop onto image question
When I press "Create a new question ..."
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I press "Create a new question ..."
And I set the field "Drag and drop onto image" to "1"
And I click on "Add" "button" in the "Choose a question type to add" "dialogue"
And I set the field "Question name" to "Drag and drop onto image 001"
@@ -19,16 +19,16 @@ Feature: Test duplicating a quiz containing a drag and drop onto image question
| quiz | Test quiz | C1 | quiz1 |
And quiz "Test quiz" contains the following questions:
| Drag onto image | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing a drag and drop onto image question
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
And I choose "Edit question" action for "Drag onto image" in the question bank
Then the following fields match these values:
| Question name | Drag onto image |
@@ -6,27 +6,24 @@ Feature: Test editing a drag and drop onto image questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddimageortext | Drag onto image | xsection |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript
Scenario: Edit a drag and drop onto image question
And I choose "Edit question" action for "Drag onto image" in the question bank
When I am on the "Drag onto image" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | Edited question name |
And I press "id_submitbutton"
@@ -6,30 +6,27 @@ Feature: Test exporting drag and drop onto image questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddimageortext | Drag onto image | xsection |
And I log in as "teacher1"
And I am on "Course 1" course homepage
@javascript
Scenario: Export a drag and drop onto image question
# Import sample file.
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "18600" and "19150" bytes
Then following "click here" should download between "18600" and "19150" bytes
# If the download step is the last in the scenario then we can sometimes run
# into the situation where the download page causes a http redirect but behat
# has already conducted its reset (generating an error). By putting a logout
@@ -6,20 +6,18 @@ Feature: Test importing drag and drop onto image questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import drag and drop onto image question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddimageortext/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -6,31 +6,24 @@ Feature: Preview a drag-drop onto image question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddimageortext | Drag onto image | xsection |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_bug_phantomjs
Scenario: Preview a question using the mouse.
When I choose "Preview" action for "Drag onto image" in the question bank
And I switch to "questionpreview" window
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
# Keep window large else drag will scroll the window to find element.
And I change window size to "medium"
When I am on the "Drag onto image" "core_question > preview" page logged in as teacher
And I wait "2" seconds
# Odd, but the <br>s go to nothing, not a space.
And I drag "mountainbelt" to place "1" in the drag and drop onto image question
@@ -44,12 +37,10 @@ Feature: Preview a drag-drop onto image question
And I press "Submit and finish"
Then the state of "Identify the features" question is shown as "Correct"
And I should see "Mark 1.00 out of 1.00"
And I switch to the main window
@javascript
Scenario: Preview a question using the keyboard.
When I choose "Preview" action for "Drag onto image" in the question bank
And I switch to "questionpreview" window
When I am on the "Drag onto image" "core_question > preview" page logged in as teacher
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
And I change window size to "medium"
And I wait "2" seconds
@@ -64,4 +55,3 @@ Feature: Preview a drag-drop onto image question
And I press "Submit and finish"
Then the state of "Identify the features" question is shown as "Correct"
And I should see "Mark 1.00 out of 1.00"
And I switch to the main window
@@ -6,21 +6,19 @@ Feature: Test creating a drag and drop markers question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: Create a drag and drop markers question
When I press "Create a new question ..."
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I press "Create a new question ..."
And I set the field "Drag and drop markers" to "1"
And I click on "Add" "button" in the "Choose a question type to add" "dialogue"
And I set the field "Question name" to "Drag and drop markers"
@@ -27,7 +27,8 @@ Feature: Test duplicating a quiz containing a drag and drop markers question
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I navigate to "Question bank" in current page administration
And I choose "Edit question" action for "Drag markers" in the question bank
Then the following fields match these values:
@@ -6,27 +6,24 @@ Feature: Test editing a drag and drop markers questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddmarker | Drag markers | mkmap |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript
Scenario: Edit a drag and drop markers question
When I choose "Edit question" action for "Drag markers" in the question bank
When I am on the "Drag markers" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | Edited question name |
And I press "id_submitbutton"
@@ -6,30 +6,27 @@ Feature: Test exporting drag and drop markers questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddmarker | Drag markers | mkmap |
And I log in as "teacher1"
And I am on "Course 1" course homepage
@javascript
Scenario: Export a drag and drop markers question
# Import sample file.
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "233700" and "233950" bytes
Then following "click here" should download between "233700" and "233950" bytes
# If the download step is the last in the scenario then we can sometimes run
# into the situation where the download page causes a http redirect but behat
# has already conducted its reset (generating an error). By putting a logout
@@ -6,20 +6,18 @@ Feature: Test importing drag and drop markers questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import drag and drop markers question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddmarker/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -6,28 +6,24 @@ Feature: Preview a drag-drop marker question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddmarker | Drag markers | mkmap |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_bug_phantomjs
Scenario: Preview a question using the mouse.
When I choose "Preview" action for "Drag markers" in the question bank
And I switch to "questionpreview" window
When I am on the "Drag markers" "core_question > preview" page logged in as teacher
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
# Keep window large else drag will scroll the window to find element.
And I change window size to "large"
@@ -40,19 +36,12 @@ Feature: Preview a drag-drop marker question
And I press "Submit and finish"
Then the state of "Please place the markers on the map of Milton Keynes" question is shown as "Correct"
And I should see "Mark 1.00 out of 1.00"
And I switch to the main window
@javascript
Scenario: Preview a question using the keyboard.
When I choose "Preview" action for "Drag markers" in the question bank
And I switch to "questionpreview" window
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
# Keep window large else drag will scroll the window to find element.
And I change window size to "medium"
And I wait "2" seconds
Scenario: Preview a question using the keyboard
When I am on the "Drag markers" "core_question > preview" page logged in as teacher
And I type "up" "88" times on marker "Railway station" in the drag and drop markers question
And I type "right" "26" times on marker "Railway station" in the drag and drop markers question
And I press "Submit and finish"
Then the state of "Please place the markers on the map of Milton Keynes" question is shown as "Partially correct"
And I should see "Mark 0.25 out of 1.00"
And I switch to the main window
+6 -8
View File
@@ -6,21 +6,19 @@ Feature: Test creating a drag and drop into text question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
@javascript
Scenario: Create a drag and drop into text question
When I add a "Drag and drop into text" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Drag and drop into text" question filling the form with:
| Question name | Drag and drop into text 001 |
| Question text | The [[1]] [[2]] on the [[3]]. |
| General feedback | The cat sat on the mat. |
@@ -19,16 +19,16 @@ Feature: Test duplicating a quiz containing a drag and drop into text question
| quiz | Test quiz | C1 | quiz1 |
And quiz "Test quiz" contains the following questions:
| Drag to text | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing a drag and drop into text question
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
And I choose "Edit question" action for "Drag to text" in the question bank
Then the following fields match these values:
| Question name | Drag to text |
@@ -6,28 +6,25 @@ Feature: Test editing a drag and drop into text questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddwtos | Drag to text | fox |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript
Scenario: Edit a drag and drop into text question
When I choose "Edit question" action for "Drag to text" in the question bank
Then I should see "Choice [[1]]"
When I am on the "Drag to text" "core_question > edit" page logged in as teacher
And I should see "Choice [[1]]"
And I should see "Choice [[2]]"
And I should see "Choice [[3]]"
And I set the following fields to these values:
@@ -6,27 +6,24 @@ Feature: Test exporting drag and drop into text questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddwtos | Drag to text | fox |
And I log in as "teacher1"
And I am on "Course 1" course homepage
@javascript
Scenario: Export a drag and drop into text question
# Import sample file.
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
And following "click here" should download between "1550" and "1700" bytes
@@ -6,20 +6,18 @@ Feature: Test importing drag and drop into text questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import drag and drop into text question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/ddwtos/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -6,14 +6,14 @@ Feature: Preview a drag-drop into text question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -21,75 +21,54 @@ Feature: Preview a drag-drop into text question
| questioncategory | qtype | name | template |
| Test questions | ddwtos | Drag to text | fox |
| Test questions | ddwtos | Drag to text infinite | infinite |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_bug_phantomjs
Scenario: Preview a question using the mouse.
When I choose "Preview" action for "Drag to text" in the question bank
And I switch to "questionpreview" window
# Increase window size and wait 2 seconds to ensure elements are placed properly by js.
# Keep window large else drag will scroll the window to find element.
And I change window size to "medium"
And I wait "2" seconds
When I am on the "Drag to text" "core_question > preview" page logged in as teacher
And I drag "quick" to space "1" in the drag and drop into text question
And I drag "fox" to space "2" in the drag and drop into text question
And I drag "assiduous" to space "3" in the drag and drop into text question
And I press "Submit and finish"
Then the state of "The" question is shown as "Partially correct"
And I should see "Mark 0.67 out of 1.00"
And I switch to the main window
@javascript
Scenario: Preview a question using the keyboard & submit incomplete.
When I choose "Preview" action for "Drag to text" in the question bank
And I switch to "questionpreview" window
When I am on the "Drag to text" "core_question > preview" page logged in as teacher
And I type " " into space "1" in the drag and drop onto image question
And I type " " into space "2" in the drag and drop onto image question
And I type " " into space "3" in the drag and drop onto image question
And I press "Save"
Then the state of "The" question is shown as "Incomplete answer"
And I should see "Please put an answer in each box."
And I switch to the main window
@javascript
Scenario: Preview a question using the keyboard.
When I choose "Preview" action for "Drag to text" in the question bank
And I switch to "questionpreview" window
When I am on the "Drag to text" "core_question > preview" page logged in as teacher
And I type " " into space "1" in the drag and drop onto image question
And I type " " into space "2" in the drag and drop onto image question
And I type " " into space "3" in the drag and drop onto image question
And I press "Submit and finish"
Then the state of "The" question is shown as "Incorrect"
And I should see "Mark 0.00 out of 1.00"
And I switch to the main window
@javascript
Scenario: Preview a question that uses strange group numbers using the keyboard.
Given the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | ddwtos | Funny groups | oddgroups |
And I reload the page
When I choose "Preview" action for "Funny groups" in the question bank
And I switch to "questionpreview" window
When I am on the "Funny groups" "core_question > preview" page logged in as teacher
And I type " " into space "1" in the drag and drop onto image question
And I type " " into space "2" in the drag and drop onto image question
And I type " " into space "3" in the drag and drop onto image question
And I press "Submit and finish"
Then the state of "The" question is shown as "Correct"
And I should see "Mark 1.00 out of 1.00"
And I switch to the main window
@javascript
Scenario: Preview a infinite question.
When I choose "Preview" action for "Drag to text infinite" in the question bank
And I switch to "questionpreview" window
# Increase window size.
# Keep window large else drag will scroll the window to find element.
And I change window size to "medium"
When I am on the "Drag to text infinite" "core_question > preview" page logged in as teacher
And I press "Fill in correct responses"
Then I should see "Option1" in the home area of drag and drop into text question
And I should see "Option2" in the home area of drag and drop into text question
And I should see "Option3" in the home area of drag and drop into text question
And I switch to the main window
@@ -6,20 +6,18 @@ Feature: Test creating a Description question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
Scenario: Create a Description question with Correct answer as False
When I add a "Description" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Description" question filling the form with:
| Question name | description-001 |
| Question text | Instructions about the following questions. |
| General feedback | Why actually the field 'General feedback' used in this qytype? |
@@ -19,16 +19,16 @@ Feature: Test duplicating a quiz containing a Description question
| quiz | Test quiz | C1 | quiz1 |
And quiz "Test quiz" contains the following questions:
| description-001 | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing a Description question
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
And I choose "Edit question" action for "description-001" in the question bank
Then the following fields match these values:
| Question name | description-001 |
@@ -6,26 +6,23 @@ Feature: Test editing a Description question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | description | description-001 | info |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
Scenario: Edit a Description question
When I choose "Edit question" action for "description-001" in the question bank
When I am on the "description-001" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | |
And I press "id_submitbutton"
@@ -6,25 +6,23 @@ Feature: Test exporting Description questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | description | description-001 | info |
And I log in as "teacher1"
And I am on "Course 1" course homepage
Scenario: Export a Description question
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "650" and "900" bytes
@@ -6,20 +6,18 @@ Feature: Test importing Description questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import a Description question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/description/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -6,29 +6,25 @@ Feature: Preview a Description question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | description | description-001 | info |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_switch_window
Scenario: Preview a Description question and submit a correct response.
When I choose "Preview" action for "description-001" in the question bank
And I switch to "questionpreview" window
When I am on the "description-001" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I should see "Here is some information about the questions you are about to attempt."
And I switch to the main window
+8 -9
View File
@@ -6,20 +6,18 @@ Feature: Test creating an Essay question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
Scenario: Create an Essay question with Response format set to 'HTML editor'
When I add a "Essay" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Essay" question filling the form with:
| Question name | essay-001 |
| Question text | Write an essay with 500 words. |
| General feedback | This is general feedback |
@@ -27,7 +25,8 @@ Feature: Test creating an Essay question
Then I should see "essay-001"
Scenario: Create an Essay question with Response format set to 'HTML editor with the file picker'
When I add a "Essay" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Essay" question filling the form with:
| Question name | essay-002 |
| Question text | Write an essay with 500 words. |
| General feedback | This is general feedback |
@@ -23,17 +23,17 @@ Feature: Test duplicating a quiz containing an Assay question
| essay-001 | 1 |
| essay-002 | 1 |
| essay-003 | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing 3 Essay questions
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
And I should see "essay-001"
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
Then I should see "essay-001"
And I should see "essay-002"
And I should see "essay-003"
And I choose "Edit question" action for "essay-001" in the question bank
+10 -12
View File
@@ -6,14 +6,14 @@ Feature: Test editing an Essay question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -22,22 +22,20 @@ Feature: Test editing an Essay question
| Test questions | essay | essay-001 | editor |
| Test questions | essay | essay-002 | editorfilepicker |
| Test questions | essay | essay-003 | plain |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
Scenario: Edit an Essay question
When I choose "Edit question" action for "essay-001" in the question bank
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I choose "Edit question" action for "essay-001" in the question bank
And I set the following fields to these values:
| Question name | |
And I press "id_submitbutton"
Then I should see "You must supply a value here."
When I set the following fields to these values:
And I should see "You must supply a value here."
And I set the following fields to these values:
| Question name | Edited essay-001 name |
| Response format | No online text |
And I press "id_submitbutton"
Then I should see "When \"No online text\" is selected, or responses are optional, you must allow at least one attachment."
When I set the following fields to these values:
And I should see "When \"No online text\" is selected, or responses are optional, you must allow at least one attachment."
And I set the following fields to these values:
| Response format | Plain text |
And I press "id_submitbutton"
Then I should see "Edited essay-001 name"
@@ -6,14 +6,14 @@ Feature: Test exporting Essay questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -22,11 +22,9 @@ Feature: Test exporting Essay questions
| Test questions | essay | essay-001 | editor |
| Test questions | essay | essay-002 | editorfilepicker |
| Test questions | essay | essay-003 | plain |
And I log in as "teacher1"
And I am on "Course 1" course homepage
Scenario: Export 3 Essay questions
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "2600" and "3100" bytes
@@ -1,21 +1,21 @@
@qtype @qtype_essay
Feature: In a essay question, limit submittable file types
In order to constrain student submissions for marking
As a teacher
I need to limit the submittable file types
In order to constrain student submissions for marking
As a teacher
I need to limit the submittable file types
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student0@example.com |
| username |
| teacher |
| student |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -28,18 +28,19 @@ I need to limit the submittable file types
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
Given I am on the "Quiz 1" "mod_quiz > edit" page logged in as teacher1
Given I am on the "Quiz 1" "mod_quiz > edit" page logged in as teacher
And I click on "Edit question TF1" "link"
And I set the field "Allow attachments" to "1"
And I set the field "Response format" to "No online text"
And I set the field "Require attachments" to "1"
And I set the field "filetypeslist[filetypes]" to ".txt"
And I press "Save changes"
And I am on the "Quiz 1" "mod_quiz > edit" page
Then I log out
@javascript @_file_upload
Scenario: Preview an Essay question and submit a response with a correct filetype.
When I log in as "student1"
When I log in as "student"
And I follow "Manage private files"
And I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager
And I press "Save changes"
@@ -57,7 +58,7 @@ I need to limit the submittable file types
@javascript @_file_upload
Scenario: Preview an Essay question and try to submit a response with an incorrect filetype.
When I log in as "student1"
When I log in as "student"
And I follow "Manage private files"
And I upload "lib/tests/fixtures/upload_users.csv" file to "Files" filemanager
And I press "Save changes"
@@ -6,20 +6,18 @@ Feature: Test importing Essay questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import Essay question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/essay/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
+13 -19
View File
@@ -6,14 +6,14 @@ Feature: Preview Essay questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -22,34 +22,28 @@ Feature: Preview Essay questions
| Test questions | essay | essay-001 | editor |
| Test questions | essay | essay-002 | editorfilepicker |
| Test questions | essay | essay-003 | plain |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
When I choose "Preview" action for "essay-001" in the question bank
And I switch to "questionpreview" window
Scenario: Preview an Essay question that uses the HTML editor.
When I am on the "essay-001" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I should see "Please write a story about a frog."
And I switch to the main window
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
When I choose "Preview" action for "essay-002" in the question bank
And I switch to "questionpreview" window
Scenario: Preview an Essay question that uses the HTML editor with embedded files.
When I am on the "essay-002" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I should see "Please write a story about a frog."
And I should see "You can drag and drop files here to add them."
And I switch to the main window
@javascript @_switch_window
Scenario: Preview an Essay question and submit a partially correct response.
When I choose "Preview" action for "essay-003" in the question bank
And I switch to "questionpreview" window
Scenario: Preview an Essay question that uses a plain text area.
When I am on the "essay-003" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I should see "Please write a story about a frog."
And I switch to the main window
@@ -5,20 +5,18 @@ Feature: Test all the basic functionality of this question type
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
@javascript
Scenario: Create, edit then preview a gapselect question.
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
# Create a new question.
And I add a "Select missing words" question filling the form with:
@@ -38,7 +36,7 @@ Feature: Test all the basic functionality of this question type
Then I should see "Select missing words 001"
# Preview it.
When I choose "Preview" action for "Select missing words 001" in the question bank
And I choose "Preview" action for "Select missing words 001" in the question bank
And I switch to "questionpreview" window
# Gaps (drop-down menus) do not have labels. ids and names are generated
@@ -60,7 +58,7 @@ Feature: Test all the basic functionality of this question type
And I set space "2" to "sat" in the select missing words question
And I set space "3" to "mat" in the select missing words question
And I press "Check"
Then I should see "Your answer is correct"
And I should see "Your answer is correct"
And I should see "The cat sat on the mat"
And I should see "The correct answer is: The [cat] [sat] on the [mat]."
And I press "Start again"
@@ -70,19 +68,19 @@ Feature: Test all the basic functionality of this question type
And I set space "2" to "sat" in the select missing words question
And I set space "3" to "dog" in the select missing words question
And I press "Check"
Then I should see "Your answer is partially correct"
And I should see "Your answer is partially correct"
And I should see "First hint"
When I press "Try again"
And I press "Try again"
And I set space "3" to "table" in the select missing words question
And I press "Check"
Then I should see "Your answer is partially correct"
And I should see "Your answer is partially correct"
And I should see "Second hint"
When I press "Try again"
And I press "Try again"
And I set space "3" to "mat" in the select missing words question
And I press "Check"
Then I should see "Your answer is correct"
And I should see "Your answer is correct"
And I should see "The cat sat on the mat"
And I should see "The correct answer is: The [cat] [sat] on the [mat]."
@@ -92,8 +90,8 @@ Feature: Test all the basic functionality of this question type
And I press "Start again with these options"
# Answer question correctly
When I press "Check"
Then I should see "Please put an answer in each box."
And I press "Check"
And I should see "Please put an answer in each box."
And I set space "1" to "cat" in the select missing words question
And I set space "2" to "sat" in the select missing words question
And I set space "3" to "mat" in the select missing words question
@@ -108,7 +106,7 @@ Feature: Test all the basic functionality of this question type
And I set space "2" to "sat" in the select missing words question
And I set space "3" to "cat" in the select missing words question
And I press "Check"
Then I should see "Your answer is partially correct"
And I should see "Your answer is partially correct"
And I should see "You have correctly selected 1."
And I should see "The cat sat on the mat"
And I should see "The correct answer is: The [cat] [sat] on the [mat]."
@@ -119,25 +117,25 @@ Feature: Test all the basic functionality of this question type
And I set space "2" to "ran" in the select missing words question
And I set space "3" to "table" in the select missing words question
And I press "Check"
Then I should see "Your answer is incorrect"
And I should see "Your answer is incorrect"
And I should see "The cat sat on the mat"
And I should see "The correct answer is: The [cat] [sat] on the [mat]."
And I switch to the main window
# Backup the course and restore it.
When I log out
And I log out
And I log in as "admin"
When I backup "Course 1" course using this options:
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
When I restore "test_backup.mbz" backup into a new course using this options:
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
Then I should see "Course 2"
When I navigate to "Question bank" in current page administration
Then I should see "Select missing words 001"
And I should see "Course 2"
And I navigate to "Question bank" in current page administration
And I should see "Select missing words 001"
# Edit the copy and verify the form field contents.
When I choose "Edit question" action for "Select missing words 001" in the question bank
Then the following fields match these values:
And I choose "Edit question" action for "Select missing words 001" in the question bank
And the following fields match these values:
| Question name | Select missing words 001 |
| Question text | The [[1]] [[2]] on the [[3]]. |
| General feedback | The cat sat on the mat. |
@@ -154,4 +152,4 @@ Feature: Test all the basic functionality of this question type
And I set the following fields to these values:
| Question name | Edited question name |
And I press "id_submitbutton"
Then I should see "Edited question name"
And I should see "Edited question name"
@@ -6,21 +6,19 @@ Feature: Import and export select missing words questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: Import and export select missing words questions
# Import sample file.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/gapselect/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
@@ -31,10 +29,10 @@ Feature: Import and export select missing words questions
And I should see "Imported Select missing words 001"
# Now export again.
When I follow "Export"
And I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1650" and "1800" bytes
And following "click here" should download between "1650" and "1800" bytes
# If the download step is the last in the scenario then we can sometimes run
# into the situation where the download page causes a http redirect but behat
# has already conducted its reset (generating an error). By putting a logout
+6 -8
View File
@@ -6,20 +6,18 @@ Feature: Test creating a Matching question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
Scenario: Create a Matching question with 3 subquestions
When I add a "Matching" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Matching" question filling the form with:
| Question name | match-001 |
| Question text | Match the country with the capital city. |
| General feedback | England=London, France=Paris and Spain=Madrid. |
@@ -19,16 +19,16 @@ Feature: Test duplicating a quiz containing a Matching question
| quiz | Test quiz | C1 | quiz1 |
And quiz "Test quiz" contains the following questions:
| matching-001 | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing a Matching question
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
And I choose "Edit question" action for "matching-001" in the question bank
Then the following fields match these values:
| Question name | matching-001 |
+11 -14
View File
@@ -6,45 +6,42 @@ Feature: Test editing a Matching question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | match | Matching for editing | foursubq |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
@javascript @_switch_window
Scenario: Edit a Matching question
When I choose "Edit question" action for "Matching for editing" in the question bank
When I am on the "Matching for editing" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | |
And I press "id_submitbutton"
Then I should see "You must supply a value here."
When I set the following fields to these values:
And I should see "You must supply a value here."
And I set the following fields to these values:
| Question name | Edited Matching name |
And I press "id_submitbutton"
Then I should see "Edited Matching name"
When I choose "Edit question" action for "Edited Matching name" in the question bank
And I should see "Edited Matching name"
And I choose "Edit question" action for "Edited Matching name" in the question bank
And I set the following fields to these values:
| Shuffle | 0 |
| Question 2 | dog |
| Question 4 | fly |
And I press "id_submitbutton"
Then I should see "Edited Matching name"
When I choose "Preview" action for "Edited Matching name" in the question bank
And I choose "Preview" action for "Edited Matching name" in the question bank
And I switch to "questionpreview" window
Then I should see "frog"
And I should see "frog"
And I should see "dog"
And I should see "newt"
And I should see "fly"
@@ -6,25 +6,23 @@ Feature: Test exporting Matching questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | match | matching-001 | foursubq |
And I log in as "teacher1"
And I am on "Course 1" course homepage
Scenario: Export a Matching question
When I navigate to "Question bank > Export" in current page administration
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "1600" and "1750" bytes
@@ -6,20 +6,18 @@ Feature: Test importing Matching questions
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
| user | course | role |
| teacher | C1 | editingteacher |
@javascript @_file_upload
Scenario: import Matching question.
When I navigate to "Question bank > Import" in current page administration
When I am on the "Course 1" "core_question > course question import" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I upload "question/type/match/tests/fixtures/testquestion.moodle.xml" file to "Import" filemanager
And I press "id_submitbutton"
+21 -39
View File
@@ -6,74 +6,56 @@ Feature: Preview a Matching question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | match | matching-001 | foursubq |
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| questioncategory | qtype | name | template | shuffleanswers |
| Test questions | match | matching-001 | foursubq | 0 |
@javascript @_switch_window
Scenario: Preview a Matching question and submit a correct response.
When I choose "Edit question" action for "matching-001" in the question bank
And I set the following fields to these values:
| Shuffle | 0 |
And I press "id_submitbutton"
When I choose "Preview" action for "matching-001" in the question bank
And I switch to "questionpreview" window
When I am on the "matching-001" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "amphibian"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub1')]" to "mammal"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub2')]" to "amphibian"
And I set the field "Answer 1" to "amphibian"
And I set the field "Answer 2" to "mammal"
And I set the field "Answer 3" to "amphibian"
And I press "Check"
Then I should see "Well done!"
And I should see "General feedback."
And I switch to the main window
@javascript @_switch_window
Scenario: Preview a Matching question and submit a partially correct response.
When I choose "Edit question" action for "matching-001" in the question bank
And I set the following fields to these values:
| Shuffle | 0 |
And I press "id_submitbutton"
When I choose "Preview" action for "matching-001" in the question bank
And I switch to "questionpreview" window
When I am on the "matching-001" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "amphibian"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub1')]" to "insect"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub2')]" to "amphibian"
And I set the field "Answer 1" to "amphibian"
And I set the field "Answer 2" to "insect"
And I set the field "Answer 3" to "amphibian"
And I press "Check"
Then I should see "Parts, but only parts, of your response are correct."
And I should see "General feedback."
And I switch to the main window
@javascript @_switch_window
Scenario: Preview a Matching question and submit an incorrect response.
When I choose "Edit question" action for "matching-001" in the question bank
And I set the following fields to these values:
| Shuffle | 0 |
And I press "id_submitbutton"
When I choose "Preview" action for "matching-001" in the question bank
And I switch to "questionpreview" window
When I am on the "matching-001" "core_question > preview" page logged in as teacher
And I expand all fieldsets
And I set the field "How questions behave" to "Immediate feedback"
And I press "Start again with these options"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub0')]" to "mammal"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub1')]" to "insect"
And I set the field with xpath "//table[@class='answer']//td[@class='control']//select[contains(@id, '1_sub2')]" to "insect"
And I set the field "Answer 1" to "mammal"
And I set the field "Answer 2" to "insect"
And I set the field "Answer 3" to "insect"
And I press "Check"
Then I should see "That is not right at all."
And I should see "General feedback."
And I switch to the main window
@@ -6,33 +6,32 @@ Feature: Test creating a Multianswer (Cloze) question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
Scenario: Create a Cloze question
When I add a "Embedded answers (Cloze)" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Embedded answers (Cloze)" question filling the form with:
| Question name | multianswer-001 |
| Question text | {1:SHORTANSWER:=Berlin} is the capital of Germany. |
| General feedback | The capital of Germany is Berlin. |
Then I should see "multianswer-001" in the "categoryquestions" "table"
Scenario: Create a broken Cloze question and correct it
Given I press "Create a new question ..."
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I press "Create a new question ..."
And I set the field "Embedded answers (Cloze)" to "1"
And I press "Add"
And I set the field "Question name" to "multianswer-002"
And I set the field "Question text" to "Please select the fruits {1:MULTICHOICE:=Apple#Correct}"
And I set the field "General feedback" to "Apple are delicious."
When I press "id_submitbutton"
And I press "id_submitbutton"
Then I should see "This type of question requires at least 2 choices"
And I set the following fields to these values:
| Question text | Please select the fruits {1:MULTICHOICE:=Apple#Correct~Banana#Wrong} |
@@ -40,11 +39,12 @@ Feature: Test creating a Multianswer (Cloze) question
And I should see "multianswer-002" in the "categoryquestions" "table"
Scenario: Try to create a Cloze question that has no answer
Given I press "Create a new question ..."
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I press "Create a new question ..."
And I set the field "Embedded answers (Cloze)" to "1"
And I press "Add"
And I set the following fields to these values:
| Question name | multianswer-003 |
| Question text | {1:SHORTANSWER:= } is the capital of Germany. |
And I press "id_submitbutton"
And I should see "This type of question requires at least 1 answers"
Then I should see "This type of question requires at least 1 answers"
@@ -6,20 +6,18 @@ Feature: Test creating a Multiple choice question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@moodle.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
| user | course | role |
| teacher | C1 | editingteacher |
Scenario: Create a Multiple choice question with multiple response
When I add a "Multiple choice" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Multiple choice" question filling the form with:
| Question name | Multi-choice-001 |
| Question text | Find the capital cities in Europe. |
| General feedback | Paris and London |
@@ -39,7 +37,8 @@ Feature: Test creating a Multiple choice question
Then I should see "Multi-choice-001"
Scenario: Create a Multiple choice question with single response
When I add a "Multiple choice" question filling the form with:
When I am on the "Course 1" "core_question > course question bank" page logged in as teacher
And I add a "Multiple choice" question filling the form with:
| Question name | Multi-choice-002 |
| Question text | Find the capital city of England. |
| General feedback | London is the capital city of England. |
@@ -19,16 +19,16 @@ Feature: Test duplicating a quiz containing a Multiple choice question
| quiz | Test quiz | C1 | quiz1 |
And quiz "Test quiz" contains the following questions:
| Multi-choice-001 | 1 |
And I log in as "admin"
And I am on "Course 1" course homepage
@javascript
Scenario: Backup and restore a course containing a Multiple choice question
When I backup "Course 1" course using this options:
When I am on the "Course 1" course page logged in as admin
And I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Schema | Course name | Course 2 |
And I navigate to "Question bank" in current page administration
| Schema | Course name | Course 2 |
| Schema | Course short name | C2 |
And I am on the "Course 2" "core_question > course question bank" page
And I choose "Edit question" action for "Multi-choice-001" in the question bank
Then the following fields match these values:
| Question name | Multi-choice-001 |
@@ -6,15 +6,15 @@ Feature: Clear my answers
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | S1 | Student1 | student1@moodle.com |
| username |
| student |
And the following "course" exists:
| fullname | Course 1 |
| shortname | C1 |
| category | 0 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| user | course | role |
| student | C1 | student |
And the following "question category" exists:
| contextlevel | Course |
| reference | C1 |
@@ -39,8 +39,8 @@ Feature: Clear my answers
@javascript
Scenario: Attempt a quiz and reset my chosen answer.
Given I am on the "Quiz 1" "quiz activity" page logged in as student1
When I press "Attempt quiz now"
Given I am on the "Quiz 1" "quiz activity" page logged in as student
When I press "Attempt quiz"
And I should see "Question One"
And I click on "Four" "qtype_multichoice > Answer" in the "Question One" "question"
And I should see "Clear my choice"
@@ -51,8 +51,8 @@ Feature: Clear my answers
@javascript
Scenario: Attempt a quiz and revisit a cleared answer.
Given I am on the "Quiz 1" "quiz activity" page logged in as student1
When I press "Attempt quiz now"
Given I am on the "Quiz 1" "quiz activity" page logged in as student
When I press "Attempt quiz"
And I should see "Question One"
And I click on "Four" "qtype_multichoice > Answer" in the "Question One" "question"
And I follow "Finish attempt ..."
@@ -6,14 +6,14 @@ Feature: Test editing a Multiple choice question
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | T1 | Teacher1 | teacher1@example.com |
| username |
| teacher |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher | C1 | editingteacher |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
@@ -21,23 +21,20 @@ Feature: Test editing a Multiple choice question
| questioncategory | qtype | name | template |
| Test questions | multichoice | Multiple choice for editing | two_of_four |
| Test questions | multichoice | Single choice for editing | one_of_four |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Question bank" in current page administration
Scenario: Edit a Multiple choice question with multiple response (checkboxes)
When I choose "Edit question" action for "Multiple choice for editing" in the question bank
When I am on the "Multiple choice for editing" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | |
And I press "id_submitbutton"
Then I should see "You must supply a value here."
When I set the following fields to these values:
And I should see "You must supply a value here."
And I set the following fields to these values:
| Question name | Edited Multiple choice name |
And I press "id_submitbutton"
Then I should see "Edited Multiple choice name"
Scenario: Edit a Multiple choice question with single response (radio buttons)
When I choose "Edit question" action for "Single choice for editing" in the question bank
When I am on the "Single choice for editing" "core_question > edit" page logged in as teacher
And I set the following fields to these values:
| Question name | Edited Single choice name |
And I press "id_submitbutton"

Some files were not shown because too many files have changed in this diff Show More