Compare commits

..

42 Commits

Author SHA1 Message Date
Jun Pataleta b90b0e6a8a Moodle release 3.9.21 2023-04-22 16:22:34 +08:00
Eloy Lafuente (stronk7) 58a55fcd40 weekly release 3.9.20+ 2023-04-21 19:19:36 +02:00
Jun Pataleta c37dd0ecbd Merge branch 'MDL-77927-39' of https://github.com/stevandoMoodle/moodle into MOODLE_39_STABLE 2023-04-21 16:51:14 +08:00
Jun Pataleta 84462c3e71 MDL-77927 core: mod_assignment subplugins environment check 2023-04-21 15:58:22 +08:00
Andrew Nicols 129b2186ac Merge branch 'MDL-77128-39' of https://github.com/mackensen/moodle into MOODLE_39_STABLE 2023-04-20 10:22:35 +08:00
Paul Holden 7eb6482266 MDL-77187 mod_wiki: validate external method sort parameters. 2023-04-19 12:57:22 +00:00
Paul Holden 9e4c3f858f Merge branch 'MDL-77960-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-04-19 13:41:36 +01:00
Paul Holden a7bbba41bf Merge branch 'MDL-77944-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-04-19 13:06:44 +01:00
Simey Lameze bfc911b928 MDL-77960 behat: make verification steps more specific 2023-04-19 13:33:59 +08:00
Andrew Nicols 9766906cc5 weekly release 3.9.20+ 2023-04-18 22:28:25 +08:00
Charles Fulton 0864e3adb3 MDL-77128 upgrade: Fix incompatible check in upgrade to match docs
Backport of MDL-72324
2023-04-18 09:07:34 -04:00
Andrew Nicols 86de73cb14 Merge branch 'MDL-77829-39' of https://github.com/stevandoMoodle/moodle into MOODLE_39_STABLE 2023-04-18 12:33:14 +08:00
Andrew Nicols b3e6ce7cfe MDL-77944 behat: Rename chrome options for w3c support
From Selenium 4.8.0, support for non-w3c browser control has ended.

We only use W3C browser control these days, and this was missed as part
of the move to W3C. All browser options must be vendor-prefixed.
2023-04-18 09:40:16 +08:00
Sara Arjona 94836d56b6 weekly release 3.9.20+ 2023-04-14 10:50:22 +02:00
Sara Arjona 3477b9c1c5 Merge branch 'MDL-73610_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-04-12 18:20:10 +02:00
Sara Arjona 6ee405e107 Merge branch 'MDL-77837-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-04-11 12:13:38 +02:00
Stevani Andolo 869b26f3e3 MDL-77829 core: Added environment check for mod_assignment
Decided to add an environment check before uninstalling the
mod_assignment plugin to prevent data lost.
2023-04-10 13:56:09 +08:00
Andrew Nicols d1f085a771 MDL-77837 core: Improve usage docs for cron_setup_user 2023-04-06 23:21:29 +08:00
Andrew Nicols 22ac74f686 MDL-77837 phpunit: Ensure that the cron user setter is used
When running an adhoc task in a unit test we should use the cron variant
of the set user method to mimic the behaviour of a real cron run.
2023-04-06 23:21:29 +08:00
Andrew Nicols 72a51148e9 MDL-77837 cron: Ensure user is set when running tasks
We should be proactive in ensuring that the environment is clean when
running a task. We already ensure that we have a clean renderer and
other parts of the output chain, but we were not setting a clean user.

This change adds a call to setup the cron user before each task is
actually executed.
2023-04-06 23:21:29 +08:00
Eloy Lafuente (stronk7) 7e6d3caab7 MDL-73610 nodejs: Small updates to required packages
The main goal of this issue is to avoid scanners (Dependabot
and friends), reporting about security issues with the current
xmldom 0.6.0 package.

Note that this doesn't affect prod at all, because it's a dev
dependency, hardly exploitable. So it's not a security fix, just
a security_benefit, if something.

