Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 62c1f37d40 | |||
| cfda0752ab | |||
| 9fb15b2357 | |||
| d216f54daf | |||
| ab19e3a35b | |||
| c08f1615ea | |||
| a92dfea792 | |||
| 8f2b234393 | |||
| 3e442e842a | |||
| 4fa7993ca5 | |||
| 483aa01191 | |||
| b45e5e9e64 | |||
| 2736b6e7fa | |||
| f26739cfec | |||
| 3d336a1afa | |||
| 4a21f27def | |||
| 8c36dadbe2 | |||
| 82d535640a | |||
| 7e5acc697b | |||
| 97866086d3 | |||
| 00b1e807ab | |||
| 179fe73506 | |||
| a7834a73bf | |||
| e97e13b7ec | |||
| e41452ba37 | |||
| 8d8ec98aea | |||
| 27e94bad0a | |||
| a3342ca99f | |||
| efce12bb63 | |||
| c5783bb8d1 | |||
| cbafc99366 | |||
| a6c2b16be5 | |||
| ce34532f39 | |||
| 5c6365cde6 | |||
| 0ed9c4bc30 | |||
| 09c29f3496 | |||
| aa2c8af443 | |||
| c4d0b41624 | |||
| 0c39608eaf | |||
| 32a85859bf | |||
| b98c8f7a5f | |||
| 6027dc0942 | |||
| 5746cd1ba4 | |||
| abb970f87c | |||
| 578f563ea6 | |||
| f8e8c6eff2 | |||
| 9e961824a3 | |||
| b6d37642e8 | |||
| cbcd372a39 | |||
| a700df849f | |||
| ef214ba29a | |||
| 06a7c2fb1c | |||
| ce1233b43c | |||
| 26737b5337 | |||
| 8233caad6d | |||
| 07b0a5740b | |||
| 9ba5a1a913 | |||
| 45f64ecdef | |||
| 6007ba3c53 | |||
| d11d6e1fd9 | |||
| e2faf39070 | |||
| 7ce351e8b5 | |||
| a8a5651b8f | |||
| 65b8f8c33d | |||
| 97ff8d2f9f | |||
| d9e35bd123 | |||
| 5b76a6fd20 | |||
| e98f31c222 | |||
| 45e3520fe6 | |||
| aa12f3ab77 | |||
| 8603e870d7 | |||
| 5fdc5a3bda | |||
| 2eb8d9af4c | |||
| 90d53f7d90 | |||
| a75906d75e | |||
| 0f3cc7d9f5 | |||
| e1d8bfd7d8 | |||
| 7933daf5cc | |||
| 767e84f401 | |||
| 2c68ee6918 | |||
| 7c72ec0373 | |||
| e59ce79f00 | |||
| 6ff2db90f9 | |||
| 3dd7c6f6f8 | |||
| 41ac252e70 | |||
| 41269b7115 | |||
| 5bf260d921 | |||
| ee1ea6ffe6 | |||
| f5a2991935 | |||
| 34b34aed9c | |||
| 423cbd2824 | |||
| d76c95f425 | |||
| e3581a759a | |||
| a344e93c28 | |||
| 47197dded0 | |||
| f90b310189 | |||
| 0a00ae5151 | |||
| 574e7b39f4 | |||
| 71427f127c | |||
| 83b31ea2d6 | |||
| ab1982b600 | |||
| 9ea30b852d | |||
| feb5468de7 | |||
| 1ba4c16317 | |||
| 3835002cf1 | |||
| 89855404de | |||
| 44d7647837 | |||
| ab9737d0ec | |||
| 157135400d | |||
| e684f9a0eb | |||
| 766fd1c555 | |||
| 5eba696644 | |||
| dddcaba228 | |||
| c136d9798d | |||
| 9b4a0b4978 | |||
| 6958f54ef4 | |||
| 71b4125622 | |||
| 70106f31f9 |
@@ -4504,6 +4504,203 @@
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_oracle_usage" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_async_backup" level="recommended">
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="4.5" requires="4.1.2">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.6.7" />
|
||||
<VENDOR name="mysql" version="8.0" />
|
||||
<VENDOR name="postgres" version="13" />
|
||||
<VENDOR name="mssql" version="14.0" />
|
||||
<VENDOR name="oracle" version="19" />
|
||||
</DATABASE>
|
||||
<PHP version="8.1.0" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mbstringrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="intlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
<PHP_EXTENSION name="sodium" level="required"/>
|
||||
<PHP_EXTENSION name="exif" level="optional"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbstorageengine" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="quizattemptsupgradedmessage" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="slashargumentswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unsupporteddbtablerowformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unoconvwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="ishttpswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="incompleteunicodesupport" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="sixtyfourbitsrequired" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="iscustomadminwarnings" />
|
||||
</FEEDBACK>
|
||||
</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_CHECK file="lib/upgradelib.php" function="check_db_prefix_length" level="required">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_oracle_usage" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_async_backup" level="recommended">
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
+5
-2
@@ -2051,8 +2051,10 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
// We are checking installed & enabled things
|
||||
if ($environment_result->getLevel() == 'required') {
|
||||
$stringtouse = 'environmentrequirecustomcheck';
|
||||
} else {
|
||||
} else if ($environment_result->getLevel() == 'optional') {
|
||||
$stringtouse = 'environmentrecommendcustomcheck';
|
||||
} else {
|
||||
$stringtouse = 'environmentshouldfixcustomcheck';
|
||||
}
|
||||
|
||||
} else if ($environment_result->getPart() == 'php_setting') {
|
||||
@@ -2083,7 +2085,8 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if ($status) { //Handle ok result (ok)
|
||||
$status = get_string('statusok');
|
||||
} else {
|
||||
if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
|
||||
// Handle check result (warning).
|
||||
if (in_array($environment_result->getLevel(), ['optional', 'recommended'])) {
|
||||
$status = get_string('check');
|
||||
$warningline = true;
|
||||
} else { //Handle error result (error)
|
||||
|
||||
@@ -152,7 +152,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$sensiblesettingsdefault .= 'server_password@@search_solr, ssl_keypassword@@search_solr, ';
|
||||
$sensiblesettingsdefault .= 'alternateserver_password@@search_solr, alternatessl_keypassword@@search_solr, ';
|
||||
$sensiblesettingsdefault .= 'test_password@@cachestore_redis, password@@mlbackend_python, ';
|
||||
$sensiblesettingsdefault .= 'badges_badgesalt@@none, calendar_exportsalt@@none';
|
||||
$sensiblesettingsdefault .= 'badges_badgesalt@@none, calendar_exportsalt@@none, ';
|
||||
$sensiblesettingsdefault .= 'bigbluebuttonbn_shared_secret@@none';
|
||||
$temp->add(new admin_setting_configtextarea('adminpresets/sensiblesettings',
|
||||
get_string('sensiblesettings', 'core_adminpresets'),
|
||||
get_string('sensiblesettingstext', 'core_adminpresets'),
|
||||
|
||||
@@ -18,7 +18,7 @@ Feature: An administrator can browse user accounts
|
||||
When I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
# Name field always present, email field is default for showidentity.
|
||||
Then the following should exist in the "users" table:
|
||||
| First name / Last name | Email address |
|
||||
| First name | Email address |
|
||||
| User One | one@example.com |
|
||||
| User Two | two@example.com |
|
||||
# Should not see other identity fields or non-default name fields.
|
||||
@@ -34,7 +34,7 @@ Feature: An administrator can browse user accounts
|
||||
| alternativefullnameformat | firstnamephonetic lastname |
|
||||
When I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
Then the following should exist in the "users" table:
|
||||
| First name - phonetic / Last name | Email address |
|
||||
| First name - phonetic | Email address |
|
||||
| Yewzer One | one@example.com |
|
||||
| Yoozare Two | two@example.com |
|
||||
|
||||
@@ -43,7 +43,7 @@ Feature: An administrator can browse user accounts
|
||||
| showuseridentity | department,profile_field_frog |
|
||||
When I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
Then the following should exist in the "users" table:
|
||||
| First name / Last name | Favourite frog | Department |
|
||||
| First name | Favourite frog | Department |
|
||||
| User One | Kermit | Attack |
|
||||
| User Two | Tree | Defence |
|
||||
And I should not see "Email address" in the "table" "css_element"
|
||||
|
||||
@@ -155,9 +155,9 @@ class data_request extends persistent {
|
||||
case api::DATAREQUEST_STATUS_EXPIRED:
|
||||
$result = true;
|
||||
break;
|
||||
// Complete requests are expired if the expiry time has elapsed.
|
||||
// Complete requests are expired if the expiry time is a positive value, and has elapsed.
|
||||
case api::DATAREQUEST_STATUS_DOWNLOAD_READY:
|
||||
$expiryseconds = get_config('tool_dataprivacy', 'privacyrequestexpiry');
|
||||
$expiryseconds = (int) get_config('tool_dataprivacy', 'privacyrequestexpiry');
|
||||
if ($expiryseconds > 0 && time() >= ($request->get('timemodified') + $expiryseconds)) {
|
||||
$result = true;
|
||||
}
|
||||
@@ -178,7 +178,12 @@ class data_request extends persistent {
|
||||
public static function get_expired_requests($userid = 0) {
|
||||
global $DB;
|
||||
|
||||
$expiryseconds = get_config('tool_dataprivacy', 'privacyrequestexpiry');
|
||||
// Complete requests are expired if the expiry time is a positive value, and has elapsed.
|
||||
$expiryseconds = (int) get_config('tool_dataprivacy', 'privacyrequestexpiry');
|
||||
if ($expiryseconds <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$expirytime = strtotime("-{$expiryseconds} second");
|
||||
$table = self::TABLE;
|
||||
$sqlwhere = 'type = :export_type AND status = :completestatus AND timemodified <= :expirytime';
|
||||
|
||||
@@ -26,10 +26,11 @@ require_once('data_privacy_testcase.php');
|
||||
* Expired data requests tests.
|
||||
*
|
||||
* @package tool_dataprivacy
|
||||
* @covers \tool_dataprivacy\data_request
|
||||
* @copyright 2018 Michael Hawkins
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class expired_data_requests_test extends data_privacy_testcase {
|
||||
final class expired_data_requests_test extends data_privacy_testcase {
|
||||
|
||||
/**
|
||||
* Test tearDown.
|
||||
@@ -107,6 +108,52 @@ class expired_data_requests_test extends data_privacy_testcase {
|
||||
$this->assertEquals(0, $DB->count_records('files', $fileconditions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that data requests are not expired when expiration is disabled (set to zero)
|
||||
*/
|
||||
public function test_data_request_expiry_never(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
\core_privacy\local\request\writer::setup_real_writer_instance();
|
||||
|
||||
// Disable request expiry.
|
||||
set_config('privacyrequestexpiry', 0, 'tool_dataprivacy');
|
||||
|
||||
// Create and approve data request.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$usercontext = \context_user::instance($user->id);
|
||||
|
||||
$this->setUser($user->id);
|
||||
$datarequest = api::create_data_request($user->id, api::DATAREQUEST_TYPE_EXPORT);
|
||||
$requestid = $datarequest->get('id');
|
||||
|
||||
$this->setAdminUser();
|
||||
api::approve_data_request($requestid);
|
||||
|
||||
ob_start();
|
||||
$this->runAdhocTasks('\tool_dataprivacy\task\process_data_request_task');
|
||||
ob_end_clean();
|
||||
|
||||
// Run expiry deletion - should not affect test export.
|
||||
$expiredrequests = data_request::get_expired_requests();
|
||||
$this->assertEmpty($expiredrequests);
|
||||
data_request::expire($expiredrequests);
|
||||
|
||||
// Confirm approved and exported.
|
||||
$request = new data_request($requestid);
|
||||
$this->assertEquals(api::DATAREQUEST_STATUS_DOWNLOAD_READY, $request->get('status'));
|
||||
$fileconditions = [
|
||||
'userid' => $user->id,
|
||||
'component' => 'tool_dataprivacy',
|
||||
'filearea' => 'export',
|
||||
'itemid' => $requestid,
|
||||
'contextid' => $usercontext->id,
|
||||
];
|
||||
$this->assertEquals(2, $DB->count_records('files', $fileconditions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for \tool_dataprivacy\data_request::is_expired()
|
||||
* Tests for the expected request status to protect from false positive/negative,
|
||||
|
||||
@@ -37,8 +37,8 @@ Feature: Delete custom licenses
|
||||
| Licence version | ##1 March 2019## |
|
||||
And I press "Save changes"
|
||||
And I follow "Private files" in the user menu
|
||||
And I upload "lib/editor/atto/tests/fixtures/moodle-logo.png" file to "Files" filemanager
|
||||
And I click on "moodle-logo.png" "link"
|
||||
And I upload "lib/tests/fixtures/gd-logo.png" file to "Files" filemanager
|
||||
And I click on "gd-logo.png" "link"
|
||||
And I set the field "Choose licence" to "Test licence"
|
||||
And I press "Update"
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -14,6 +14,6 @@ Feature: In a report, admin can see logstore visibility changes
|
||||
And I click on "Enable" "icon" in the "External database log" "table_row"
|
||||
And I navigate to "Reports > Config changes" in site administration
|
||||
Then the following should exist in the "reportbuilder-table" table:
|
||||
| User | Plugin | Setting | New value | Original value |
|
||||
| First name | Plugin | Setting | New value | Original value |
|
||||
| Admin User | logstore_standard | tool_logstore_visibility | 0 | 1 |
|
||||
| Admin User | logstore_database | tool_logstore_visibility | 1 | 0 |
|
||||
|
||||
@@ -62,8 +62,8 @@ Feature: Manage scheduled tasks
|
||||
And I press "Save changes"
|
||||
Then I should see "Changes saved"
|
||||
And the following should not exist in the "admintable" table:
|
||||
| Name | Component | Minute | Hour | Day | Day of week | Month |
|
||||
| Log table cleanup | Standard log | */5 | 1 | 2 | 4 | 3 |
|
||||
| Name | Minute | Hour | Day | Day of week | Month |
|
||||
| Log table cleanup | */5 | 1 | 2 | 4 | 3 |
|
||||
And I should see "Log table cleanup" in the "tr.table-primary" "css_element"
|
||||
|
||||
Scenario: Disabled plugin's tasks are labelled as disabled too
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -36,6 +36,7 @@ import {dispatchEvent} from 'core/event_dispatcher';
|
||||
import {eventTypes} from './events';
|
||||
import {get_string as getString} from 'core/str';
|
||||
import {prefetchStrings} from 'core/prefetch';
|
||||
import PendingPromise from 'core/pending';
|
||||
|
||||
/**
|
||||
* The minimum spacing for tour step to display.
|
||||
@@ -485,14 +486,22 @@ const Tour = class {
|
||||
return this.endTour();
|
||||
}
|
||||
|
||||
const pendingPromise = new PendingPromise(`tool_usertours/tour:_gotoStep-${stepConfig.stepNumber}`);
|
||||
|
||||
if (typeof stepConfig.delay !== 'undefined' && stepConfig.delay && !stepConfig.delayed) {
|
||||
stepConfig.delayed = true;
|
||||
window.setTimeout(this._gotoStep.bind(this), stepConfig.delay, stepConfig, direction);
|
||||
window.setTimeout(function(stepConfig, direction) {
|
||||
this._gotoStep(stepConfig, direction);
|
||||
pendingPromise.resolve();
|
||||
}, stepConfig.delay, stepConfig, direction);
|
||||
|
||||
return this;
|
||||
} else if (!stepConfig.orphan && !this.isStepActuallyVisible(stepConfig)) {
|
||||
let fn = direction == -1 ? 'getPreviousStepNumber' : 'getNextStepNumber';
|
||||
return this.gotoStep(this[fn](stepConfig.stepNumber), direction);
|
||||
const fn = direction == -1 ? 'getPreviousStepNumber' : 'getNextStepNumber';
|
||||
this.gotoStep(this[fn](stepConfig.stepNumber), direction);
|
||||
|
||||
pendingPromise.resolve();
|
||||
return this;
|
||||
}
|
||||
|
||||
this.hide();
|
||||
@@ -503,6 +512,7 @@ const Tour = class {
|
||||
this.dispatchEvent(eventTypes.stepRendered, {stepConfig});
|
||||
}
|
||||
|
||||
pendingPromise.resolve();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -820,12 +830,14 @@ const Tour = class {
|
||||
left: 0,
|
||||
});
|
||||
|
||||
const pendingPromise = new PendingPromise(`tool_usertours/tour:addStepToPage-${stepConfig.stepNumber}`);
|
||||
animationTarget
|
||||
.animate({
|
||||
scrollTop: this.calculateScrollTop(stepConfig),
|
||||
}).promise().then(function() {
|
||||
this.positionStep(stepConfig);
|
||||
this.revealStep(stepConfig);
|
||||
pendingPromise.resolve();
|
||||
return;
|
||||
}.bind(this))
|
||||
.catch(function() {
|
||||
@@ -897,6 +909,7 @@ const Tour = class {
|
||||
*/
|
||||
revealStep(stepConfig) {
|
||||
// Fade the step in.
|
||||
const pendingPromise = new PendingPromise(`tool_usertours/tour:revealStep-${stepConfig.stepNumber}`);
|
||||
this.currentStepNode.fadeIn('', $.proxy(function() {
|
||||
// Announce via ARIA.
|
||||
this.announceStep(stepConfig);
|
||||
@@ -910,6 +923,7 @@ const Tour = class {
|
||||
if (this.currentStepNode) {
|
||||
this.currentStepNode.focus();
|
||||
}
|
||||
pendingPromise.resolve();
|
||||
}, this), 100);
|
||||
|
||||
}, this));
|
||||
@@ -1157,6 +1171,7 @@ const Tour = class {
|
||||
return this;
|
||||
}
|
||||
|
||||
const pendingPromise = new PendingPromise('tool_usertours/tour:hide');
|
||||
if (this.currentStepNode && this.currentStepNode.length) {
|
||||
this.currentStepNode.hide();
|
||||
if (this.currentStepPopper) {
|
||||
@@ -1191,17 +1206,22 @@ const Tour = class {
|
||||
this.currentStepConfig = null;
|
||||
}
|
||||
|
||||
let fadeTime = 0;
|
||||
if (transition) {
|
||||
fadeTime = 400;
|
||||
}
|
||||
|
||||
// Remove the backdrop features.
|
||||
$('[data-flexitour="step-background"]').remove();
|
||||
$('[data-flexitour="step-backdrop"]').removeAttr('data-flexitour');
|
||||
$('[data-flexitour="backdrop"]').fadeOut(fadeTime, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
|
||||
const backdrop = $('[data-flexitour="backdrop"]');
|
||||
if (backdrop.length) {
|
||||
if (transition) {
|
||||
const backdropRemovalPromise = new PendingPromise('tool_usertours/tour:hide:backdrop');
|
||||
backdrop.fadeOut(400, function() {
|
||||
$(this).remove();
|
||||
backdropRemovalPromise.resolve();
|
||||
});
|
||||
} else {
|
||||
backdrop.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove aria-describedby and tabindex attributes.
|
||||
if (this.currentStepNode && this.currentStepNode.length) {
|
||||
@@ -1222,6 +1242,8 @@ const Tour = class {
|
||||
|
||||
this.currentStepNode = null;
|
||||
this.currentStepPopper = null;
|
||||
|
||||
pendingPromise.resolve();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,11 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
function init() {
|
||||
parent::init();
|
||||
|
||||
global $DB;
|
||||
if ($DB->get_dbfamily() !== 'mysql') {
|
||||
throw new moodle_exception('DB family not supported');
|
||||
}
|
||||
|
||||
// Set own custom attributes
|
||||
|
||||
// Get needed strings
|
||||
@@ -55,8 +60,6 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
function invoke() {
|
||||
parent::invoke();
|
||||
|
||||
$result = true;
|
||||
|
||||
// Set own core attributes
|
||||
$this->does_generate = ACTION_GENERATE_HTML;
|
||||
|
||||
@@ -125,11 +128,15 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
// If table, retrofit information and, if everything works,
|
||||
// go to the table edit action
|
||||
} else {
|
||||
// Get some params (table is mandatory here)
|
||||
$tableparam = required_param('table', PARAM_CLEAN);
|
||||
$afterparam = required_param('after', PARAM_CLEAN);
|
||||
// Get some params (table is mandatory here).
|
||||
$tableparam = required_param('table', PARAM_ALPHAEXT);
|
||||
$afterparam = required_param('after', PARAM_ALPHAEXT);
|
||||
|
||||
// Create one new xmldb_table
|
||||
if (empty($tableparam) || empty($afterparam)) {
|
||||
throw new moodle_exception('Invalid param value detected.');
|
||||
}
|
||||
|
||||
// Create one new xmldb_table.
|
||||
$table = new xmldb_table(strtolower(trim($tableparam)));
|
||||
$table->setComment($table->getName() . ' table retrofitted from MySQL');
|
||||
// Get fields info from ADODb
|
||||
@@ -147,7 +154,6 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
// Get PK, UK and indexes info from ADODb
|
||||
$dbindexes = $DB->get_indexes($tableparam);
|
||||
if ($dbindexes) {
|
||||
$lastkey = NULL; //To temp store the last key processed
|
||||
foreach ($dbindexes as $indexname => $dbindex) {
|
||||
// Add the indexname to the array
|
||||
$dbindex['name'] = $indexname;
|
||||
@@ -156,9 +162,6 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
$key = new xmldb_key(strtolower($dbindex['name']));
|
||||
// Set key with info retrofitted
|
||||
$key->setFromADOKey($dbindex);
|
||||
// Set default comment to PKs
|
||||
if ($key->getType() == XMLDB_KEY_PRIMARY) {
|
||||
}
|
||||
// Add key to the table
|
||||
$table->addKey($key);
|
||||
|
||||
@@ -172,18 +175,17 @@ class new_table_from_mysql extends XMLDBAction {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally, add the whole retroffited table to the structure
|
||||
// in the place specified
|
||||
// Finally, add the whole retrofitted table to the structure in the place specified.
|
||||
$structure->addTable($table, $afterparam);
|
||||
}
|
||||
|
||||
// Launch postaction if exists (leave this here!)
|
||||
if ($this->getPostAction() && $result) {
|
||||
if ($this->getPostAction()) {
|
||||
return $this->launch($this->getPostAction());
|
||||
}
|
||||
|
||||
// Return ok if arrived here
|
||||
return $result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-11
@@ -14,31 +14,29 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit tests for activities completed by classification.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace core_analytics;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
use advanced_testcase;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Unit tests for activities completed by classification.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @covers \core_analytics\local\indicator\community_of_inquiry_activity
|
||||
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class community_of_inquiry_activities_completed_by_testcase extends advanced_testcase {
|
||||
final class community_of_inquiry_activities_completed_by_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* availability_levels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function availability_levels() {
|
||||
public static function availability_levels(): array {
|
||||
return array(
|
||||
'activity' => array('activity'),
|
||||
'section' => array('section'),
|
||||
@@ -148,7 +146,7 @@ class community_of_inquiry_activities_completed_by_testcase extends advanced_tes
|
||||
$second = $startdate + WEEKSECS;
|
||||
$third = $startdate + (WEEKSECS * 2);
|
||||
$forth = $startdate + (WEEKSECS * 3);
|
||||
$this->assertCount(1, $method->invoke($indicator, $first, $first + WEEKSECS, $stu1));
|
||||
$this->assertCount(2, $method->invoke($indicator, $first, $first + WEEKSECS, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $second, $second + WEEKSECS, $stu1));
|
||||
$this->assertCount(0, $method->invoke($indicator, $third, $third + WEEKSECS, $stu1));
|
||||
$this->assertCount(2, $method->invoke($indicator, $forth, $forth + WEEKSECS, $stu1));
|
||||
@@ -52,7 +52,7 @@ abstract class backup_block_task extends backup_task {
|
||||
}
|
||||
|
||||
$this->blockid = $blockid;
|
||||
$this->blockname = $block->blockname;
|
||||
$this->blockname = clean_param($block->blockname, PARAM_PLUGIN);
|
||||
$this->contextid = context_block::instance($this->blockid)->id;
|
||||
$this->moduleid = $moduleid;
|
||||
$this->modulename = null;
|
||||
|
||||
@@ -36,7 +36,7 @@ require_once($CFG->libdir . '/completionlib.php');
|
||||
* @copyright 2014 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle2_test extends \advanced_testcase {
|
||||
final class moodle2_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests the availability field on modules and sections is correctly
|
||||
@@ -1146,7 +1146,6 @@ class moodle2_test extends \advanced_testcase {
|
||||
'filearea' => 'package',
|
||||
'itemid' => 0,
|
||||
'filepath' => '/',
|
||||
'filepath' => '/',
|
||||
'filename' => 'dummy.h5p',
|
||||
'addxapistate' => true,
|
||||
];
|
||||
|
||||
+10
-10
@@ -134,14 +134,14 @@ class core_backup_renderer extends plugin_renderer_base {
|
||||
$html .= $this->backup_detail_pair(get_string('backupmode', 'backup'), get_string('backupmode'.$details->mode, 'backup'));
|
||||
$html .= $this->backup_detail_pair(get_string('backupdate', 'backup'), userdate($details->backup_date));
|
||||
$html .= $this->backup_detail_pair(get_string('moodleversion', 'backup'),
|
||||
html_writer::tag('span', $details->moodle_release, array('class' => 'moodle_release')).
|
||||
html_writer::tag('span', '['.$details->moodle_version.']', array('class' => 'moodle_version sub-detail')));
|
||||
html_writer::tag('span', s($details->moodle_release), array('class' => 'moodle_release')).
|
||||
html_writer::tag('span', '[' . s($details->moodle_version) .']', array('class' => 'moodle_version sub-detail')));
|
||||
$html .= $this->backup_detail_pair(get_string('backupversion', 'backup'),
|
||||
html_writer::tag('span', $details->backup_release, array('class' => 'moodle_release')).
|
||||
html_writer::tag('span', '['.$details->backup_version.']', array('class' => 'moodle_version sub-detail')));
|
||||
html_writer::tag('span', s($details->backup_release), array('class' => 'moodle_release')).
|
||||
html_writer::tag('span', '[' . s($details->backup_version) . ']', array('class' => 'moodle_version sub-detail')));
|
||||
$html .= $this->backup_detail_pair(get_string('originalwwwroot', 'backup'),
|
||||
html_writer::tag('span', $details->original_wwwroot, array('class' => 'originalwwwroot')).
|
||||
html_writer::tag('span', '['.$details->original_site_identifier_hash.']', array('class' => 'sitehash sub-detail')));
|
||||
html_writer::tag('span', s($details->original_wwwroot), array('class' => 'originalwwwroot')).
|
||||
html_writer::tag('span', '[' . s($details->original_site_identifier_hash) . ']', array('class' => 'sitehash sub-detail')));
|
||||
if (!empty($details->include_file_references_to_external_content)) {
|
||||
$message = '';
|
||||
if (backup_general_helper::backup_is_samesite($details)) {
|
||||
@@ -169,8 +169,8 @@ class core_backup_renderer extends plugin_renderer_base {
|
||||
$html .= html_writer::start_tag('div', ['class' => 'backup-section',
|
||||
'role' => 'table', 'aria-labelledby' => 'backupcoursedetailsheader']);
|
||||
$html .= $this->output->heading(get_string('backupcoursedetails', 'backup'), 2, 'header', 'backupcoursedetailsheader');
|
||||
$html .= $this->backup_detail_pair(get_string('coursetitle', 'backup'), $details->course->title);
|
||||
$html .= $this->backup_detail_pair(get_string('courseid', 'backup'), $details->course->courseid);
|
||||
$html .= $this->backup_detail_pair(get_string('coursetitle', 'backup'), format_string($details->course->title));
|
||||
$html .= $this->backup_detail_pair(get_string('courseid', 'backup'), clean_param($details->course->courseid, PARAM_INT));
|
||||
|
||||
// Warning users about front page backups.
|
||||
if ($details->original_course_format === 'site') {
|
||||
@@ -188,7 +188,7 @@ class core_backup_renderer extends plugin_renderer_base {
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$html .= $this->backup_detail_pair(get_string('backupcoursesection', 'backup', $section->title), $value);
|
||||
$html .= $this->backup_detail_pair(get_string('backupcoursesection', 'backup', format_string($section->title)), $value);
|
||||
$table = null;
|
||||
foreach ($details->activities as $activitykey => $activity) {
|
||||
if ($activity->sectionid != $section->sectionid) {
|
||||
@@ -206,7 +206,7 @@ class core_backup_renderer extends plugin_renderer_base {
|
||||
$icon = new image_icon('monologo', '', $activity->modulename, ['class' => 'iconlarge icon-pre']);
|
||||
$table->data[] = array(
|
||||
$this->output->render($icon).$name,
|
||||
$activity->title,
|
||||
format_string($activity->title),
|
||||
($activity->settings[$activitykey.'_userinfo']) ? $yestick : $notick,
|
||||
);
|
||||
}
|
||||
|
||||
+2
-1
@@ -107,9 +107,10 @@ if (!has_any_capability(array(
|
||||
$PAGE->set_title($hdr);
|
||||
$output = $PAGE->get_renderer('core', 'badges');
|
||||
|
||||
if (($delete || $archive) && has_capability('moodle/badges:deletebadge', $PAGE->context)) {
|
||||
if ($delete || $archive) {
|
||||
$badgeid = ($archive != 0) ? $archive : $delete;
|
||||
$badge = new badge($badgeid);
|
||||
require_capability('moodle/badges:deletebadge', $badge->get_context());
|
||||
if (!$confirm) {
|
||||
echo $output->header();
|
||||
// Archive this badge?
|
||||
|
||||
@@ -17,7 +17,7 @@ Feature: Manage comments made by users
|
||||
Scenario: View and filter site comments
|
||||
When I navigate to "Reports > Comments" in site administration
|
||||
And the following should exist in the "reportbuilder-table" table:
|
||||
| -0- | Content | Context URL |
|
||||
| First name | Content | Context URL |
|
||||
| Admin User | Uno | Course: Course 1 |
|
||||
| Admin User | Dos | Course: Course 1 |
|
||||
| Admin User | Tres | Course: Course 1 |
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
@core @core_contentbank @core_h5p @contenttype_h5p @_file_upload @_switch_iframe @javascript
|
||||
@core @core_contentbank @core_h5p @contenttype_h5p @_switch_iframe @javascript
|
||||
Feature: H5P file upload to content bank for admins
|
||||
In order import new H5P content to content bank
|
||||
As an admin
|
||||
I need to be able to upload a new .h5p file to content bank
|
||||
|
||||
Background:
|
||||
Given the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
Given the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I turn editing mode on
|
||||
And the following config values are set as admin:
|
||||
| unaddableblocks | | theme_boost|
|
||||
|
||||
@@ -19,13 +19,10 @@ Feature: H5P file upload to content bank for non admins
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| teacher2 | C1 | editingteacher |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And the following "user private file" exists:
|
||||
| user | teacher1 |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
|
||||
Scenario: Teachers can not access system level content bank
|
||||
Given I turn editing mode on
|
||||
@@ -128,11 +125,10 @@ Feature: H5P file upload to content bank for non admins
|
||||
And I should not see "filltheblanks.h5p"
|
||||
|
||||
Scenario: Teachers can not see existing contents when libraries are not installed
|
||||
Given I log out
|
||||
Given the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I navigate to "H5P > Manage H5P content types" in site administration
|
||||
And I should not see "Fill in the Blanks"
|
||||
When I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "H5P content type" filemanager
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @_file_upload @javascript
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @javascript
|
||||
Feature: Delete H5P file from the content bank
|
||||
In order remove H5P content from the content bank
|
||||
As an admin
|
||||
I need to be able to delete any H5P content from the content bank
|
||||
|
||||
Background:
|
||||
Given the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And the following config values are set as admin:
|
||||
| unaddableblocks | | theme_boost|
|
||||
And I add the "Navigation" block if not present
|
||||
And I configure the "Navigation" block
|
||||
And I set the following fields to these values:
|
||||
| Page contexts | Display throughout the entire site |
|
||||
And I press "Save changes"
|
||||
And I click on "Site pages" "list_item" in the "Navigation" "block"
|
||||
And I click on "Content bank" "link" in the "Navigation" "block"
|
||||
Given the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I am on the "Content bank" page logged in as "admin"
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
@@ -32,14 +18,16 @@ Feature: Delete H5P file from the content bank
|
||||
And I click on "Save changes" "button"
|
||||
|
||||
Scenario: Admins can delete content from the content bank
|
||||
Given I click on "More" "button"
|
||||
Given I wait "2" seconds
|
||||
And I click on "More" "button"
|
||||
And I should see "Delete"
|
||||
And I click on "Delete" "link" in the ".cb-toolbar-container" "css_element"
|
||||
And I click on "Delete" "link"
|
||||
And I should see "Are you sure you want to delete the content 'content2delete.h5p'"
|
||||
And I should not see "The content will only be deleted from the content bank"
|
||||
And I click on "Cancel" "button" in the "Delete content" "dialogue"
|
||||
Then I should see "content2delete.h5p"
|
||||
And I click on "More" "button"
|
||||
And I wait "2" seconds
|
||||
And I click on "More" "button"
|
||||
And I click on "Delete" "link" in the ".cb-toolbar-container" "css_element"
|
||||
And I click on "Delete" "button" in the "Delete content" "dialogue"
|
||||
And I wait until the page is ready
|
||||
@@ -56,40 +44,38 @@ Feature: Delete H5P file from the content bank
|
||||
And the following "role assigns" exist:
|
||||
| user | role | contextlevel | reference |
|
||||
| manager | manager | System | |
|
||||
And I log out
|
||||
And I log in as "manager"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/find-the-words.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
When I click on "Site pages" "list_item" in the "Navigation" "block"
|
||||
And I click on "Content bank" "link" in the "Navigation" "block"
|
||||
And the following "user private file" exists:
|
||||
| user | manager |
|
||||
| filepath | h5p/tests/fixtures/find-the-words.h5p |
|
||||
When I am on the "Content bank" page logged in as "manager"
|
||||
And I should see "content2delete.h5p"
|
||||
And I follow "content2delete.h5p"
|
||||
And I wait "2" seconds
|
||||
And I click on "More" "button"
|
||||
Then I should not see "Delete"
|
||||
And I click on "Content bank" "link"
|
||||
And I am on the "Content bank" page
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "find-the-words.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I click on "More" "button"
|
||||
And I wait "2" seconds
|
||||
And I click on "More" "button"
|
||||
And I should see "Delete"
|
||||
|
||||
Scenario: The number of times a content is used is displayed before removing it
|
||||
Given I follow "Dashboard"
|
||||
And I follow "Manage private files..."
|
||||
Given I am on the "My private files" page
|
||||
And I click on "Add..." "button"
|
||||
And I select "Content bank" repository in file picker
|
||||
And I click on "content2delete.h5p" "file" in repository content area
|
||||
And I click on "Link to the file" "radio"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
When I click on "Site pages" "list_item" in the "Navigation" "block"
|
||||
And I click on "Content bank" "link" in the "Navigation" "block"
|
||||
And I am on the "Content bank" page
|
||||
And I follow "content2delete.h5p"
|
||||
And I click on "More" "button"
|
||||
And I wait "2" seconds
|
||||
And I click on "More" "button"
|
||||
And I click on "Delete" "link" in the ".cb-toolbar-container" "css_element"
|
||||
Then I should see "Are you sure you want to delete the content 'content2delete.h5p'"
|
||||
And I should see "The content will only be deleted from the content bank"
|
||||
|
||||
@@ -5,10 +5,7 @@ Feature: Content bank use editor feature
|
||||
I need to be able to access the edition options
|
||||
|
||||
Background:
|
||||
Given the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And I log in as "admin"
|
||||
Given I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And the following config values are set as admin:
|
||||
@@ -25,10 +22,9 @@ Feature: Content bank use editor feature
|
||||
Then the "[data-action=Add-content]" "css_element" should be disabled
|
||||
|
||||
Scenario: Users can see the Add button if there is content type available for creation
|
||||
Given I follow "Dashboard"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
Given the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I click on "Site pages" "list_item" in the "Navigation" "block"
|
||||
And I click on "Content bank" "link" in the "Navigation" "block"
|
||||
And I click on "Upload" "link"
|
||||
@@ -44,10 +40,9 @@ Feature: Content bank use editor feature
|
||||
And I should see "Fill in the Blanks"
|
||||
|
||||
Scenario: Users can edit content if they have the required permission
|
||||
Given I follow "Dashboard"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
Given the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I click on "Site pages" "list_item" in the "Navigation" "block"
|
||||
And I click on "Content bank" "link" in the "Navigation" "block"
|
||||
And I click on "Upload" "link"
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @_file_upload @_switch_iframe @javascript
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @_switch_iframe @javascript
|
||||
Feature: Confirm content bank events are triggered
|
||||
In order to log content bank actions
|
||||
As an admin
|
||||
I need to be able to check triggered events
|
||||
|
||||
Background:
|
||||
Given the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And I log in as "admin"
|
||||
And I navigate to "H5P > Manage H5P content types" in site administration
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "H5P content type" filemanager
|
||||
And I click on "Upload H5P content types" "button" in the "#fitem_id_uploadlibraries" "css_element"
|
||||
And the following "courses" exist:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "contentbank content" exist:
|
||||
| contextlevel | reference | contenttype | user | contentname | filepath |
|
||||
| Course | C1 | contenttype_h5p | admin | Existing | /h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And I follow "Dashboard"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And the following "user private file" exists:
|
||||
| user | admin |
|
||||
| filepath | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
And the following config values are set as admin:
|
||||
| unaddableblocks | | theme_boost|
|
||||
And I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
|
||||
Scenario: Content created and uploaded events when uploading a content file
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @_file_upload @javascript
|
||||
@core @core_contentbank @core_h5p @contentbank_h5p @javascript
|
||||
Feature: Store the content bank view preference
|
||||
In order to consistantly view the content bank in icons or details view
|
||||
As an admin
|
||||
I need to be able to store my view preference
|
||||
|
||||
Background:
|
||||
Given the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
Given the following "user private files" exist:
|
||||
| user | filepath |
|
||||
| admin | h5p/tests/fixtures/filltheblanks.h5p |
|
||||
| admin | h5p/tests/fixtures/greeting-card.h5p |
|
||||
And I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I upload "h5p/tests/fixtures/greeting-card.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And the following config values are set as admin:
|
||||
@@ -55,8 +52,7 @@ Feature: Store the content bank view preference
|
||||
And I should not see "Last modified"
|
||||
|
||||
Scenario: Display the number of times a content is used in file details view
|
||||
Given I follow "Dashboard"
|
||||
And I follow "Manage private files..."
|
||||
Given I am on the "My private files" page
|
||||
And I click on "Add..." "button"
|
||||
And I select "Content bank" repository in file picker
|
||||
And I click on "fib.h5p" "file" in repository content area
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
@core @core_course
|
||||
Feature: Students can view their grades and activity reports
|
||||
In order for students to view their grades and activity reports
|
||||
As a teacher
|
||||
I should be able to change the report display settings
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
|
||||
Scenario Outline: Grade reports can be displayed or hidden to students
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | showgrades |
|
||||
| Course 1 | C1 | <gradevisibility> |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
When I am on the "student1" "user > profile" page logged in as student1
|
||||
And I click on "Course 1" "link"
|
||||
Then I <gradelinkvisibility> see "Grades overview"
|
||||
|
||||
Examples:
|
||||
| gradevisibility | gradelinkvisibility |
|
||||
| 1 | should |
|
||||
| 0 | should not |
|
||||
|
||||
Scenario Outline: Activity reports can be displayed or hidden to students
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | showreports |
|
||||
| Course 1 | C1 | <reportvisibility> |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
When I am on the "student1" "user > profile" page logged in as student1
|
||||
And I click on "Course 1" "link"
|
||||
Then I <reportlinkvisibility> see "Today's logs"
|
||||
And I <reportlinkvisibility> see "All logs"
|
||||
And I <reportlinkvisibility> see "Outline report"
|
||||
And I <reportlinkvisibility> see "Complete report"
|
||||
|
||||
Examples:
|
||||
| reportvisibility | reportlinkvisibility |
|
||||
| 1 | should |
|
||||
| 0 | should not |
|
||||
@@ -39,8 +39,7 @@ require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
||||
* @copyright 2012 Jerome Mouneyrac
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class externallib_test extends externallib_advanced_testcase {
|
||||
//core_course_externallib_testcase
|
||||
final class externallib_test extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests set up
|
||||
@@ -608,7 +607,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function course_empty_field_provider(): array {
|
||||
public static function course_empty_field_provider(): array {
|
||||
return [
|
||||
[[
|
||||
'fullname' => '',
|
||||
@@ -3167,7 +3166,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test cases for the get_enrolled_courses_by_timeline_classification test.
|
||||
*/
|
||||
public function get_get_enrolled_courses_by_timeline_classification_test_cases():array {
|
||||
public static function get_get_enrolled_courses_by_timeline_classification_test_cases(): array {
|
||||
$now = time();
|
||||
$day = 86400;
|
||||
|
||||
@@ -3424,16 +3423,6 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong sort direction' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'all',
|
||||
'limit' => 5,
|
||||
'offset' => 5,
|
||||
'sort' => "ul.timeaccess abcdasc",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid sort direction in $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong sort direction' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'all',
|
||||
@@ -3454,16 +3443,6 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field name' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'all',
|
||||
'limit' => 5,
|
||||
'offset' => 5,
|
||||
'sort' => "ul.foobar",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field separator' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'all',
|
||||
|
||||
@@ -21,12 +21,9 @@ Feature: Default value for the textarea custom field can contain images
|
||||
And the following "custom field categories" exist:
|
||||
| name | component | area | itemid |
|
||||
| Category for test | core_course | course | 0 |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And the following "user private files" exist:
|
||||
| user | filepath | filename |
|
||||
| admin | lib/tests/fixtures/gd-logo.png | gd-logo.png |
|
||||
| user | filepath |
|
||||
| admin | lib/tests/fixtures/gd-logo.png |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Courses > Course custom fields" in site administration
|
||||
And I click on "Add a new custom field" "link"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# This feature has Atto-specific steps. See MDL-75913 for further details.
|
||||
@core @core_course @core_customfield @javascript
|
||||
Feature: Teachers can edit course custom fields
|
||||
In order to have additional data on the course
|
||||
@@ -25,12 +24,9 @@ Feature: Teachers can edit course custom fields
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And the following "user private files" exist:
|
||||
| user | filepath | filename |
|
||||
| admin | lib/tests/fixtures/gd-logo.png | gd-logo.png |
|
||||
| user | filepath |
|
||||
| admin | lib/tests/fixtures/gd-logo.png |
|
||||
|
||||
Scenario: Display custom fields on course edit form
|
||||
When I log in as "teacher1"
|
||||
|
||||
@@ -83,11 +83,11 @@ Feature: Cohort enrolment management
|
||||
And I navigate to course participants
|
||||
# Verifies students 1 and 4 are in the cohort and student 2 is not any more.
|
||||
And the following should exist in the "participants" table:
|
||||
| First name / Last name | Email address | Roles | Groups |
|
||||
| First name | Email address | Roles | Groups |
|
||||
| Sandra Cole | s1@example.com | Student | Alpha1 cohort |
|
||||
| Jane Doe | s4@example.com | Student | Alpha1 cohort |
|
||||
And the following should not exist in the "participants" table:
|
||||
| First name / Last name | Email address | Roles | Groups |
|
||||
| First name | Email address | Roles | Groups |
|
||||
| John Smith | s2@example.com | Student | Alpha1 cohort |
|
||||
|
||||
@javascript
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace enrol_lti\local\ltiadvantage\entity;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \enrol_lti\local\ltiadvantage\entity\user
|
||||
*/
|
||||
class user_test extends \advanced_testcase {
|
||||
final class user_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test creation of a user instance using the factory method.
|
||||
@@ -64,7 +64,7 @@ class user_test extends \advanced_testcase {
|
||||
*
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function create_data_provider(): array {
|
||||
public static function create_data_provider(): array {
|
||||
global $CFG;
|
||||
return [
|
||||
'Valid create, only required args provided' => [
|
||||
@@ -272,7 +272,7 @@ class user_test extends \advanced_testcase {
|
||||
*
|
||||
* @return array the data for testing.
|
||||
*/
|
||||
public function create_from_resource_link_data_provider(): array {
|
||||
public static function create_from_resource_link_data_provider(): array {
|
||||
global $CFG;
|
||||
return [
|
||||
'Valid creation, all args provided explicitly' => [
|
||||
@@ -511,7 +511,7 @@ class user_test extends \advanced_testcase {
|
||||
*
|
||||
* @return array the array of test data.
|
||||
*/
|
||||
public function setters_getters_data_provider(): array {
|
||||
public static function setters_getters_data_provider(): array {
|
||||
global $CFG;
|
||||
return [
|
||||
'Testing set_resourcelinkid with valid id' => [
|
||||
@@ -620,12 +620,12 @@ class user_test extends \advanced_testcase {
|
||||
],
|
||||
'Testing set_maildisplay with a valid int: 2' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '1',
|
||||
'arg' => '2',
|
||||
'expectations' => [
|
||||
'valid' => true,
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with invalid int' => [
|
||||
'Testing set_maildisplay with invalid int: -1' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '-1',
|
||||
'expectations' => [
|
||||
@@ -634,7 +634,7 @@ class user_test extends \advanced_testcase {
|
||||
'exceptionmessage' => "Invalid maildisplay value '-1'. Must be in the range {0..2}."
|
||||
]
|
||||
],
|
||||
'Testing set_maildisplay with invalid int' => [
|
||||
'Testing set_maildisplay with invalid int: 3' => [
|
||||
'methodname' => 'maildisplay',
|
||||
'arg' => '3',
|
||||
'expectations' => [
|
||||
@@ -659,7 +659,7 @@ class user_test extends \advanced_testcase {
|
||||
'exceptionmessage' => 'Invalid lang value. Cannot be an empty string.'
|
||||
]
|
||||
],
|
||||
'Testing set_lang with an empty string' => [
|
||||
'Testing set_lang with invalid lang code' => [
|
||||
'methodname' => 'lang',
|
||||
'arg' => 'ff',
|
||||
'expectations' => [
|
||||
|
||||
@@ -38,12 +38,12 @@ require_once($CFG->dirroot . '/enrol/externallib.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since Moodle 2.4
|
||||
*/
|
||||
class externallib_test extends externallib_advanced_testcase {
|
||||
final class externallib_test extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* dataProvider for test_get_enrolled_users_visibility().
|
||||
*/
|
||||
public function get_enrolled_users_visibility_provider() {
|
||||
public static function get_enrolled_users_visibility_provider(): array {
|
||||
return array(
|
||||
'Course without groups, default behavior (not filtering by cap, group, active)' =>
|
||||
array(
|
||||
@@ -232,7 +232,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
),
|
||||
),
|
||||
|
||||
'Course with separate groups, filtering by withcapability (having moodle/role:review)' =>
|
||||
'Course with separate groups, filtering by withcapability (having moodle/role:review & moodle/course:bulkmessaging)' =>
|
||||
array(
|
||||
'settings' => array(
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
@@ -1125,7 +1125,7 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
/**
|
||||
* dataProvider for test_submit_user_enrolment_form().
|
||||
*/
|
||||
public function submit_user_enrolment_form_provider() {
|
||||
public static function submit_user_enrolment_form_provider(): array {
|
||||
$now = new \DateTime();
|
||||
|
||||
$nextmonth = clone($now);
|
||||
|
||||
@@ -14,9 +14,6 @@ Feature: Render H5P content using filters
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
And the "displayh5p" filter is "on"
|
||||
And the following config values are set as admin:
|
||||
| allowedsources | https://moodle.h5p.com/content/[id]/embed | filter_displayh5p |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@editor @editor_atto @atto @atto_h5p @filter @filter_displayh5p @core_h5p @_file_upload @_switch_iframe
|
||||
@editor @filter @filter_displayh5p @core_h5p @_switch_iframe
|
||||
Feature: Inline editing H5P content anywhere
|
||||
In order to edit an existing H5P content
|
||||
As a user
|
||||
@@ -30,31 +30,25 @@ Feature: Inline editing H5P content anywhere
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/course:update | Allow | teacher | System | |
|
||||
| moodle/course:update | Allow | student | System | |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| private_files | System | 1 | my-index | side-post |
|
||||
|
||||
@javascript @mod @mod_page
|
||||
Scenario: Edit H5P content from a page using link to private file
|
||||
Given the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/h5p:updatelibraries | Allow | editingteacher | System | |
|
||||
And I log in as "teacher1"
|
||||
# Upload the H5P to private user files.
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/greeting-card.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And the following "user private file" exists:
|
||||
| user | teacher1 |
|
||||
| filepath | h5p/tests/fixtures/greeting-card.h5p |
|
||||
# Add H5P content to the page.
|
||||
And I am on "Course 1" course homepage
|
||||
And I am on the "PageName1" "page activity" page
|
||||
And I am on the "PageName1" "page activity" page logged in as "teacher1"
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Insert H5P" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Configure H5P content" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P content" "dialogue"
|
||||
And I select "Private files" repository in file picker
|
||||
And I click on "greeting-card.h5p" "file" in repository content area
|
||||
And I click on "Link to the file" "radio"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P content" "dialogue"
|
||||
And I click on "Save and display" "button"
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
@@ -92,13 +86,13 @@ Feature: Inline editing H5P content anywhere
|
||||
# Add H5P content to the page.
|
||||
And I am on the "PageName1" "page activity" page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Insert H5P" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Configure H5P content" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P content" "dialogue"
|
||||
And I select "Content bank" repository in file picker
|
||||
And I click on "Greeting card" "file" in repository content area
|
||||
And I click on "Link to the file" "radio"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P content" "dialogue"
|
||||
And I click on "Save and display" "button"
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
@@ -136,13 +130,13 @@ Feature: Inline editing H5P content anywhere
|
||||
# Add H5P content to the page.
|
||||
And I am on the "PageName1" "page activity" page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Insert H5P" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Configure H5P content" "button" in the "#fitem_id_page" "css_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P content" "dialogue"
|
||||
And I select "Content bank" repository in file picker
|
||||
And I click on "Greeting card" "file" in repository content area
|
||||
And I click on "Make a copy of the file" "radio"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P content" "dialogue"
|
||||
And I click on "Save and display" "button"
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
@@ -182,9 +176,9 @@ Feature: Inline editing H5P content anywhere
|
||||
# Add H5P content to the page.
|
||||
And I am on the "PageName1" "page activity" page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I click on "Insert H5P" "button" in the "#fitem_id_page" "css_element"
|
||||
And I set the field with xpath "//input[@data-region='h5pfile']" to "https://moodle.h5p.com/content/1290772960722742119"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Configure H5P content" "button" in the "#fitem_id_page" "css_element"
|
||||
And I set the field "H5P URL or file upload" to "https://moodle.h5p.com/content/1290772960722742119"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P content" "dialogue"
|
||||
And I click on "Save and display" "button"
|
||||
And ".h5p-placeholder" "css_element" should exist
|
||||
And I switch to "h5pcontent" iframe
|
||||
@@ -225,13 +219,13 @@ Feature: Inline editing H5P content anywhere
|
||||
| Text block title | H5PTest |
|
||||
| Content | - |
|
||||
And I configure the "H5PTest" block
|
||||
And I click on "Insert H5P" "button" in the "//div[contains(@id,'fitem_id_config_text')]" "xpath_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Configure H5P content" "button" in the "//div[contains(@id,'fitem_id_config_text')]" "xpath_element"
|
||||
And I click on "Browse repositories..." "button" in the "Insert H5P content" "dialogue"
|
||||
And I select "Content bank" repository in file picker
|
||||
And I click on "Greeting card" "file" in repository content area
|
||||
And I click on "Make a copy of the file" "radio"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
|
||||
And I click on "Insert H5P" "button" in the "Insert H5P content" "dialogue"
|
||||
And I click on "Save changes" "button" in the "Configure H5PTest block" "dialogue"
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
|
||||
@@ -14,26 +14,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace filter_multilang;
|
||||
|
||||
/**
|
||||
* Unit tests.
|
||||
* Tests for filter_multilang.
|
||||
*
|
||||
* @package filter_multilang
|
||||
* @category test
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace filter_multilang;
|
||||
|
||||
use filter_multilang;
|
||||
|
||||
/**
|
||||
* Tests for filter_multilang.
|
||||
*
|
||||
* @copyright 2019 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class filter_test extends \advanced_testcase {
|
||||
final class filter_test extends \advanced_testcase {
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
@@ -62,7 +53,7 @@ class filter_test extends \advanced_testcase {
|
||||
/**
|
||||
* Data provider for multi-language filtering tests.
|
||||
*/
|
||||
public function multilang_testcases() {
|
||||
public static function multilang_testcases(): array {
|
||||
return [
|
||||
'Basic case EN' => [
|
||||
'English',
|
||||
@@ -79,7 +70,7 @@ class filter_test extends \advanced_testcase {
|
||||
'<span lang="fr" class="multilang">Français</span><span class="multilang" lang="en">English</span>',
|
||||
'en',
|
||||
],
|
||||
'Reversed input order EN' => [
|
||||
'Reversed input order FR' => [
|
||||
'Français',
|
||||
'<span lang="fr" class="multilang">Français</span><span class="multilang" lang="en">English</span>',
|
||||
'fr',
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ function filter_tex_sanitize_formula(string $texexp): string {
|
||||
'\afterassignment', '\expandafter', '\noexpand', '\special',
|
||||
'\let', '\futurelet', '\else', '\fi', '\chardef', '\makeatletter', '\afterground',
|
||||
'\noexpand', '\line', '\mathcode', '\item', '\section', '\mbox', '\declarerobustcommand',
|
||||
'\ExplSyntaxOn',
|
||||
'\ExplSyntaxOn', '\pdffiledump',
|
||||
];
|
||||
|
||||
$allowlist = ['inputenc'];
|
||||
|
||||
@@ -49,6 +49,7 @@ class lib_test extends advanced_testcase {
|
||||
['x\ =\ \frac{\sqrt{144}}{2}\ \times\ (y\ +\ 12)', 'x\ =\ \frac{\sqrt{144}}{2}\ \times\ (y\ +\ 12)'],
|
||||
['\usepackage[latin1]{inputenc}', '\usepackage[latin1]{inputenc}'],
|
||||
['\newcommand{\A}{\verbatiminput}', '\newforbiddenkeyword_command{\A}{\verbatimforbiddenkeyword_input}'],
|
||||
['\pdffiledump offset 0 length', 'forbiddenkeyword_\pdffiledump offset 0 length'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -14,14 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit test for the filter_urltolink
|
||||
*
|
||||
* @package filter_urltolink
|
||||
* @category phpunit
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace filter_urltolink;
|
||||
|
||||
@@ -32,10 +24,22 @@ defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/filter/urltolink/filter.php'); // Include the code to test
|
||||
|
||||
/**
|
||||
* Unit test for the filter_urltolink
|
||||
*
|
||||
* @package filter_urltolink
|
||||
* @category test
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class filter_test extends \basic_testcase {
|
||||
|
||||
class filter_test extends \basic_testcase {
|
||||
|
||||
function get_convert_urls_into_links_test_cases() {
|
||||
/**
|
||||
* Data provider for {@see test_convert_urls_into_links}
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_convert_urls_into_links_test_cases(): array {
|
||||
// Create a 4095 and 4096 long URLs.
|
||||
$superlong4095 = str_pad('http://www.superlong4095.com?this=something', 4095, 'a');
|
||||
$superlong4096 = str_pad('http://www.superlong4096.com?this=something', 4096, 'a');
|
||||
@@ -165,7 +169,6 @@ class filter_test extends \basic_testcase {
|
||||
'URL: <span style="kasd"> my link to http://google.com </span>' => 'URL: <span style="kasd"> my link to <a href="http://google.com" class="_blanktarget">http://google.com</a> </span>',
|
||||
// Nested tags test.
|
||||
'<b><i>www.google.com</i></b>' => '<b><i><a href="http://www.google.com" class="_blanktarget">www.google.com</a></i></b>',
|
||||
'<input type="submit" value="Go to http://moodle.org">' => '<input type="submit" value="Go to http://moodle.org">',
|
||||
// Test realistic content.
|
||||
'<p><span style="color: rgb(37, 37, 37); font-family: sans-serif; line-height: 22.3999996185303px;">Lorem ipsum amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut http://google.com aliquip ex ea <a href="http://google.com">commodo consequat</a>. Duis aute irure in reprehenderit in excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing mollit anim id est laborum.</span><br></p>'
|
||||
=>
|
||||
|
||||
@@ -101,16 +101,24 @@ class get_enrolled_users_for_search_widget extends external_api {
|
||||
|
||||
$users = [];
|
||||
|
||||
$userfieldsapi = \core_user\fields::for_identity($coursecontext, false)->with_userpic();
|
||||
$extrauserfields = $userfieldsapi->get_required_fields([\core_user\fields::PURPOSE_IDENTITY]);
|
||||
|
||||
while ($userdata = $gui->next_user()) {
|
||||
$guiuser = $userdata->user;
|
||||
$user = new \stdClass();
|
||||
$user->fullname = fullname($guiuser);
|
||||
foreach (\core_user\fields::get_name_fields() as $field) {
|
||||
$user->$field = $guiuser->$field ?? null;
|
||||
}
|
||||
$user->id = $guiuser->id;
|
||||
$user->url = (new moodle_url($actionbaseurl, ['id' => $courseid, 'userid' => $guiuser->id]))->out(false);
|
||||
$userpicture = new \user_picture($guiuser);
|
||||
$userpicture->size = 1;
|
||||
$user->profileimage = $userpicture->get_url($PAGE)->out(false);
|
||||
$user->email = $guiuser->email;
|
||||
foreach ($extrauserfields as $field) {
|
||||
$user->$field = $userdata->user->$field ?? null;
|
||||
}
|
||||
$user->active = false;
|
||||
|
||||
$users[] = $user;
|
||||
|
||||
+20
-10
@@ -25,6 +25,7 @@ use core_external\external_value;
|
||||
use core_external\external_warnings;
|
||||
use core_external\restricted_context_exception;
|
||||
use core_user;
|
||||
use user_picture;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
@@ -94,17 +95,26 @@ class get_enrolled_users_for_selector extends external_api {
|
||||
|
||||
$users = [];
|
||||
|
||||
while ($userdata = $gui->next_user()) {
|
||||
$guiuser = $userdata->user;
|
||||
$user = new \stdClass();
|
||||
$user->fullname = fullname($guiuser);
|
||||
$user->id = $guiuser->id;
|
||||
$userpicture = new \user_picture($guiuser);
|
||||
$userpicture->size = 1;
|
||||
$user->profileimage = $userpicture->get_url($PAGE)->out(false);
|
||||
$user->email = $guiuser->email;
|
||||
$userfieldsapi = \core_user\fields::for_identity($coursecontext, false)->with_userpic();
|
||||
$extrauserfields = $userfieldsapi->get_required_fields([\core_user\fields::PURPOSE_IDENTITY]);
|
||||
|
||||
$users[] = $user;
|
||||
while ($userdata = $gui->next_user()) {
|
||||
$userforselector = new \stdClass();
|
||||
$userforselector->id = $userdata->user->id;
|
||||
$userforselector->fullname = fullname($userdata->user);
|
||||
foreach (\core_user\fields::get_name_fields() as $field) {
|
||||
$userforselector->$field = $userdata->user->$field ?? null;
|
||||
}
|
||||
$userpicture = new user_picture($userdata->user);
|
||||
$userpicture->size = 1;
|
||||
$userforselector->profileimageurl = $userpicture->get_url($PAGE)->out(false);
|
||||
$userpicture->size = 0; // Size f2.
|
||||
$userforselector->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
|
||||
foreach ($extrauserfields as $field) {
|
||||
$userforselector->$field = $userdata->user->$field ?? null;
|
||||
}
|
||||
|
||||
$users[] = $userforselector;
|
||||
}
|
||||
$gui->close();
|
||||
|
||||
|
||||
@@ -70,3 +70,31 @@ Feature: Display marking guide information to students
|
||||
| criteria | description | remark | maxscore | criteriascore |
|
||||
| Grade Criteria 1 | Grade 1 description for students | Excellent work! | 70 | 50 / 70 |
|
||||
| Grade Criteria 2 | Grade 2 description for students | Try harder | 30 | 20 / 30 |
|
||||
|
||||
Scenario: Confirm that marking guide definition is retained when grading method is changed
|
||||
Given I am on the "Assign 1" "assign activity" page
|
||||
And I go to "Student 1" "Assign 1" activity advanced grading page
|
||||
And I grade by filling the marking guide with:
|
||||
| Grade Criteria 1 | 70 | Well done! |
|
||||
| Grade Criteria 2 | 20 | Great work |
|
||||
And I press "Save changes"
|
||||
And I am on the "Assign 1" "assign activity editing" page
|
||||
And I set the following fields to these values:
|
||||
| Grading method | Simple direct grading |
|
||||
And I press "Save and return to course"
|
||||
When I go to "Assign 1" advanced grading page
|
||||
Then I should not see "Assign 1 marking guide Ready for use"
|
||||
And I should not see "Grade Critera 1"
|
||||
And I should not see "Grade Critera 2"
|
||||
And I am on the "Course 1" "grades > Grader report > View" page
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -2- | -3- |
|
||||
| Student 1 | student1@example.com | 90 |
|
||||
And I am on the "Assign 1" "assign activity editing" page
|
||||
And I set the following fields to these values:
|
||||
| Grading method | Marking guide |
|
||||
And I press "Save and return to course"
|
||||
And I go to "Assign 1" advanced grading page
|
||||
And I should see "Assign 1 marking guide Ready for use"
|
||||
And I should see "Grade Criteria 1"
|
||||
And I should see "Grade Criteria 2"
|
||||
|
||||
@@ -7,12 +7,14 @@ Feature: Teacher can delete marking guide
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | One | teacher1@example.com |
|
||||
| student1 | Student | One | student1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | advancedgradingmethod_submissions |
|
||||
| assign | C1 | Assign 1 | guide |
|
||||
@@ -25,13 +27,19 @@ Feature: Teacher can delete marking guide
|
||||
| Criterion 1 | Criterion 1 description for student | Criterion 1 description for markers | 100 |
|
||||
And I press "Save marking guide and make it ready"
|
||||
|
||||
@javascript
|
||||
Scenario: Delete a marking guide
|
||||
Given I am on the "Course 1" course page
|
||||
Given I am on the "Assign 1" "assign activity" page
|
||||
And I go to "Student One" "Assign 1" activity advanced grading page
|
||||
And I grade by filling the marking guide with:
|
||||
| Criterion 1 | 70 | Well done! |
|
||||
And I press "Save changes"
|
||||
And I go to "Assign 1" advanced grading page
|
||||
When I click on "Delete the currently defined form" "link"
|
||||
Then I should see "You are going to delete the grading form 'Marking guide 1' and all the associated information from 'Assign 1 (Submissions)'"
|
||||
And I press "Cancel"
|
||||
# Confirm that marking guide was not deleted if Cancel is pressed
|
||||
Then I should see "Marking guide 1 Ready for use"
|
||||
And I should see "Marking guide 1 Ready for use"
|
||||
And I should see "Criterion 1"
|
||||
And I click on "Delete the currently defined form" "link"
|
||||
And I press "Continue"
|
||||
@@ -39,3 +47,7 @@ Feature: Teacher can delete marking guide
|
||||
And I should see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I should not see "Marking guide 1 Ready for use"
|
||||
And I should not see "Criterion 1"
|
||||
And I am on the "Course 1" "grades > Grader report > View" page
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -2- | -3- |
|
||||
| Student One | student1@example.com | 70 |
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
@gradingform @gradingform_guide
|
||||
Feature: Teacher can edit a marking guide state
|
||||
In order to change marking guide back to draft
|
||||
As a teacher
|
||||
I need to be able to edit the marking guide status
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | advancedgradingmethod_submissions |
|
||||
| assign | C1 | Assign 1 | guide |
|
||||
|
||||
Scenario: Marking guide state can be changed to draft
|
||||
Given I am on the "Course 1" course page logged in as teacher1
|
||||
And I go to "Assign 1" advanced grading definition page
|
||||
And I set the following fields to these values:
|
||||
| Name | Assign 1 marking guide |
|
||||
| Description | Marking guide description |
|
||||
And I define the following marking guide:
|
||||
| Criterion name | Description for students | Description for markers | Maximum score |
|
||||
| Grade Criteria 1 | Grade 1 description for students | Grade 1 description for markers | 70 |
|
||||
| Grade Criteria 2 | Grade 2 description for students | Grade 2 description for markers | 30 |
|
||||
And I press "Save marking guide and make it ready"
|
||||
And I should not see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I should not see "Assign 1 marking guide Draft"
|
||||
And I should see "Assign 1 marking guide Ready for use"
|
||||
And I click on "Edit the current form definition" "link"
|
||||
When I press "Save as draft"
|
||||
Then I should see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I should see "Assign 1 marking guide Draft"
|
||||
And I should not see "Assign 1 marking guide Ready for use"
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -144,7 +144,11 @@ export default class UserSearch extends GradebookSearchClass {
|
||||
`<span class="font-weight-bold">${searchTerm.replace(/</g, '<')}</span>`
|
||||
);
|
||||
|
||||
user.matchingField = `${escapedMatchingField} (${user.email})`;
|
||||
if (user.email) {
|
||||
user.matchingField = `${escapedMatchingField} (${user.email})`;
|
||||
} else {
|
||||
user.matchingField = escapedMatchingField;
|
||||
}
|
||||
user.link = this.selectOneLink(user.id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -87,15 +87,26 @@ class get_users_in_report extends external_api {
|
||||
);
|
||||
$report = new grade_report_grader($courseid, $gpr, $context);
|
||||
|
||||
$userfieldsapi = \core_user\fields::for_identity($context, false)->with_userpic();
|
||||
$extrauserfields = $userfieldsapi->get_required_fields([\core_user\fields::PURPOSE_IDENTITY]);
|
||||
|
||||
// For the returned users, Add a couple of extra fields that we need for the search module.
|
||||
$users = array_map(function ($user) use ($PAGE) {
|
||||
$user->fullname = fullname($user);
|
||||
$users = array_map(function ($user) use ($PAGE, $extrauserfields) {
|
||||
$userforselector = new \stdClass();
|
||||
$userforselector->id = $user->id;
|
||||
$userforselector->fullname = fullname($user);
|
||||
foreach (\core_user\fields::get_name_fields() as $field) {
|
||||
$userforselector->$field = $user->$field ?? null;
|
||||
}
|
||||
$userpicture = new user_picture($user);
|
||||
$userpicture->size = 1;
|
||||
$user->profileimageurl = $userpicture->get_url($PAGE)->out(false);
|
||||
$userforselector->profileimageurl = $userpicture->get_url($PAGE)->out(false);
|
||||
$userpicture->size = 0; // Size f2.
|
||||
$user->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
|
||||
return $user;
|
||||
$userforselector->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
|
||||
foreach ($extrauserfields as $field) {
|
||||
$userforselector->$field = $user->$field ?? null;
|
||||
}
|
||||
return $userforselector;
|
||||
}, $report->load_users(true));
|
||||
sort($users);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should see "Manual grade"
|
||||
And I should see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- | -6- |
|
||||
| -1- | -2- | -3- | -4- | -5- | -6- |
|
||||
| Student 1 | student1@example.com | 80 | 90 | 30 | 170 |
|
||||
And I click on grade item menu "Course 1" of type "course" on "grader" page
|
||||
And I choose "Show totals only" in the open action menu
|
||||
@@ -57,7 +57,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should not see "Manual grade"
|
||||
And I should see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- |
|
||||
| -1- | -2- | -3- |
|
||||
| Student 1 | student1@example.com | 170 |
|
||||
And I click on grade item menu "Course 1" of type "course" on "grader" page
|
||||
And I click on "Show grades only" "link"
|
||||
@@ -66,7 +66,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should see "Manual grade"
|
||||
And I should not see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | 80 | 90 | 30 |
|
||||
|
||||
@javascript @skip_chrome_zerosize
|
||||
@@ -83,7 +83,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should see "Manual grade"
|
||||
And I should see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- | -6- |
|
||||
| -1- | -2- | -3- | -4- | -5- | -6- |
|
||||
| Student 1 | student1@example.com | 80 | - | 30 | 105.71 |
|
||||
And I click on grade item menu "Course 1" of type "course" on "grader" page
|
||||
And I choose "Show totals only" in the open action menu
|
||||
@@ -92,7 +92,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should not see "Manual grade"
|
||||
And I should see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- |
|
||||
| -1- | -2- | -3- |
|
||||
| Student 1 | student1@example.com | 105.71 |
|
||||
And I click on grade item menu "Course 1" of type "course" on "grader" page
|
||||
When I click on "Show grades only" "link"
|
||||
@@ -101,5 +101,5 @@ Feature: We can change what we are viewing on the grader report
|
||||
And I should see "Manual grade"
|
||||
And I should not see "Course total"
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | 80 | - | 30 |
|
||||
|
||||
@@ -290,6 +290,8 @@ Feature: Within the grader report, test that we can search for users
|
||||
# Activate View all results.
|
||||
And I press the enter key
|
||||
And I wait to be redirected
|
||||
# Sometimes with behat we get unattached nodes causing spurious failures.
|
||||
And I wait "1" seconds
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- |
|
||||
| Dummy User |
|
||||
@@ -300,8 +302,6 @@ Feature: Within the grader report, test that we can search for users
|
||||
| Teacher 1 |
|
||||
| Student 1 |
|
||||
| Turtle Manatee |
|
||||
# Sometimes with behat we get unattached nodes causing spurious failures.
|
||||
And I wait "1" seconds
|
||||
And I set the field "Search users" to "ABC"
|
||||
And I wait until "Turtle Manatee" "option_role" exists
|
||||
And I press the tab key
|
||||
|
||||
@@ -51,7 +51,7 @@ Feature: A teacher checks the grade history report in a course
|
||||
And I navigate to "View > Grade history" in the course gradebook
|
||||
When I press "Submit"
|
||||
Then the following should exist in the "gradereport_history" table:
|
||||
| First name/Last name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| First name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| Student 1 | student1@example.com | apple | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
| Student 1 | student1@example.com | apple | Rewarding assignment | | 60.00 | Teacher 1 |
|
||||
| Student 2 | student2@example.com | orange | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
@@ -79,7 +79,7 @@ Feature: A teacher checks the grade history report in a course
|
||||
And I press "Finish selecting users"
|
||||
And I press "Submit"
|
||||
And the following should exist in the "gradereport_history" table:
|
||||
| First name/Last name | Grade item | Original grade | Revised grade | Grader |
|
||||
| First name | Grade item | Original grade | Revised grade | Grader |
|
||||
| Student 1 | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
| Student 1 | Rewarding assignment | | 60.00 | Teacher 1 |
|
||||
| Student 1 | The greatest assignment ever | 50.00 | 70.00 | Teacher 2 |
|
||||
@@ -96,7 +96,7 @@ Feature: A teacher checks the grade history report in a course
|
||||
And I set the field "Grade item" to "The greatest assignment ever"
|
||||
And I press "Submit"
|
||||
And the following should exist in the "gradereport_history" table:
|
||||
| First name/Last name | Grade item | Original grade | Revised grade | Grader |
|
||||
| First name | Grade item | Original grade | Revised grade | Grader |
|
||||
| Student 1 | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
| Student 1 | The greatest assignment ever | 50.00 | 70.00 | Teacher 2 |
|
||||
And the following should not exist in the "gradereport_history" table:
|
||||
@@ -106,7 +106,7 @@ Feature: A teacher checks the grade history report in a course
|
||||
And I set the field "Grader" to "Teacher 1"
|
||||
And I press "Submit"
|
||||
And the following should exist in the "gradereport_history" table:
|
||||
| First name/Last name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| First name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| Student 1 | student1@example.com | apple | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
And the following should not exist in the "gradereport_history" table:
|
||||
| Student 1 | The greatest assignment ever | 50.00 | 70.00 | Teacher 2 |
|
||||
@@ -114,5 +114,5 @@ Feature: A teacher checks the grade history report in a course
|
||||
And I click on "id_revisedonly" "checkbox"
|
||||
And I press "Submit"
|
||||
And the following should exist in the "gradereport_history" table:
|
||||
| First name/Last name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| First name | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
|
||||
| Student 1 | student1@example.com | apple | The greatest assignment ever | | 50.00 | Teacher 1 |
|
||||
|
||||
@@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
* @copyright 2014 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class report_test extends \advanced_testcase {
|
||||
final class report_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Create some grades.
|
||||
@@ -251,7 +251,7 @@ class report_test extends \advanced_testcase {
|
||||
*
|
||||
* @return array List of data sets (test cases)
|
||||
*/
|
||||
public function get_users_with_profile_fields_provider(): array {
|
||||
public static function get_users_with_profile_fields_provider(): array {
|
||||
return [
|
||||
// User identity check boxes, 'email', 'profile_field_lang' and 'profile_field_height' are checked.
|
||||
'show email,lang and height;search for all users' =>
|
||||
@@ -264,24 +264,18 @@ class report_test extends \advanced_testcase {
|
||||
['email,profile_field_lang,profile_field_height', '.uk', ['u3']],
|
||||
'show email,lang and height,search for Spanish speakers' =>
|
||||
['email,profile_field_lang,profile_field_height', 'spanish', ['u1', 'u4']],
|
||||
'show email,lang and height,search for Spanish speakers' =>
|
||||
'show email,lang and height,search for Spanish speakers (using spa)' =>
|
||||
['email,profile_field_lang,profile_field_height', 'spa', ['u1', 'u4']],
|
||||
'show email,lang and height,search for German speakers' =>
|
||||
['email,profile_field_lang,profile_field_height', 'german', ['u2']],
|
||||
'show email,lang and height,search for German speakers' =>
|
||||
'show email,lang and height,search for German speakers (using ger)' =>
|
||||
['email,profile_field_lang,profile_field_height', 'ger', ['u2']],
|
||||
'show email,lang and height,search for English speakers' =>
|
||||
['email,profile_field_lang,profile_field_height', 'english', ['u3']],
|
||||
'show email,lang and height,search for English speakers' =>
|
||||
'show email,lang and height,search for English speakers (using eng)' =>
|
||||
['email,profile_field_lang,profile_field_height', 'eng', ['u3']],
|
||||
'show email,lang and height,search for English speakers' =>
|
||||
['email,profile_field_lang,profile_field_height', 'ish', ['u3']],
|
||||
'show email,lang and height,search for users with height 180cm' =>
|
||||
['email,profile_field_lang,profile_field_height', '180cm', ['u2', 'u3', 'u4']],
|
||||
'show email,lang and height,search for users with height 180cm' =>
|
||||
['email,profile_field_lang,profile_field_height', '180', ['u2', 'u3', 'u4']],
|
||||
'show email,lang and height,search for users with height 170cm' =>
|
||||
['email,profile_field_lang,profile_field_height', '170cm', ['u1']],
|
||||
'show email,lang and height,search for users with height 170cm' =>
|
||||
['email,profile_field_lang,profile_field_height', '170', ['u1']],
|
||||
|
||||
@@ -292,25 +286,15 @@ class report_test extends \advanced_testcase {
|
||||
['email,profile_field_height', '.com', []],
|
||||
'show email and height;search for users on .co' =>
|
||||
['email,profile_field_height', '.co', ['u3']],
|
||||
'show email and height,search for Spanish/German/English speakers' =>
|
||||
'show email and height,search for Spanish speakers' =>
|
||||
['email,profile_field_height', 'spanish', []],
|
||||
'show email and height,search for Spanish/German/English speakers' =>
|
||||
'show email and height,search for German speakers' =>
|
||||
['email,profile_field_height', 'german', []],
|
||||
'show email and height,search for Spanish/German/English speakers' =>
|
||||
['email,profile_field_height', 'english', []],
|
||||
'show email,lang and height,search for English speakers' =>
|
||||
['email,profile_field_height', 'english', []],
|
||||
'show email and height,search for English speakers' =>
|
||||
['email,profile_field_height', 'eng', []],
|
||||
'show email and height,search for English speakers' =>
|
||||
['email,profile_field_height', 'ish', []],
|
||||
['email,profile_field_height', 'english', []],
|
||||
'show email and height,search for users with height 180cm' =>
|
||||
['email,profile_field_height', '180cm', ['u2', 'u3', 'u4']],
|
||||
'show email,lang and height,search for users with height 180cm' =>
|
||||
['email,profile_field_height', '180', ['u2', 'u3', 'u4']],
|
||||
'show email,lang and height,search for users with height 170cm' =>
|
||||
['email,profile_field_height', '170cm', ['u1']],
|
||||
'show email,lang and height,search for users with height 170cm' =>
|
||||
'show email and height,search for users with height 170cm' =>
|
||||
['email,profile_field_height', '170', ['u1']],
|
||||
|
||||
// User identity check boxes, only 'email' is checked.
|
||||
@@ -322,9 +306,7 @@ class report_test extends \advanced_testcase {
|
||||
'show email only;search for Spanish speakers' => ['email', 'spanish', []],
|
||||
'show email only;search for German speakers' => ['email', 'german', []],
|
||||
'show email only;search for English speakers' => ['email', 'english', []],
|
||||
'show email only;search for users with height 180cm' => ['email', '180cm', []],
|
||||
'show email only;search for users with height 180cm' => ['email', '180', []],
|
||||
'show email only;search for users with height 170cm' => ['email', '170cm', []],
|
||||
'show email only;search for users with height 170cm' => ['email', '170', []],
|
||||
];
|
||||
}
|
||||
@@ -401,7 +383,7 @@ class report_test extends \advanced_testcase {
|
||||
/**
|
||||
* Data provider method for \gradereport_history_report_testcase::test_get_users_with_groups()
|
||||
*/
|
||||
public function get_users_provider() {
|
||||
public static function get_users_provider(): array {
|
||||
return [
|
||||
'Visible groups, non-editing teacher, not in any group' => [
|
||||
VISIBLEGROUPS, 'teacher', ['g1', 'g2'], ['s1', 's2', 's3', 's4', 's5']
|
||||
|
||||
@@ -54,10 +54,18 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
|
||||
// If a particular user option is selected (not in zero state).
|
||||
if ($userid) { // A single user selected.
|
||||
$user = core_user::get_user($userid);
|
||||
|
||||
$context = context_course::instance($course->id);
|
||||
$hiddenuserfields = explode(',', get_config('core', 'hiddenuserfields'));
|
||||
|
||||
// Determine whether the user's email can be displayed.
|
||||
$isemailvisible = !in_array('email', $hiddenuserfields) ||
|
||||
has_capability('moodle/course:viewhiddenuserfields', $context);
|
||||
|
||||
$data['selectedoption'] = [
|
||||
'image' => $this->user_picture($user, ['size' => 40, 'link' => false]),
|
||||
'text' => fullname($user),
|
||||
'additionaltext' => $user->email,
|
||||
'additionaltext' => $isemailvisible ? $user->email : '',
|
||||
];
|
||||
$data['userid'] = $userid;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ Feature: We can use Single view
|
||||
And I press "Save"
|
||||
Then I should see "Grades were set for 1 items"
|
||||
And the following should exist in the "generaltable" table:
|
||||
| First name (Alternate name) Last name | Grade |
|
||||
| User full name | Grade |
|
||||
| Ann, Jill, Grainne, Beauchamp | Very good |
|
||||
And I am on the "Course 1" "grades > Single view > View" page logged in as "teacher2"
|
||||
And I click on "Users" "link" in the ".page-toggler" "css_element"
|
||||
|
||||
@@ -101,10 +101,18 @@ class gradereport_user_renderer extends plugin_renderer_base {
|
||||
if (!is_null($userid)) {
|
||||
if ($userid) { // A single user selected.
|
||||
$user = core_user::get_user($userid);
|
||||
|
||||
$context = context_course::instance($course->id);
|
||||
$hiddenuserfields = explode(',', get_config('core', 'hiddenuserfields'));
|
||||
|
||||
// Determine whether the user's email can be displayed.
|
||||
$isemailvisible = !in_array('email', $hiddenuserfields) ||
|
||||
has_capability('moodle/course:viewhiddenuserfields', $context);
|
||||
|
||||
$data['selectedoption'] = [
|
||||
'image' => $this->user_picture($user, ['size' => 40, 'link' => false]),
|
||||
'text' => fullname($user),
|
||||
'additionaltext' => $user->email,
|
||||
'additionaltext' => $isemailvisible ? $user->email : '',
|
||||
];
|
||||
} else { // All users selected.
|
||||
// Get the total number of users.
|
||||
|
||||
@@ -28,3 +28,22 @@ Feature: Within the User report, a teacher can search for users.
|
||||
And I confirm "Student 2" in "user" search within the gradebook widget exists
|
||||
And I confirm "Student 32" in "user" search within the gradebook widget exists
|
||||
And I confirm "Student 1" in "user" search within the gradebook widget does not exist
|
||||
|
||||
Scenario: A teacher can only search for fields that he allowed to see
|
||||
Given the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/course:viewhiddenuserfields | Prohibit | editingteacher | System | |
|
||||
And the following config values are set as admin:
|
||||
| hiddenuserfields | email |
|
||||
And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1"
|
||||
When I click on ".search-widget[data-searchtype='user']" "css_element"
|
||||
And I set the field "Search users" to "Student"
|
||||
And I confirm "Student 1" in "user" search within the gradebook widget exists
|
||||
And I confirm "Student 2" in "user" search within the gradebook widget exists
|
||||
And I confirm "Student 32" in "user" search within the gradebook widget exists
|
||||
# Email is not shown in results.
|
||||
And I confirm "Student" in "user" search within the gradebook widget exists
|
||||
And I confirm "example.com" in "user" search within the gradebook widget does not exist
|
||||
# Email is not searchable.
|
||||
And I set the field "Search users" to "student5@example.com"
|
||||
And I confirm "0 results found" in "user" search within the gradebook widget exists
|
||||
|
||||
@@ -62,7 +62,7 @@ Feature: An admin can import grades into gradebook using a CSV file
|
||||
And I should see "Grade import success"
|
||||
And I click on "Continue" "button"
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- |
|
||||
| -1- | -2- | -3- | -4- |
|
||||
| Student 1 | student1@example.com | 400.00 | 400.00 |
|
||||
| Student 2 | student2@example.com | 50.00 | 50.00 |
|
||||
| Student 3 | student3@example.com | 50.00 | 50.00 |
|
||||
|
||||
@@ -37,5 +37,5 @@ Feature: We can customise the letter boundary of a course.
|
||||
And I am on "Course 1" course homepage with editing mode off
|
||||
And I navigate to "View > Grader report" in the course gradebook
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- |-3- | -4- |
|
||||
| -1- | -2- |-3- | -4- |
|
||||
| Student 1 | student1@example.com | D | D |
|
||||
|
||||
@@ -38,5 +38,5 @@ Feature: We can customise the letter boundary of a course in gradebook version 2
|
||||
And I am on "Course 1" course homepage with editing mode off
|
||||
And I navigate to "View > Grader report" in the course gradebook
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- |
|
||||
| -1- | -2- | -3- | -4- |
|
||||
| Student 1 | student1@example.com | F | F |
|
||||
|
||||
@@ -32,8 +32,8 @@ Feature: Regrading grades does not unnecessarily mark some as overriden
|
||||
And I press "Save changes"
|
||||
And I am on the "Course 1" "grades > Grader report > View" page
|
||||
And the following should exist in the "gradereport-grader-table" table:
|
||||
| | | |
|
||||
| First name / Last name | Assignment 1 | Course total |
|
||||
| -1- | -3- | -4- |
|
||||
| First name | Assignment 1 | Course total |
|
||||
| Student 1 | 80.00 | 80.00 |
|
||||
| Student 2 | 60.00 | 60.00 |
|
||||
And I turn editing mode on
|
||||
@@ -64,7 +64,7 @@ Feature: Regrading grades does not unnecessarily mark some as overriden
|
||||
When I am on the "Course 1" "grades > Grader report > View" page
|
||||
And I turn editing mode off
|
||||
Then the following should exist in the "gradereport-grader-table" table:
|
||||
| | | |
|
||||
| First name / Last name | Assignment 1 | Course total |
|
||||
| -1- | -3- | -4- |
|
||||
| First name | Assignment 1 | Course total |
|
||||
| Student 1 | 90.00 | 180.00 |
|
||||
| Student 2 | 70.00 | 160.00 |
|
||||
|
||||
@@ -73,7 +73,7 @@ Feature: View gradebook when scales are used
|
||||
Scenario: Test displaying scales in gradebook in aggregation method Natural
|
||||
When I turn editing mode off
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | A | 5.00 | 5.00 |
|
||||
| Student 2 | student2@example.com | B | 4.00 | 4.00 |
|
||||
| Student 3 | student3@example.com | C | 3.00 | 3.00 |
|
||||
@@ -116,7 +116,7 @@ Feature: View gradebook when scales are used
|
||||
| Minimum grade | 1 |
|
||||
And I turn editing mode off
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | A | 5.00 | <coursetotal1> |
|
||||
| Student 2 | student2@example.com | B | 4.00 | <coursetotal2> |
|
||||
| Student 3 | student3@example.com | C | 3.00 | <coursetotal3> |
|
||||
|
||||
@@ -58,7 +58,7 @@ Feature: View gradebook when single item scales are used
|
||||
Scenario: Test displaying single item scales in gradebook in aggregation method Natural
|
||||
When I turn editing mode off
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | Ace! | 1.00 | 1.00 |
|
||||
And the following should exist in the "user-grades" table:
|
||||
| -1- | -2- | -3- | -4- |
|
||||
@@ -92,7 +92,7 @@ Feature: View gradebook when single item scales are used
|
||||
| Category name | Sub category (<aggregation>) |
|
||||
And I turn editing mode off
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -1- | -3- | -4- | -5- |
|
||||
| -1- | -2- | -3- | -4- | -5- |
|
||||
| Student 1 | student1@example.com | Ace! | <cattotal1> | <coursetotal1> |
|
||||
| Student 2 | student2@example.com | - | - | - |
|
||||
And the following should exist in the "user-grades" table:
|
||||
|
||||
@@ -78,14 +78,12 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Course |
|
||||
And I should see "Course" in the "setup-grades" "table"
|
||||
And "Expand" "link" should exist in the "Course" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment one |
|
||||
| Category 1 |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
| Course total |
|
||||
And I should not see "Test assignment one" in the "setup-grades" "table"
|
||||
And I should not see "Category 1" in the "setup-grades" "table"
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
And I should not see "Course total" in the "setup-grades" "table"
|
||||
# Expand the grade category 'Course'. 'Category 1' should be still collapsed.
|
||||
And I click on "Expand" "link" in the "Course" "table_row"
|
||||
And the following should exist in the "setup-grades" table:
|
||||
@@ -96,11 +94,9 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Course total |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
|
||||
Scenario: A teacher can see the aggregated max grade for a grade category even when the category is collapsed
|
||||
Given the following should exist in the "setup-grades" table:
|
||||
@@ -148,11 +144,9 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Category 1 |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
# Expand the grade category 'Category 1'.
|
||||
And I click on "Expand" "link" in the "Category 1" "table_row"
|
||||
And the following should exist in the "setup-grades" table:
|
||||
@@ -170,12 +164,10 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
And I click on "Collapse" "link" in the "Course" "table_row"
|
||||
And I should see "Course" in the "setup-grades" "table"
|
||||
And "Expand" "link" should exist in the "Course" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment one |
|
||||
| Category 1 |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
And I should not see "Test assignment one" in the "setup-grades" "table"
|
||||
And I should not see "Category 1" in the "setup-grades" "table"
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
# Expand the grade category 'Course'. 'Category 1' should be still collapsed.
|
||||
And I click on "Expand" "link" in the "Course" "table_row"
|
||||
And the following should exist in the "setup-grades" table:
|
||||
@@ -185,11 +177,9 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Category 1 |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
|
||||
Scenario: Previously collapsed categories are still shown as collapsed when a teacher navigates back to Gradebook setup
|
||||
# Collapse the grade category 'Category 1' and navigate to the course homepage.
|
||||
@@ -204,11 +194,9 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Course total |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
|
||||
Scenario: Previously collapsed categories are still shown as collapsed when a teacher is moving grade items in Gradebook setup
|
||||
# Collapse the grade category 'Category 1'.
|
||||
@@ -222,18 +210,29 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Category 1 |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
|
||||
Scenario: Grade categories are shown as collapsed only to the teacher that collapsed them
|
||||
# Collapse the grade category 'Category 1'.
|
||||
Given I click on "Collapse" "link" in the "Category 1" "table_row"
|
||||
# Log in as teacher2 and confirm that the category 'Category 1' is not collapsed.
|
||||
When I am on the "Course" "grades > gradebook setup" page logged in as "teacher2"
|
||||
When I reload the page
|
||||
# Reload the page and confirm that the category 'Category 1' is still collapsed.
|
||||
Then the following should exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Course |
|
||||
| Test assignment one |
|
||||
| Category 1 |
|
||||
| Course total |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And I should not see "Test assignment two" in the "setup-grades" "table"
|
||||
And I should not see "Manual grade" in the "setup-grades" "table"
|
||||
And I should not see "Category 1 total" in the "setup-grades" "table"
|
||||
# Log in as teacher2 and confirm that the category 'Category 1' is not collapsed.
|
||||
And I am on the "Course" "grades > gradebook setup" page logged in as "teacher2"
|
||||
And the following should exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Course |
|
||||
| Test assignment one |
|
||||
@@ -244,18 +243,3 @@ Feature: Teachers can toggle the visibility of the grade categories in the Grade
|
||||
| Course total |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Collapse" "link" should exist in the "Category 1" "table_row"
|
||||
# Log in as teacher1 and confirm that the category 'Category 1' is still collapsed.
|
||||
And I am on the "Course" "grades > gradebook setup" page logged in as "teacher1"
|
||||
And the following should exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Course |
|
||||
| Test assignment one |
|
||||
| Category 1 |
|
||||
| Course total |
|
||||
And "Collapse" "link" should exist in the "Course" "table_row"
|
||||
And "Expand" "link" should exist in the "Category 1" "table_row"
|
||||
And the following should not exist in the "setup-grades" table:
|
||||
| Name |
|
||||
| Test assignment two |
|
||||
| Manual grade |
|
||||
| Category 1 total |
|
||||
|
||||
@@ -56,7 +56,7 @@ Feature: Private groups
|
||||
Scenario: Participants in "Visible" groups see their membership and other members:
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student1"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | No groups |
|
||||
| Student 3 | No groups |
|
||||
@@ -69,7 +69,7 @@ Feature: Private groups
|
||||
Scenario: Participants in "Only visible to members" groups see their membership and other members, plus "Visible"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student2"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | Only visible to members/Non-Participation, Only visible to members/Participation |
|
||||
| Student 3 | No groups |
|
||||
@@ -82,7 +82,7 @@ Feature: Private groups
|
||||
Scenario: Participants in "Only see own membership" groups see their membership but not other members, plus "Visible"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | No groups |
|
||||
| Student 3 | Only see own membership |
|
||||
@@ -95,7 +95,7 @@ Feature: Private groups
|
||||
Scenario: Participants in "Not visible" groups do not see that group, do see "Visible"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student4"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | No groups |
|
||||
| Student 3 | No groups |
|
||||
@@ -108,7 +108,7 @@ Feature: Private groups
|
||||
Scenario: View participants list as a teacher:
|
||||
Given I am on the "C1" "enrolled users" page logged in as "teacher1"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | Only visible to members/Non-Participation, Only visible to members/Participation |
|
||||
| Student 3 | Only see own membership |
|
||||
@@ -125,10 +125,10 @@ Feature: Private groups
|
||||
And I set the field "Type or select..." to "Only see own membership"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 3 | Only see own membership |
|
||||
And the following should not exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 7 | No groups |
|
||||
|
||||
@javascript
|
||||
@@ -138,7 +138,7 @@ Feature: Private groups
|
||||
And I set the field "Type or select..." to "No group"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 2 | No groups |
|
||||
| Student 4 | No groups |
|
||||
| Student 6 | No groups |
|
||||
@@ -153,7 +153,7 @@ Feature: Private groups
|
||||
And I set the field "Type or select..." to "Only see own membership"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 2 | No groups |
|
||||
| Student 4 | No groups |
|
||||
@@ -170,7 +170,7 @@ Feature: Private groups
|
||||
And I set the field "Type or select..." to "No group"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| First name | Groups |
|
||||
| Student 1 | Visible/Non-Participation, Visible/Participation |
|
||||
| Student 3 | Only see own membership |
|
||||
| Student 5 | Visible/Non-Participation, Visible/Participation |
|
||||
|
||||
@@ -43,17 +43,17 @@
|
||||
<div class="container mt-5">
|
||||
{{#exception}}
|
||||
<div class="alert alert-block fade in alert-danger my-2" role="alert">
|
||||
{{{ exception }}}
|
||||
{{ . }}
|
||||
</div>
|
||||
{{/exception}}
|
||||
{{#info}}
|
||||
<div class="alert alert-block fade in alert-info my-2" role="alert">
|
||||
{{{ . }}}
|
||||
{{ . }}
|
||||
</div>
|
||||
{{/info}}
|
||||
{{#error}}
|
||||
<div class="alert alert-block fade in alert-warning my-2" role="alert">
|
||||
{{#code}}{{{code}}} : {{/code}}{{{ message }}}
|
||||
{{#code}} {{ . }} : {{/code}} {{ message }}
|
||||
</div>
|
||||
{{/error}}
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@ Feature: Check H5P tools information is correct
|
||||
And I should see "Disable" in the "H5P scheduled task" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: H5P atto button.
|
||||
Scenario: H5P editor button.
|
||||
Given I log in as "admin"
|
||||
When I navigate to "H5P > H5P overview" in site administration
|
||||
Then I should see "Enable" in the "Insert H5P button" "table_row"
|
||||
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'ca';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Català per a Workplace';
|
||||
$string['thislanguage'] = 'Català';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'da';
|
||||
$string['thislanguage'] = 'Dansk til Workplace';
|
||||
$string['thislanguage'] = 'Dansk';
|
||||
|
||||
@@ -82,5 +82,5 @@ $string['welcomep30'] = 'Diese Version von <strong>{$a->installername}</strong>
|
||||
$string['welcomep40'] = 'Das Paket enthält: <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Die Verwendung aller Anwendungen in diesem Paket unterliegt den jeweiligen Lizenzen. Das vollständige Paket <strong>{$a->installername}</strong> ist <a href="https://www.opensource.org/docs/definition_plain.html">Open Source</a> und wird unter mit der Lizenz <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> angeboten.';
|
||||
$string['welcomep60'] = 'Die folgenden Webseiten führen Sie in einfachen Schritten durch die Installation von <strong>Moodle</strong> auf Ihrem Computer. Sie können die vorgeschlagenen Einstellungen übernehmen oder an eigene Bedürfnisse anpassen.';
|
||||
$string['welcomep70'] = 'Klicken Sie auf die Taste \'Weiter\', um mit der Installation von Moodle fortzufahren.';
|
||||
$string['welcomep70'] = 'Klicken Sie auf die Taste \'Weiter\', um mit der Installation von <strong>Moodle</strong> fortzufahren.';
|
||||
$string['wwwroot'] = 'Webadresse';
|
||||
|
||||
@@ -46,5 +46,5 @@ $string['phpversionhelp'] = '<p>Moodle erwartet PHP mindestens in der Version 4.
|
||||
(Im Falle von 5.0.x könntest du auch zu einer Version 4.3.x/4.4.x downgraden)</p>';
|
||||
$string['welcomep20'] = 'Du hast das Paket <strong>{$a->packname} {$a->packversion}</strong> erfolgreich auf deinem Computer installiert.';
|
||||
$string['welcomep30'] = 'Diese Version von <strong>{$a->installername}</strong> enthält folgende Anwendungen, mit denen du <strong>Moodle</strong> ausführen kannst:';
|
||||
$string['welcomep60'] = 'Die folgenden Seiten führen dich in einfachen Schritten durch die Konfiguration und Installation von <strong>Moodle</strong> auf deinem Computer. Du kannst die vorgeschlagenen Einstellungen übernehmen oder an deine Bedürfnisse anpassen.';
|
||||
$string['welcomep70'] = 'Klicke auf den "Weiter"-Button, um mit dem Setup von <string>Moodle</string> fortzufahren.';
|
||||
$string['welcomep60'] = 'Die folgenden Webseiten führen dich in einfachen Schritten durch die Installation von <strong>Moodle</strong> auf deinem Computer. Du können die vorgeschlagenen Einstellungen übernehmen oder an eigene Bedürfnisse anpassen.';
|
||||
$string['welcomep70'] = 'Klicke auf die Taste "Weiter", um mit der Installation von <strong>Moodle</strong> fortzufahren.';
|
||||
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'de_du';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Deutsch (kids)';
|
||||
$string['thislanguage'] = 'Deutsch';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'el';
|
||||
$string['thislanguage'] = 'Ελληνικά για παιδιά';
|
||||
$string['thislanguage'] = 'Ελληνικά';
|
||||
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'el';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Ελληνικά για χώρους εργασίας';
|
||||
$string['thislanguage'] = 'Ελληνικά';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'en';
|
||||
$string['thislanguage'] = 'English (kids)';
|
||||
$string['thislanguage'] = 'English';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'en_us';
|
||||
$string['thislanguage'] = 'English for Workplace - United States';
|
||||
$string['thislanguage'] = 'English (United States)';
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'English for Workplace';
|
||||
$string['thislanguage'] = 'English';
|
||||
|
||||
@@ -33,3 +33,4 @@ $string['language'] = 'Idioma';
|
||||
$string['moodlelogo'] = 'Logo de Moodle';
|
||||
$string['next'] = 'Siguiente';
|
||||
$string['previous'] = 'Previo';
|
||||
$string['reload'] = 'Recargar';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'es_mx';
|
||||
$string['thislanguage'] = 'Español - México para niños';
|
||||
$string['thislanguage'] = 'Español - México';
|
||||
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'es';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Español para la Empresa';
|
||||
$string['thislanguage'] = 'Español';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'fr';
|
||||
$string['thislanguage'] = 'Français pour Workplace';
|
||||
$string['thislanguage'] = 'Français';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['clianswerno'] = 'n';
|
||||
$string['cliansweryes'] = 's';
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Interlingua';
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'ja';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Japanese (kids)';
|
||||
$string['thislanguage'] = 'Japanese';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'lt';
|
||||
$string['thislanguage'] = 'Lietuvių (Workplace)';
|
||||
$string['thislanguage'] = 'Lietuvių';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'lv';
|
||||
$string['thislanguage'] = 'Latviešu (Workplace)';
|
||||
$string['thislanguage'] = 'Latviešu';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'nl';
|
||||
$string['thislanguage'] = 'Nederlands Workplace';
|
||||
$string['thislanguage'] = 'Nederlands';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'no';
|
||||
$string['thislanguage'] = 'Norsk Workplace';
|
||||
$string['thislanguage'] = 'Norsk';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'pt_br';
|
||||
$string['thislanguage'] = 'Português Brasil para Crianças';
|
||||
$string['thislanguage'] = 'Português Brasil';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'pt_br';
|
||||
$string['thislanguage'] = 'Português para Workplace';
|
||||
$string['thislanguage'] = 'Português - Brasil';
|
||||
|
||||
@@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'ro';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Română Workplace';
|
||||
$string['thislanguage'] = 'Română';
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'sv';
|
||||
$string['thislanguage'] = 'Svenska för Workplace';
|
||||
$string['thislanguage'] = 'Svenska';
|
||||
|
||||
@@ -73,6 +73,9 @@ $string['alternativefullnameformat_desc'] = 'This defines how names are shown to
|
||||
$string['always'] = 'Always';
|
||||
$string['appearance'] = 'Appearance';
|
||||
$string['aspellpath'] = 'Path to aspell';
|
||||
$string['asyncbackupdisabled'] = 'Your site is currently configured to use synchronous backups. Asynchronous backups provide a better user experience.
|
||||
Asynchronous backups will be enabled for all sites from Moodle LMS 4.5 LTS.
|
||||
Synchronous backups will be removed from Moodle LMS the version after 4.5 LTS';
|
||||
$string['authentication'] = 'Authentication';
|
||||
$string['authpreventaccountcreation'] = 'Prevent account creation when authenticating';
|
||||
$string['authpreventaccountcreation_help'] = 'When a user authenticates, an account on the site is automatically created if it doesn\'t yet exist. If an external database, such as LDAP, is used for authentication, but you wish to restrict access to the site to users with an existing account only, then this option should be enabled. New accounts will need to be created manually or via the upload users feature. Note that this setting doesn\'t apply to MNet authentication.';
|
||||
@@ -636,6 +639,7 @@ $string['environmentrequirecustomcheck'] = 'this test must pass';
|
||||
$string['environmentrequireinstall'] = 'must be installed and enabled';
|
||||
$string['environmentrequireversion'] = 'version {$a->needed} is required and you are running {$a->current}';
|
||||
$string['environmentsettingok'] = 'recommended setting detected';
|
||||
$string['environmentshouldfixcustomcheck'] = 'should be enabled for best results';
|
||||
$string['environmentshouldfixsetting'] = 'PHP setting should be changed.';
|
||||
$string['environmentxmlerror'] = 'Error reading environment data ({$a->error_code})';
|
||||
$string['environmentmariadbwrongdbtype'] = 'Wrong $CFG->dbtype. You need to change it in your config.php file from \'mysqli\' to \'mariadb\'.';
|
||||
|
||||
Vendored
+1
-1
@@ -7,6 +7,6 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 2.9
|
||||
*/
|
||||
define("core/localstorage",["core/config","core/storagewrapper"],(function(config,StorageWrapper){var storage=new StorageWrapper(window.localStorage);return{get:function(key){return storage.get(key)},set:function(key,value){return storage.set(key,value)}}}));
|
||||
define("core/localstorage",["core/config","core/storagewrapper"],(function(config,StorageWrapper){var storage=new StorageWrapper(window.localStorage);return{get:function(key){return storage.get(key)},set:function(key,value){return storage.set(key,value)},clean:function(){return storage.clean()}}}));
|
||||
|
||||
//# sourceMappingURL=localstorage.min.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"localstorage.min.js","sources":["../src/localstorage.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Simple API for set/get to localstorage, with cacherev expiration.\n *\n * @module core/localstorage\n * @class localstorage\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\ndefine(['core/config', 'core/storagewrapper'], function(config, StorageWrapper) {\n\n // Private functions and variables.\n /** @var {Object} StorageWrapper - Wraps browsers localStorage object */\n var storage = new StorageWrapper(window.localStorage);\n\n return /** @alias module:core/localstorage */ {\n /**\n * Get a value from local storage. Remember - all values must be strings.\n *\n * @method get\n * @param {string} key The cache key to check.\n * @return {boolean|string} False if the value is not in the cache, or some other error - a string otherwise.\n */\n get: function(key) {\n return storage.get(key);\n },\n\n /**\n * Set a value to local storage. Remember - all values must be strings.\n *\n * @method set\n * @param {string} key The cache key to set.\n * @param {string} value The value to set.\n * @return {boolean} False if the value can't be saved in the cache, or some other error - true otherwise.\n */\n set: function(key, value) {\n return storage.set(key, value);\n }\n\n };\n});\n"],"names":["define","config","StorageWrapper","storage","window","localStorage","get","key","set","value"],"mappings":";;;;;;;;;AAwBAA,2BAAO,CAAC,cAAe,wBAAwB,SAASC,OAAQC,oBAIxDC,QAAU,IAAID,eAAeE,OAAOC,oBAEM,CAQ1CC,IAAK,SAASC,YACHJ,QAAQG,IAAIC,MAWvBC,IAAK,SAASD,IAAKE,cACRN,QAAQK,IAAID,IAAKE"}
|
||||
{"version":3,"file":"localstorage.min.js","sources":["../src/localstorage.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Simple API for set/get to localstorage, with cacherev expiration.\n *\n * @module core/localstorage\n * @class localstorage\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\ndefine(['core/config', 'core/storagewrapper'], function(config, StorageWrapper) {\n\n // Private functions and variables.\n /** @var {Object} StorageWrapper - Wraps browsers localStorage object */\n var storage = new StorageWrapper(window.localStorage);\n\n return /** @alias module:core/localstorage */ {\n /**\n * Get a value from local storage. Remember - all values must be strings.\n *\n * @method get\n * @param {string} key The cache key to check.\n * @return {boolean|string} False if the value is not in the cache, or some other error - a string otherwise.\n */\n get: function(key) {\n return storage.get(key);\n },\n\n /**\n * Set a value to local storage. Remember - all values must be strings.\n *\n * @method set\n * @param {string} key The cache key to set.\n * @param {string} value The value to set.\n * @return {boolean} False if the value can't be saved in the cache, or some other error - true otherwise.\n */\n set: function(key, value) {\n return storage.set(key, value);\n },\n\n /**\n * Clean local storage\n *\n * @method clean\n */\n clean: function() {\n return storage.clean();\n }\n\n };\n});\n"],"names":["define","config","StorageWrapper","storage","window","localStorage","get","key","set","value","clean"],"mappings":";;;;;;;;;AAwBAA,2BAAO,CAAC,cAAe,wBAAwB,SAASC,OAAQC,oBAIxDC,QAAU,IAAID,eAAeE,OAAOC,oBAEM,CAQ1CC,IAAK,SAASC,YACHJ,QAAQG,IAAIC,MAWvBC,IAAK,SAASD,IAAKE,cACRN,QAAQK,IAAID,IAAKE,QAQ5BC,MAAO,kBACIP,QAAQO"}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
define("core/storage_validation",["exports","core/localstorage"],(function(_exports,_localstorage){var obj;
|
||||
/**
|
||||
* Clean caches after user login in order to prevent cache poisoning.
|
||||
* @module core/storage_validation
|
||||
* @copyright 2024 Raquel Ortega <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_localstorage=(obj=_localstorage)&&obj.__esModule?obj:{default:obj};_exports.init=userCurrentLogin=>{userCurrentLogin!==Number(_localstorage.default.get("sUserLogintime"))&&(_localstorage.default.clean(),_localstorage.default.set("sUserLogintime",Number(userCurrentLogin).toString()))}}));
|
||||
|
||||
//# sourceMappingURL=storage_validation.min.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"storage_validation.min.js","sources":["../src/storage_validation.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Clean caches after user login in order to prevent cache poisoning.\n * @module core/storage_validation\n * @copyright 2024 Raquel Ortega <raquel.ortega@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport LocalStorage from 'core/localstorage';\n\n/**\n * Initialise storage validation.\n *\n * @param {Number|null} userCurrentLogin - Current login information. Can be null.\n */\nexport const init = (userCurrentLogin) => {\n const sUserLoginTime = Number(LocalStorage.get('sUserLogintime'));\n\n if (userCurrentLogin !== sUserLoginTime) {\n LocalStorage.clean();\n LocalStorage.set('sUserLogintime', Number(userCurrentLogin).toString());\n }\n};\n"],"names":["userCurrentLogin","Number","LocalStorage","get","clean","set","toString"],"mappings":";;;;;;oKA6BqBA,mBAGbA,mBAFmBC,OAAOC,sBAAaC,IAAI,2CAG9BC,8BACAC,IAAI,iBAAkBJ,OAAOD,kBAAkBM"}
|
||||
Vendored
+1
-1
@@ -6,6 +6,6 @@
|
||||
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define("core/storagewrapper",["core/config"],(function(config){var Wrapper=function(storage){this.storage=storage,this.supported=this.detectSupport(),this.hashSource=config.wwwroot+"/"+config.jsrev,this.hash=this.hashString(this.hashSource),this.prefix=this.hash+"/",this.jsrevPrefix=this.hashString(config.wwwroot)+"/jsrev",this.validateCache()};return Wrapper.prototype.detectSupport=function(){if(-1==config.jsrev)return!1;if(void 0===this.storage)return!1;try{return null!==this.storage&&(this.storage.setItem("test","1"),this.storage.removeItem("test"),!0)}catch(ex){return!1}},Wrapper.prototype.prefixKey=function(key){return this.prefix+key},Wrapper.prototype.validateCache=function(){if(this.supported){var cacheVersion=this.storage.getItem(this.jsrevPrefix);if(null!==cacheVersion)config.jsrev!=cacheVersion&&(this.storage.clear(),this.storage.setItem(this.jsrevPrefix,config.jsrev));else this.storage.setItem(this.jsrevPrefix,config.jsrev)}},Wrapper.prototype.hashString=function(source){var i,len,hash=0;if(0===source.length)return hash;for(i=0,len=source.length;i<len;i++)hash=(hash<<5)-hash+source.charCodeAt(i),hash|=0;return hash},Wrapper.prototype.get=function(key){return!!this.supported&&(key=this.prefixKey(key),this.storage.getItem(key))},Wrapper.prototype.set=function(key,value){if(!this.supported)return!1;key=this.prefixKey(key);try{this.storage.setItem(key,value)}catch(e){return!1}return!0},Wrapper}));
|
||||
define("core/storagewrapper",["core/config"],(function(config){var Wrapper=function(storage){this.storage=storage,this.supported=this.detectSupport(),this.hashSource=config.wwwroot+"/"+config.jsrev,this.hash=this.hashString(this.hashSource),this.prefix=this.hash+"/",this.jsrevPrefix=this.hashString(config.wwwroot)+"/jsrev",this.validateCache()};return Wrapper.prototype.detectSupport=function(){if(-1==config.jsrev)return!1;if(void 0===this.storage)return!1;try{return null!==this.storage&&(this.storage.setItem("test","1"),this.storage.removeItem("test"),!0)}catch(ex){return!1}},Wrapper.prototype.prefixKey=function(key){return this.prefix+key},Wrapper.prototype.validateCache=function(){if(this.supported){var cacheVersion=this.storage.getItem(this.jsrevPrefix);if(null!==cacheVersion)config.jsrev!=cacheVersion&&(this.storage.clear(),this.storage.setItem(this.jsrevPrefix,config.jsrev));else this.storage.setItem(this.jsrevPrefix,config.jsrev)}},Wrapper.prototype.hashString=function(source){var i,len,hash=0;if(0===source.length)return hash;for(i=0,len=source.length;i<len;i++)hash=(hash<<5)-hash+source.charCodeAt(i),hash|=0;return hash},Wrapper.prototype.get=function(key){return!!this.supported&&(key=this.prefixKey(key),this.storage.getItem(key))},Wrapper.prototype.set=function(key,value){if(!this.supported)return!1;key=this.prefixKey(key);try{this.storage.setItem(key,value)}catch(e){return!1}return!0},Wrapper.prototype.clean=function(){this.storage.clear()},Wrapper}));
|
||||
|
||||
//# sourceMappingURL=storagewrapper.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -50,6 +50,15 @@ define(['core/config', 'core/storagewrapper'], function(config, StorageWrapper)
|
||||
*/
|
||||
set: function(key, value) {
|
||||
return storage.set(key, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clean local storage
|
||||
*
|
||||
* @method clean
|
||||
*/
|
||||
clean: function() {
|
||||
return storage.clean();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Clean caches after user login in order to prevent cache poisoning.
|
||||
* @module core/storage_validation
|
||||
* @copyright 2024 Raquel Ortega <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import LocalStorage from 'core/localstorage';
|
||||
|
||||
/**
|
||||
* Initialise storage validation.
|
||||
*
|
||||
* @param {Number|null} userCurrentLogin - Current login information. Can be null.
|
||||
*/
|
||||
export const init = (userCurrentLogin) => {
|
||||
const sUserLoginTime = Number(LocalStorage.get('sUserLogintime'));
|
||||
|
||||
if (userCurrentLogin !== sUserLoginTime) {
|
||||
LocalStorage.clean();
|
||||
LocalStorage.set('sUserLogintime', Number(userCurrentLogin).toString());
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user