So here, we are updating from xmldom 0.6.0 to @xmldom/xmldom 0.8.7
(note that the package was renamed in 0.7.0, so it's the very same)

Also, when proceeding with the changes, it was detected that we
are incorrectly declaring @babel/eslint-parser as a normal dependency
instead of a development one, so we are also fixing that little detail.

The commands executed to get the changes above applied have been:

- nvm use
- npm install @xmldom/xmldom@^0.8.7 --save-dev
- npm uninstall xmldom
- npm install @babel/eslint-parser@^7.17.0 --save-dev

(we haven't run a complete re-install because we only want to modify
the minimum possible at this stage).
2023-04-06 15:00:14 +02:00
Sara Arjona 0b15830a44 weekly release 3.9.20+ 2023-04-06 14:02:40 +02:00
Andrew Nicols 6c34850db6 Merge branch 'MDL-77584-39' of https://github.com/ewallah/moodle into MOODLE_39_STABLE 2023-04-04 12:08:26 +08:00
Paul Holden ed81c8df64 Merge branch 'MDL-75906-39' of https://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2023-04-03 14:54:07 +01:00
Michael Hawkins efa1cab75a MDL-75906 core: Updated security.txt expiry 2023-04-03 17:28:04 +08:00
Paul Holden aa99d2ebac weekly release 3.9.20+ 2023-03-31 18:12:03 +01:00
Sara Arjona 9c4d90cb52 Merge branch 'MDL-77761-39' of https://github.com/junpataleta/moodle into MOODLE_39_STABLE 2023-03-30 17:53:39 +02:00
Jun Pataleta 6a15f3890e Merge branch 'MDL-77333_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-03-30 19:03:17 +08:00
Jun Pataleta 4a4bf70e8b MDL-77761 core_form: Add label for editor format selector 2023-03-28 23:35:24 +08:00
Eloy Lafuente (stronk7) 3aba658a40 MDL-77333 mod_resource: fixes generator uploading files + tests
MDL-76499 revealed a few problems with resource generators:

1. We were not covering with unit tests the upload of files from disk
   (and here it's where the problem was).
2. There was a little of confusion between disk paths (only needed
   to upload files) and file_area paths (the generator only creates
   or uploads files to the root directory of the file area.
3. It was possible to request the upload of a file to the generator
   without that file effectively existing.

This commit fixes those points  and covers 99% of the generator code.
2023-03-26 11:45:05 +02:00
Sara Arjona ed154e71b0 weekly release 3.9.20+ 2023-03-24 13:59:44 +01:00
Jun Pataleta 06d46b875b Merge branch 'MDL-77669-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-24 11:50:48 +08:00
Paul Holden 478b7146e5 Merge branch 'MDL-77691-39' of https://github.com/roland04/moodle into MOODLE_39_STABLE 2023-03-23 11:43:45 +00:00
Mikel Martín 5febdbe6a2 MDL-77691 behat: Add step to navigate to profile page directly
Co-authored-by: Simey Lameze <simey@moodle.com>
2023-03-23 08:28:43 +01:00
Ilya Tregubov 09e068e8bb weekly release 3.9.20+ 2023-03-22 09:37:21 +08:00
Meirza d17d7263fd MDL-77669 dml: Added extrainfo in the DB options config.
extrainfo is an extra information for the DB driver, e.g. SQL Server,
has additional configuration according to its environment,
which the administrator can specify to alter and override any connection options.

Co-authored-by: LukeCarrier <luke@carrier.im>

This is a backport of MDL-64153.
2023-03-21 08:48:08 +08:00
Sara Arjona 0afaaad6dd Merge branch 'MDL-77574-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-03-20 17:06:41 +01:00
info@eWallah.net 556cdde71a MDL-77584 currencies: Fix outdated ISO 4217 code for Zambian Kwacha
On 2013-01-01 the ZMK code got replaced by the new ZMW code.

AMOS BEGIN
 MOV [ZMK,core_currencies],[ZMW,core_currencies]
AMOS END
2023-03-16 19:53:28 +01:00
Eloy Lafuente (stronk7) f24eb73cc5 weekly release 3.9.20+ 2023-03-14 16:07:54 +01:00
Jun Pataleta 01576f2100 Merge branch 'MDL-76680/39' of https://github.com/skodak/moodle into MOODLE_39_STABLE 2023-03-14 11:56:45 +08:00
Simey Lameze f39e564141 MDL-77574 myoverview: wait until next button exists before clicking 2023-03-13 14:19:10 +08:00
Petr Skoda ef1ecd2ad3 MDL-76680 core: disable $USER->ignoresesskey on next page 2023-03-11 10:37:56 +01:00
38 changed files with 826 additions and 246 deletions
+1 -1
View File
@@ -142,7 +142,7 @@ module.exports = function(grunt) {
const path = require('path');
const tasks = {};
const async = require('async');
const DOMParser = require('xmldom').DOMParser;
const DOMParser = require('@xmldom/xmldom').DOMParser;
const xpath = require('xpath');
const semver = require('semver');
const watchman = require('fb-watchman');
+2
View File
@@ -4109,6 +4109,8 @@
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mod_assignment" level="required">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
@@ -144,9 +144,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -163,9 +161,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -185,9 +181,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | complete | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | complete | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -241,9 +241,7 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
And I set the field "I agree to the This site policy" to "1"
And I press "Next"
And I log out
And I log in as "admin"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "Manager"
And I am on the "manager" "user > profile" page logged in as "admin"
And I follow "Log in as"
And I press "Continue"
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
@@ -562,9 +562,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
And the following "users" exist:
| username | firstname | lastname | email |
| user1 | User | 1 | user1@example.com |
When I log in as "admin"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
When I am on the "user1" "user > profile" page logged in as "admin"
And I follow "Log in as"
Then I should see "You are logged in as User 1"
And I press "Continue"
@@ -603,8 +601,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
And I set the field "I agree to the This site policy" to "1"
And I set the field "I agree to the This privacy policy" to "1"
And I press "Next"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page
And I follow "Log in as"
Then I should see "You are logged in as User 1"
And I press "Continue"
@@ -146,6 +146,7 @@ Feature: My overview block pagination
| student1 | C12 | student |
| student1 | C13 | student |
When I log in as "student1"
And I wait until ".block_myoverview [data-control='next']" "css_element" exists
And I click on "[data-control='next']" "css_element" in the "Course overview" "block"
Then the "class" attribute of ".block_myoverview [data-control='next']" "css_element" should contain "disabled"
And I log out
+4
View File
@@ -70,6 +70,10 @@ $CFG->dboptions = array(
// can be removed for MySQL (by default it will
// use 'utf8mb4_unicode_ci'. This option should
// be removed for all other databases.
// 'extrainfo' => [], // Extra information for the DB driver, e.g. SQL Server,
// has additional configuration according to its environment,
// which the administrator can specify to alter and
// override any connection options.
// 'fetchbuffersize' => 100000, // On PostgreSQL, this option sets a limit
// on the number of rows that are fetched into
// memory when doing a large recordset query
@@ -43,24 +43,24 @@ Feature: We can change what we are viewing on the grader report
And I click on "Hide" "link" in the "Test assignment name 2" activity
And I am on "Course 1" course homepage
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 "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
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- | -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 "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
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 | 170 |
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 "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
@@ -68,7 +68,7 @@ Feature: We can change what we are viewing on the grader report
| 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
Scenario: Minimise the grader report containing hidden activities without the 'moodle/grade:viewhidden' capability
When I am on "Course 1" course homepage with editing mode on
And I open "Test assignment name 2" actions menu
And I click on "Hide" "link" in the "Test assignment name 2" activity
@@ -81,24 +81,24 @@ Feature: We can change what we are viewing on the grader report
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 should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
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- | -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 "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
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 | 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 "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
+2 -1
View File
@@ -1460,7 +1460,8 @@ $string['xmlrpcmnetenabled'] = 'It has been detected that the Moodle Networking
$string['xmlrpcwebserviceenabled'] = 'It has been detected that the XML-RPC Web Service protocol is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer maintained by PHP.';
$string['yuicomboloading'] = 'YUI combo loading';
$string['ziprequired'] = 'The Zip PHP extension is now required by Moodle, info-ZIP binaries or PclZip library are not used anymore.';
$string['modassignmentinuse'] = 'Your site is still using the Assignment 2.2 plugin. Before upgrading you must 1) backup any Assignment 2.2 activities that you want to keep and restore them as Assignment activities, and 2) delete all Assignment 2.2 data from the database.';
$string['modassignmentsubpluginsexist'] = 'Assignment 2.2. subplugins may be present. The mod/assignment folder and all of its subplugins need to be removed before upgrading.';
$string['caching'] = 'Caching';
$string['cachesettings'] = 'Cache settings';
+1 -1
View File
@@ -180,5 +180,5 @@ $string['XOF'] = 'CFA Franc BCEAO';
$string['XPF'] = 'CFP Franc';
$string['YER'] = 'Yemeni Rial';
$string['ZAR'] = 'South African Rand';
$string['ZMK'] = 'Zambian Kwacha';
$string['ZMW'] = 'Zambian Kwacha';
$string['ZWL'] = 'Zimbabwe Dollar';
+1
View File
@@ -53,6 +53,7 @@ $string['cutpastemozilla'] = 'Unfortunately, you cannot currently use normal key
$string['delete'] = 'Delete';
$string['editors'] = 'Text editors';
$string['editorsettings'] = 'Manage editors';
$string['editorxformat'] = '{$a} format';
$string['enterurlfirst'] = 'You have to enter an URL first';
$string['filebrowser'] = 'File Browser';
$string['findwhat'] = 'Find';
+14 -4
View File
@@ -666,7 +666,7 @@ class behat_config_util {
[
'capabilities' => [
'extra_capabilities' => [
'chromeOptions' => [
'goog:chromeOptions' => [
'args' => [
'unlimited-storage',
'disable-web-security',
@@ -678,6 +678,16 @@ class behat_config_util {
$values
);
// Selenium no longer supports non-w3c browser control.
// Rename chromeOptions to goog:chromeOptions, which is the W3C variant of this.
if (array_key_exists('chromeOptions', $values['capabilities']['extra_capabilities'])) {
$values['capabilities']['extra_capabilities']['goog:chromeOptions'] = array_merge_recursive(
$values['capabilities']['extra_capabilities']['goog:chromeOptions'],
$values['capabilities']['extra_capabilities']['chromeOptions']
);
unset($values['capabilities']['extra_capabilities']['chromeOptions']);
}
// If the mobile app is enabled, check its version and add appropriate tags.
if ($mobiletags = $this->get_mobile_version_tags()) {
if (!empty($values['tags'])) {
@@ -687,13 +697,13 @@ class behat_config_util {
}
}
$values['capabilities']['extra_capabilities']['chromeOptions']['args'] = array_map(function($arg): string {
$values['capabilities']['extra_capabilities']['goog:chromeOptions']['args'] = array_map(function($arg): string {
if (substr($arg, 0, 2) === '--') {
return substr($arg, 2);
}
return $arg;
}, $values['capabilities']['extra_capabilities']['chromeOptions']['args']);
sort($values['capabilities']['extra_capabilities']['chromeOptions']['args']);
}, $values['capabilities']['extra_capabilities']['goog:chromeOptions']['args']);
sort($values['capabilities']['extra_capabilities']['goog:chromeOptions']['args']);
}
// Fill tags information.
+26
View File
@@ -1676,4 +1676,30 @@ EOF;
return !empty($matches);
}
/**
* Get the user id from an identifier.
*
* The user username and email fields are checked.
*
* @param string $identifier The user's username or email.
* @return int|null The user id or null if not found.
*/
protected function get_user_id_by_identifier(string $identifier): ?int {
global $DB;
$sql = <<<EOF
SELECT id
FROM {user}
WHERE username = :username
OR email = :email
EOF;
$result = $DB->get_field_sql($sql, [
'username' => $identifier,
'email' => $identifier,
]);
return $result ?: null;
}
}
+8
View File
@@ -242,6 +242,10 @@ function cron_run_inner_scheduled_task(\core\task\task_base $task) {
$predbqueries = null;
$predbqueries = $DB->perf_get_queries();
$pretime = microtime(1);
// Ensure that we have a clean session with the correct cron user.
cron_setup_user();
try {
get_mailer('buffer');
cron_prepare_core_renderer();
@@ -325,6 +329,10 @@ function cron_run_inner_adhoc_task(\core\task\adhoc_task $task) {
}
cron_setup_user($user);
} else {
// No user specified, ensure that we have a clean session with the correct cron user.
cron_setup_user();
}
try {
+17 -10
View File
@@ -208,21 +208,28 @@ class sqlsrv_native_moodle_database extends moodle_database {
$this->store_settings($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
$options = [
'UID' => $this->dbuser,
'PWD' => $this->dbpass,
'Database' => $this->dbname,
'CharacterSet' => 'UTF-8',
'MultipleActiveResultSets' => true,
'ConnectionPooling' => !empty($this->dboptions['dbpersist']),
'ReturnDatesAsStrings' => true,
];
$dbhost = $this->dbhost;
if (!empty($dboptions['dbport'])) {
$dbhost .= ',' . $dboptions['dbport'];
}
$this->sqlsrv = sqlsrv_connect($dbhost, array
(
'UID' => $this->dbuser,
'PWD' => $this->dbpass,
'Database' => $this->dbname,
'CharacterSet' => 'UTF-8',
'MultipleActiveResultSets' => true,
'ConnectionPooling' => !empty($this->dboptions['dbpersist']),
'ReturnDatesAsStrings' => true,
));
// The sqlsrv_connect() has a lot of connection options to be used.
// Users can add any supported options with the 'extrainfo' key in the dboptions.
if (isset($this->dboptions['extrainfo'])) {
$options = array_merge($options, $this->dboptions['extrainfo']);
}
$this->sqlsrv = sqlsrv_connect($dbhost, $options);
if ($this->sqlsrv === false) {
$this->sqlsrv = null;
+1 -1
View File
@@ -21,7 +21,7 @@ Feature: Atto Autosave
And I click on "Save changes" "button"
And I am on "Course 1" course homepage
And I navigate to "Edit settings" in current page administration
And I set the field with xpath "//select[@name='summary_editor[format]']" to "1"
And I set the field "Course summary format" to "1"
And I click on "Save and display" "button"
And I log out
+1
View File
@@ -444,6 +444,7 @@ class MoodleQuickForm_editor extends HTML_QuickForm_element implements templatab
$context['id'] = $id;
$context['value'] = $text;
$context['format'] = $format;
$context['formatlabel'] = get_string('editorxformat', 'editor', $this->_label);
if (!is_null($this->getAttribute('onblur')) && !is_null($this->getAttribute('onchange'))) {
$context['changelistener'] = true;
@@ -35,6 +35,7 @@
</div>
<div>
{{#hasformats}}
<label for="menu{{name}}format" class="sr-only">{{formatlabel}}</label>
<select name="{{name}}[format]" id="menu{{name}}format" class="custom-select">
{{#formats}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{text}}</option>
+1 -1
View File
@@ -702,7 +702,7 @@ abstract class advanced_testcase extends base_testcase {
}
cron_prepare_core_renderer();
$this->setUser($user);
cron_setup_user($user);
$task->execute();
\core\task\manager::adhoc_task_complete($task);
+54
View File
@@ -33,8 +33,13 @@ defined('MOODLE_INTERNAL') || die();
* @category phpunit
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \advanced_testcase
*/
class core_phpunit_advanced_testcase extends advanced_testcase {
public static function setUpBeforeClass(): void {
global $CFG;
require_once(__DIR__ . '/fixtures/adhoc_test_task.php');
}
public function test_debugging() {
global $CFG;
@@ -680,4 +685,53 @@ class core_phpunit_advanced_testcase extends advanced_testcase {
self::resetAllData(false);
self::assertFalse(core_useragent::get_user_agent_string(), 'It should not be set again, data was reset.');
}
/**
* @covers ::runAdhocTasks
*/
public function test_runadhoctasks_no_tasks_queued(): void {
$this->runAdhocTasks();
$this->expectOutputRegex('/^$/');
}
/**
* @covers ::runAdhocTasks
*/
public function test_runadhoctasks_tasks_queued(): void {
$this->resetAfterTest(true);
$admin = get_admin();
\core\task\manager::queue_adhoc_task(new \core_phpunit\adhoc_test_task());
$this->runAdhocTasks();
$this->expectOutputRegex("/Task was run as {$admin->id}/");
}
/**
* @covers ::runAdhocTasks
*/
public function test_runadhoctasks_with_existing_user_change(): void {
$this->resetAfterTest(true);
$admin = get_admin();
$this->setGuestUser();
\core\task\manager::queue_adhoc_task(new \core_phpunit\adhoc_test_task());
$this->runAdhocTasks();
$this->expectOutputRegex("/Task was run as {$admin->id}/");
}
/**
* @covers ::runAdhocTasks
*/
public function test_runadhoctasks_with_existing_user_change_and_specified(): void {
global $USER;
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$this->setGuestUser();
$task = new \core_phpunit\adhoc_test_task();
$task->set_userid($user->id);
\core\task\manager::queue_adhoc_task($task);
$this->runAdhocTasks();
$this->expectOutputRegex("/Task was run as {$user->id}/");
}
}
+35
View File
@@ -0,0 +1,35 @@
<?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/>.
namespace core_phpunit;
/**
* Fixtures for task tests.
*
* @package core
* @category phpunit
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class adhoc_test_task extends \core\task\adhoc_task {
/**
* Execute.
*/
public function execute() {
global $USER;
mtrace("Task was run as {$USER->id}");
}
}
+5 -1
View File
@@ -170,7 +170,11 @@ function get_moodle_cookie() {
/**
* Sets up current user and course environment (lang, etc.) in cron.
* Do not use outside of cron script!
* Note: This function is intended only for use in:
* - the cron runner scripts
* - individual tasks which extend the adhoc_task and scheduled_task classes
* - unit tests related to tasks
* - other parts of the cron/task system
*
* @param stdClass $user full user object, null means default cron user (admin),
* value 'reset' means reset internal static caches.
+2
View File
@@ -796,6 +796,8 @@ if (empty($CFG->sessiontimeout)) {
$CFG->sessiontimeout = 8 * 60 * 60;
}
\core\session\manager::start();
// Prevent ignoresesskey hack from getting carried over to a next page.
unset($USER->ignoresesskey);
// Set default content type and encoding, developers are still required to use
// echo $OUTPUT->header() everywhere, anything that gets set later should override these headers.
+23
View File
@@ -1526,4 +1526,27 @@ class upgradelib_test extends advanced_testcase {
$this->assertEquals('admin_dir_usage', $result->getInfo());
$this->assertFalse($result->getStatus());
}
/**
* Test the check_mod_assignment check if mod_assignment is still used.
*
* @covers ::check_mod_assignment
* @return void
*/
public function test_check_mod_assignment_is_used(): void {
global $DB;
$this->resetAfterTest();
$result = new environment_results('custom_checks');
if ($DB->get_manager()->table_exists('assignment')) {
$DB->insert_record('assignment', (object)['name' => 'test_assign', 'intro' => 'test_assign_intro']);
$this->assertNotNull(check_mod_assignment($result));
$this->assertEquals('Assignment 2.2 is in use', $result->getInfo());
$this->assertFalse($result->getStatus());
} else {
$this->assertTrue($result->getStatus());
}
}
}
+5
View File
@@ -1,6 +1,11 @@
This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
===3.9.21===
* Added 'extrainfo' in the DB options config. Its extra information for the DB driver, e.g. SQL Server,
has additional configuration according to its environment, which the administrator can specify to alter and
override any connection options.
===3.9.12===
* Two new helper functions have been added to lib/datalib.php, for safely preparing SQL ORDER BY statements where user
interactions define sort parameters (see the respective docblocks for full details and examples):
+27 -1
View File
@@ -614,7 +614,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
// Throw exception if plugin is incompatible with moodle version.
if (!empty($plugin->incompatible)) {
if ($CFG->branch <= $plugin->incompatible) {
if ($CFG->branch >= $plugin->incompatible) {
throw new plugin_incompatible_exception($component, $plugin->version);
}
}
@@ -2766,3 +2766,29 @@ function check_xmlrpc_usage(environment_results $result): ?environment_results {
return null;
}
/**
* Check whether the mod_assignment is currently being used.
*
* @param environment_results $result
* @return environment_results|null
*/
function check_mod_assignment(environment_results $result): ?environment_results {
global $DB, $CFG;
// Check the number of records.
if ($DB->get_manager()->table_exists('assignment') && $DB->count_records('assignment') > 0) {
$result->setInfo('Assignment 2.2 is in use');
$result->setFeedbackStr('modassignmentinuse');
return $result;
}
// Check for mod_assignment subplugins.
if (is_dir($CFG->dirroot . '/mod/assignment/type')) {
$result->setInfo('Assignment 2.2 subplugins present');
$result->setFeedbackStr('modassignmentsubpluginsexist');
return $result;
}
return null;
}
@@ -18,8 +18,7 @@ Feature: To be able to see and save user message preferences as admin
And I navigate to "Messaging > Notification settings" in site administration
And I set the field "email" to "1"
And I press "Save changes"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I click on "Student 1" "link" in the "Student 1" "table_row"
And I am on the "student1" "user > profile" page
And I click on "Preferences" "link" in the "#region-main-box" "css_element"
And I click on "Message preferences" "link" in the "#region-main-box" "css_element"
And I click on "//label[@data-state='loggedoff']" "xpath_element"
+14 -5
View File
@@ -77,8 +77,6 @@ class mod_resource_generator extends testing_module_generator {
}
$usercontext = context_user::instance($USER->id);
$filename = $record->defaultfilename ?? 'resource' . ($this->instancecount + 1) . '.txt';
// Set filepath depending on filename.
$filepath = (isset($record->defaultfilename)) ? $CFG->dirroot . '/' : '/';
// Pick a random context id for specified user.
$record->files = file_get_unused_draft_itemid();
@@ -86,11 +84,22 @@ class mod_resource_generator extends testing_module_generator {
// Add actual file there.
$filerecord = ['component' => 'user', 'filearea' => 'draft',
'contextid' => $usercontext->id, 'itemid' => $record->files,
'filename' => basename($filename), 'filepath' => $filepath];
'filename' => basename($filename), 'filepath' => '/'];
$fs = get_file_storage();
if ($record->uploaded == 1) {
// For uploading a file, it's required to specify a file, how not!
if (!isset($record->defaultfilename)) {
throw new coding_exception(
'The $record->defaultfilename option is required in order to upload a file');
}
// We require the full file path to exist when uploading a real file (fixture or whatever).
$fullfilepath = $CFG->dirroot . '/' . $record->defaultfilename;
if (!is_readable($fullfilepath)) {
throw new coding_exception(
'The $record->defaultfilename option must point to an existing file within dirroot');
}
// Create file using pathname (defaultfilename) set.
$fs->create_file_from_pathname($filerecord, $filepath . $filename);
$fs->create_file_from_pathname($filerecord, $fullfilepath);
} else {
// If defaultfilename is not set, create file from string "resource 1.txt".
$fs->create_file_from_string($filerecord, 'Test resource ' . $filename . ' file');
@@ -98,6 +107,6 @@ class mod_resource_generator extends testing_module_generator {
}
// Do work to actually add the instance.
return parent::create_instance($record, (array)$options);
return parent::create_instance($record, $options);
}
}
+43
View File
@@ -31,10 +31,12 @@ defined('MOODLE_INTERNAL') || die();
*
* @package mod_resource
* @category phpunit
* @covers \mod_resource_generator
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_resource_generator_testcase extends advanced_testcase {
public function test_generator() {
global $DB, $SITE;
@@ -86,5 +88,46 @@ class mod_resource_generator_testcase extends advanced_testcase {
$this->assertCount(1, $files);
$this->assertEquals('myfile.pdf', $file->get_filename());
$this->assertEquals('Test resource myfile.pdf file', $file->get_content());
// Create a new resource uploading a file.
$resource = $generator->create_instance([
'course' => $SITE->id,
'uploaded' => true,
'defaultfilename' => 'mod/resource/tests/fixtures/samplefile.txt',
]);
// Check that generated resource module contains the uploaded samplefile.txt.
$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('samplefile.txt', $file->get_filename());
$this->assertEquals('Hello!', $file->get_content());
// Try to generate a resource with uploaded file without specifying the file.
try {
$resource = $generator->create_instance([
'course' => $SITE->id,
'uploaded' => true,
]);
$this->assertTrue(false, 'coding_exception expected, defaultfilename is required');
} catch (\Exception $e) {
$this->assertInstanceOf(\coding_exception::class, $e);
$this->assertStringContainsString('defaultfilename option is required', $e->getMessage());
}
// Try to generate a resource with uploaded file pointing to non-existing file.
try {
$resource = $generator->create_instance([
'course' => $SITE->id,
'uploaded' => true,
'defaultfilename' => 'mod/resource/tests/fixtures/doesnotexist.txt',
]);
$this->assertTrue(false, 'coding_exception expected, defaultfilename must point to an existing file');
} catch (\Exception $e) {
$this->assertInstanceOf(\coding_exception::class, $e);
$this->assertStringContainsString('defaultfilename option must point to an existing file', $e->getMessage());
}
}
}
+10 -8
View File
@@ -467,15 +467,17 @@ class mod_wiki_external extends external_api {
throw new moodle_exception('cannotviewpage', 'wiki');
} else if ($subwiki->id != -1) {
// Set sort param.
$options = $params['options'];
if (!empty($options['sortby'])) {
if ($options['sortdirection'] != 'ASC' && $options['sortdirection'] != 'DESC') {
// Invalid sort direction. Use default.
$options['sortdirection'] = 'ASC';
}
$sort = $options['sortby'] . ' ' . $options['sortdirection'];
}
// Set sort param.
$sort = get_safe_orderby([
'id' => 'id',
'title' => 'title',
'timecreated' => 'timecreated',
'timemodified' => 'timemodified',
'pageviews' => 'pageviews',
'default' => 'title',
], $options['sortby'], $options['sortdirection'], false);
$pages = wiki_get_page_list($subwiki->id, $sort);
$caneditpages = wiki_user_can_edit($subwiki);
@@ -21,9 +21,9 @@ Feature: Teachers can embed images into instructions and conclusion fields
| workshop | C1 | Workshop with embedded images |
And I am on the "Workshop with embedded images" "workshop activity editing" page logged in as admin
And I set the following fields to these values:
| instructauthorseditor[format] | 1 |
| instructreviewerseditor[format] | 1 |
| conclusioneditor[format] | 1 |
| Instructions for submission format | 1 |
| Instructions for assessment format | 1 |
| Conclusion format | 1 |
And I press "Save and display"
And I log out
And I log in as "teacher1"
+472 -166
View File
File diff suppressed because it is too large Load Diff
+2 -4
View File
@@ -4,11 +4,13 @@
"description": "Moodle",
"devDependencies": {
"@babel/core": "7.17.5",
"@babel/eslint-parser": "^7.21.3",
"@babel/plugin-proposal-class-properties": "7.16.7",
"@babel/plugin-proposal-json-strings": "7.16.7",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/plugin-syntax-import-meta": "7.10.4",
"@babel/preset-env": "7.16.11",
"@xmldom/xmldom": "^0.8.7",
"ajv": "8.10.0",
"async": "3.2.3",
"babel-eslint": "10.1.0",
@@ -37,13 +39,9 @@
"stylelint": "13.3.3",
"stylelint-checkstyle-formatter": "0.1.2",
"stylelint-csstree-validator": "1.8.0",
"xmldom": "^0.6.0",
"xpath": "0.0.32"
},
"engines": {
"node": ">=16.14.0 <17"
},
"dependencies": {
"@babel/eslint-parser": "^7.17.0"
}
}
+1 -1
View File
@@ -3,4 +3,4 @@ Acknowledgments: https://moodle.org/security/
Preferred-Languages: en
Canonical: https://moodle.org/.well-known/security.txt
Policy: https://moodledev.io/general/development/process/security
Expires: 2023-05-29T01:00:00.000Z
Expires: 2023-10-30T01:00:00.000Z
+25
View File
@@ -84,4 +84,29 @@ class behat_user extends behat_base {
throw new ExpectationException('The "' . $field . '" field does have purpose "' . $purpose . '"', $this->getSession());
}
}
/**
* Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'.
*
* Recognised page names are:
* | Page Type | Identifier meaning | Description |
* | profile | username or email | User profile page (/user/profile.php) |
*
* @param string $type identifies which type of page this is, e.g. 'Editing'.
* @param string $identifier identifies the user, e.g. 'student1'.
* @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 'profile':
$userid = $this->get_user_id_by_identifier($identifier);
if (!$userid) {
throw new Exception('The specified user with username or email "' . $identifier . '" does not exist');
}
return new moodle_url('/user/profile.php', ['id' => $userid]);
default:
throw new Exception("Unrecognised page type '{$type}'.");
}
}
}
@@ -76,8 +76,7 @@ Feature: The student can navigate to their grades page and user grade report.
| moodle/user:viewuseractivitiesreport | 1 |
| moodle/user:viewdetails | 1 |
And I click on "Create this role" "button"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "Student 1"
And I am on the "student1" "user > profile" page
And I click on "Preferences" "link" in the ".profile_tree" "css_element"
And I follow "Assign roles relative to this user"
And I follow "Parent"
@@ -68,8 +68,7 @@ Feature: Access to preferences page
| moodle/user:viewuseractivitiesreport | 1 |
| moodle/user:viewdetails | 1 |
And I click on "Create this role" "button"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "Student 1"
And I am on the "student1" "user > profile" page
And I click on "Preferences" "link" in the ".profile_tree" "css_element"
And I follow "Assign roles relative to this user"
And I follow "Parent"
+2 -2
View File
@@ -29,9 +29,9 @@
defined('MOODLE_INTERNAL') || die();
$version = 2020061520.00; // 20200615 = branching date YYYYMMDD - do not modify!
$version = 2020061521.00; // 20200615 = branching date YYYYMMDD - do not modify!
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '3.9.20 (Build: 20230313)'; // Human-friendly version name
$release = '3.9.21 (Build: 20230424)'; // Human-friendly version name
$branch = '39'; // This version's branch.
$maturity = MATURITY_STABLE; // This version's maturity level.