Compare commits
184 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 823f673b73 | |||
| 9c0ff75a5d | |||
| 6d55f452d8 | |||
| 73d04ef74e | |||
| 4f4d579ff7 | |||
| 8fc56b46e1 | |||
| 5e2a59a83e | |||
| 1053b971c1 | |||
| f949dda2bb | |||
| d628e6bfbb | |||
| 07235465ca | |||
| 7ad9944401 | |||
| 6d691e16b3 | |||
| 0621cdcbd0 | |||
| 84b0279b36 | |||
| 77c6dd8c55 | |||
| a4aee520ab | |||
| d3bc590537 | |||
| 397c5e357e | |||
| 5584d36373 | |||
| 3194d058b2 | |||
| 41f32d0a4e | |||
| 28c5507861 | |||
| afc6b1903a | |||
| 8301c80a95 | |||
| 5644e62971 | |||
| 4d4cdc6bab | |||
| 358aff25ce | |||
| d2b117e850 | |||
| ffbeec7615 | |||
| 9a1a8521ac | |||
| e6754cac35 | |||
| a55e35eb64 | |||
| bb83d2d84f | |||
| 08e8db984c | |||
| 944b61fbff | |||
| 908a25c60a | |||
| b214133039 | |||
| d67b765f12 | |||
| 455faf3f3d | |||
| d7edf9a8df | |||
| dd3b81d627 | |||
| d92728cacd | |||
| 2cf275b49d | |||
| d1e2ed624e | |||
| 8fbab920e7 | |||
| 8cbd6496b0 | |||
| 6b27a037ba | |||
| 2991f6e78e | |||
| e75588202a | |||
| 71f7003de8 | |||
| d2b6e5728c | |||
| 1984d0f465 | |||
| e506b18e86 | |||
| 6ca3a5fb55 | |||
| 4fede30d7f | |||
| a9e5f87376 | |||
| 86c09cebc8 | |||
| 0a1bc3c0bc | |||
| d9e42fb951 | |||
| 6357e519e8 | |||
| 59f8be6d89 | |||
| 11041c8c08 | |||
| c2ec489dec | |||
| df5d73f599 | |||
| 62c1f37d40 | |||
| f611f4fafc | |||
| 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 |
@@ -3,7 +3,7 @@ name: Core
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
- main
|
||||
- MOODLE_[0-9]+_STABLE
|
||||
tags-ignore:
|
||||
- v[0-9]+.[0-9]+.[0-9]+*
|
||||
|
||||
@@ -500,4 +500,15 @@ abstract class plugin_management_table extends flexible_table implements dynamic
|
||||
protected function supports_ordering(): bool {
|
||||
return $this->plugininfoclass::plugintype_supports_ordering();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has the capability to access this table.
|
||||
*
|
||||
* Default implementation for plugin management tables is to require 'moodle/site:config' capability
|
||||
*
|
||||
* @return bool Return true if capability check passed.
|
||||
*/
|
||||
public function has_capability(): bool {
|
||||
return has_capability('moodle/site:config', $this->get_context());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -48,25 +48,3 @@ Feature: View task logs report and use its filters
|
||||
| operator | shouldornotsee |
|
||||
| Less than | should not see |
|
||||
| Greater than | should see |
|
||||
|
||||
@javascript
|
||||
Scenario: Reset task log filters
|
||||
Given I log in as "admin"
|
||||
And I change window size to "large"
|
||||
And I navigate to "Server > Tasks > Task logs" in site administration
|
||||
When I click on "Filters" "button"
|
||||
And I set the following fields in the "Result" "core_reportbuilder > Filter" to these values:
|
||||
| Result operator | Is equal to |
|
||||
| Result value | Fail |
|
||||
And I click on "Apply" "button" in the "[data-region='report-filters']" "css_element"
|
||||
Then I should see "Filters applied"
|
||||
And I should see "Filters (1)" in the "#dropdownFiltersButton" "css_element"
|
||||
And I should see "Nothing to display"
|
||||
And I click on "Reset all" "button" in the "[data-region='report-filters']" "css_element"
|
||||
And I should see "Filters reset"
|
||||
And I should not see "Filters (1)" in the "#dropdownFiltersButton" "css_element"
|
||||
And I should see "Filters" in the "#dropdownFiltersButton" "css_element"
|
||||
And "[data-region='report-filters']" "css_element" should be visible
|
||||
And the following fields in the "Result" "core_reportbuilder > Filter" match these values:
|
||||
| Result operator | Is any value |
|
||||
And I should not see "Nothing to display"
|
||||
|
||||
@@ -5,16 +5,18 @@ Feature: I can download a preset
|
||||
| name |
|
||||
| Custom preset |
|
||||
|
||||
@javascript
|
||||
Scenario: Custom preset settings can be downloaded
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Site admin presets" in site administration
|
||||
When I open the action menu in "Custom preset" "table_row"
|
||||
Then following "Download" "link" in the "Custom preset" "table_row" should download between "0" and "5000" bytes
|
||||
Then following "Download" in the "Custom preset" "table_row" should download a file that:
|
||||
| Has mimetype | text/xml |
|
||||
| Contains text in xml element | Custom preset |
|
||||
|
||||
@javascript
|
||||
Scenario: Core preset settings can be downloaded
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Site admin presets" in site administration
|
||||
When I open the action menu in "Starter" "table_row"
|
||||
Then following "Download" "link" in the "Starter" "table_row" should download between "0" and "5000" bytes
|
||||
Then following "Download" in the "Starter" "table_row" should download a file that:
|
||||
| Has mimetype | text/xml |
|
||||
| Contains text in xml element | Starter |
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -54,6 +54,7 @@ Feature: Data delete from the privacy API
|
||||
And I should see "Awaiting approval" in the "Victim User 1" "table_row"
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And I follow "Approve request"
|
||||
And I wait until "Approve request" "button" exists
|
||||
And I press "Approve request"
|
||||
And I should see "Approved" in the "Victim User 1" "table_row"
|
||||
And I run all adhoc tasks
|
||||
@@ -80,6 +81,7 @@ Feature: Data delete from the privacy API
|
||||
And I navigate to "Users > Privacy and policies > Data requests" in site administration
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And I follow "Approve request"
|
||||
And I wait until "Approve request" "button" exists
|
||||
And I press "Approve request"
|
||||
|
||||
And I log out
|
||||
@@ -115,6 +117,7 @@ Feature: Data delete from the privacy API
|
||||
And I navigate to "Users > Privacy and policies > Data requests" in site administration
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And I follow "Approve request"
|
||||
And I wait until "Approve request" "button" exists
|
||||
And I press "Approve request"
|
||||
|
||||
And I log out
|
||||
|
||||
@@ -48,13 +48,15 @@ Feature: Data export from the privacy API
|
||||
And I should see "Awaiting approval" in the "Victim User 1" "table_row"
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And I follow "Approve request"
|
||||
And I wait until "Approve request" "button" exists
|
||||
And I press "Approve request"
|
||||
And I should see "Approved" in the "Victim User 1" "table_row"
|
||||
And I run all adhoc tasks
|
||||
And I reload the page
|
||||
And I should see "Download ready" in the "Victim User 1" "table_row"
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And following "Download" should download between "1" and "200000" bytes
|
||||
And following "Download" should download a file that:
|
||||
| Contains file in zip | index.html |
|
||||
And the following config values are set as admin:
|
||||
| privacyrequestexpiry | 1 | tool_dataprivacy |
|
||||
And I wait "1" seconds
|
||||
@@ -89,7 +91,8 @@ Feature: Data export from the privacy API
|
||||
And I reload the page
|
||||
And I should see "Download ready" in the "Export all of my personal data" "table_row"
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And following "Download" should download between "1" and "200000" bytes
|
||||
And following "Download" should download a file that:
|
||||
| Contains file in zip | index.html |
|
||||
|
||||
And the following config values are set as admin:
|
||||
| privacyrequestexpiry | 1 | tool_dataprivacy |
|
||||
@@ -115,6 +118,7 @@ Feature: Data export from the privacy API
|
||||
And I navigate to "Users > Privacy and policies > Data requests" in site administration
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And I follow "Approve request"
|
||||
And I wait until "Approve request" "button" exists
|
||||
And I press "Approve request"
|
||||
|
||||
And I log out
|
||||
@@ -126,7 +130,8 @@ Feature: Data export from the privacy API
|
||||
And I reload the page
|
||||
And I should see "Download ready" in the "Victim User 1" "table_row"
|
||||
And I open the action menu in "Victim User 1" "table_row"
|
||||
And following "Download" should download between "1" and "200000" bytes
|
||||
And following "Download" should download a file that:
|
||||
| Contains file in zip | index.html |
|
||||
|
||||
And the following config values are set as admin:
|
||||
| privacyrequestexpiry | 1 | tool_dataprivacy |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -170,6 +170,7 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I click on "Actions" "link_or_button" in the "This privacy policy" "table_row"
|
||||
And I click on "Set status to \"Active\"" "link" in the "This privacy policy" "table_row"
|
||||
And I wait until "Activate" "button" exists
|
||||
And I press "Activate"
|
||||
And I log out
|
||||
When I log in as "manager"
|
||||
@@ -260,6 +261,7 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I click on "Actions" "link_or_button" in the "This privacy policy" "table_row"
|
||||
And I click on "Set status to \"Active\"" "link" in the "This privacy policy" "table_row"
|
||||
And I wait until "Activate" "button" exists
|
||||
And I press "Activate"
|
||||
And I log out
|
||||
When I log in as "manager"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Feature: Apply content type to a tour
|
||||
Then "Content type" "select" should exist
|
||||
And the "Content type" select box should contain "Language string ID"
|
||||
And the "Content type" select box should contain "Manual"
|
||||
And I change window size to "large"
|
||||
And I select "Language string ID" from the "Content type" singleselect
|
||||
And I should see " Language string ID"
|
||||
And "#fgroup_id_contenthtmlgrp" "css_element" should not be visible
|
||||
@@ -38,6 +39,7 @@ Feature: Apply content type to a tour
|
||||
And I click on "View" "link" in the "My first tour" "table_row"
|
||||
And I click on "New step" "link"
|
||||
And I set the field "Title" to "tour_activityinfo_course_teacher_title,tool_usertours"
|
||||
And I change window size to "large"
|
||||
And I select "Language string ID" from the "Content type" singleselect
|
||||
And I set the field "Language string ID" to "tour_activityinfo_course_teacher_content_abc,tool_usertours"
|
||||
When I press "Save changes"
|
||||
|
||||
@@ -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_ALPHANUMEXT);
|
||||
$afterparam = required_param('after', PARAM_ALPHANUMEXT);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ Feature: Manage analytics models
|
||||
And I should see "Read actions amount"
|
||||
And I click on "Select Student 6 for bulk action" "checkbox" in the "Student 6" "table_row"
|
||||
And I click on "Accept" "button"
|
||||
And I wait until "Confirm" "button" exists
|
||||
And I click on "Confirm" "button" in the "Accept" "dialogue"
|
||||
And I click on "View prediction details" "icon" in the "Student 5" "table_row"
|
||||
And I click on "Select Student 5 for bulk action" "checkbox" in the "Student 5" "table_row"
|
||||
@@ -145,7 +146,8 @@ Feature: Manage analytics models
|
||||
When I open the action menu in "Students at risk of not meeting the course completion conditions" "table_row"
|
||||
And I choose "Export" in the open action menu
|
||||
And I click on "Actions" "link" in the "Students at risk of not meeting the course completion conditions" "table_row"
|
||||
And following "Export" should download between "100" and "500" bytes
|
||||
And following "Export" should download a file that:
|
||||
| Contains file in zip | model-config.json |
|
||||
|
||||
Scenario: Check invalid site elements
|
||||
When I open the action menu in "Students at risk of not meeting the course completion conditions" "table_row"
|
||||
|
||||
+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));
|
||||
@@ -345,7 +345,7 @@ class api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete linked login
|
||||
* Delete a users own linked login
|
||||
*
|
||||
* Requires auth/oauth2:managelinkedlogins capability at the user context.
|
||||
*
|
||||
@@ -353,14 +353,19 @@ class api {
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete_linked_login($linkedloginid) {
|
||||
$login = new linked_login($linkedloginid);
|
||||
$userid = $login->get('userid');
|
||||
global $USER;
|
||||
|
||||
if (\core\session\manager::is_loggedinas()) {
|
||||
throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$context = context_user::instance($userid);
|
||||
$login = linked_login::get_record([
|
||||
'id' => $linkedloginid,
|
||||
'userid' => $USER->id,
|
||||
'confirmtoken' => '',
|
||||
], MUST_EXIST);
|
||||
|
||||
$context = context_user::instance($login->get('userid'));
|
||||
require_capability('auth/oauth2:managelinkedlogins', $context);
|
||||
|
||||
$login->delete();
|
||||
|
||||
@@ -137,6 +137,7 @@ class api_test extends \advanced_testcase {
|
||||
$issuer = \core\oauth2\api::create_standard_issuer('google');
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$info = [];
|
||||
$info['username'] = 'banana';
|
||||
@@ -169,6 +170,30 @@ class api_test extends \advanced_testcase {
|
||||
$this->assertEquals($newuser->id, $match->get('userid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we cannot deleted a linked login for another user
|
||||
*/
|
||||
public function test_delete_linked_login_other_user(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$issuer = \core\oauth2\api::create_standard_issuer('google');
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
api::link_login([
|
||||
'username' => 'banana',
|
||||
'email' => 'banana@example.com',
|
||||
], $issuer, $user->id);
|
||||
|
||||
/** @var linked_login $linkedlogin */
|
||||
$linkedlogin = api::get_linked_logins($user->id)[0];
|
||||
|
||||
// We are logged in as a different user, so cannot delete this.
|
||||
$this->expectException(\dml_missing_record_exception::class);
|
||||
api::delete_linked_login($linkedlogin->get('id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that is_enabled correctly identifies when the plugin is enabled.
|
||||
*/
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -180,7 +180,18 @@ $PAGE->set_pagelayout('admin');
|
||||
|
||||
if ($rssid) {
|
||||
$isadding = false;
|
||||
$rssrecord = $DB->get_record('block_rss_client', array('id' => $rssid), '*', MUST_EXIST);
|
||||
|
||||
if ($managesharedfeeds) {
|
||||
$select = 'id = :id AND (userid = :userid OR shared = 1)';
|
||||
} else {
|
||||
$select = 'id = :id AND userid = :userid';
|
||||
}
|
||||
|
||||
$rssrecord = $DB->get_record_select('block_rss_client', $select, [
|
||||
'id' => $rssid,
|
||||
'userid' => $USER->id,
|
||||
], '*', MUST_EXIST);
|
||||
|
||||
} else {
|
||||
$isadding = true;
|
||||
$rssrecord = new stdClass;
|
||||
|
||||
@@ -61,20 +61,27 @@ if ($returnurl) {
|
||||
$baseurl = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
|
||||
$PAGE->set_url($baseurl);
|
||||
|
||||
if ($managesharedfeeds) {
|
||||
$select = '(userid = :userid OR shared = 1)';
|
||||
} else {
|
||||
$select = 'userid = :userid';
|
||||
}
|
||||
|
||||
// Process any actions
|
||||
if ($deleterssid && confirm_sesskey()) {
|
||||
$DB->delete_records('block_rss_client', array('id'=>$deleterssid));
|
||||
|
||||
$deleterssid = $DB->get_field_select('block_rss_client', 'id', "id = :id AND {$select}", [
|
||||
'id' => $deleterssid,
|
||||
'userid' => $USER->id
|
||||
], MUST_EXIST);
|
||||
|
||||
$DB->delete_records('block_rss_client', ['id' => $deleterssid]);
|
||||
|
||||
redirect($PAGE->url, get_string('feeddeleted', 'block_rss_client'));
|
||||
}
|
||||
|
||||
// Display the list of feeds.
|
||||
if ($managesharedfeeds) {
|
||||
$select = '(userid = ' . $USER->id . ' OR shared = 1)';
|
||||
} else {
|
||||
$select = 'userid = ' . $USER->id;
|
||||
}
|
||||
$feeds = $DB->get_records_select('block_rss_client', $select, null, $DB->sql_order_by_text('title'));
|
||||
$feeds = $DB->get_records_select('block_rss_client', $select, ['userid' => $USER->id], $DB->sql_order_by_text('title'));
|
||||
|
||||
$strmanage = get_string('managefeeds', 'block_rss_client');
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Feature: Edit activities in main menu block
|
||||
I need to add and edit activities there
|
||||
|
||||
@javascript
|
||||
Scenario: Edit name of acitivity in-place in site main menu block
|
||||
Scenario: Edit name of activity in-place in site main menu block
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
@@ -36,6 +36,7 @@ Feature: Edit activities in main menu block
|
||||
| forum | Acceptance test site | 0 | Visible forum |
|
||||
| forum | Acceptance test site | 0 | My forum name |
|
||||
And I log in as "admin"
|
||||
And I change window size to "large"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And "My forum name" activity in site main menu block should have "Hide" editing icon
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,11 +33,6 @@ Feature: Course activity controls works as expected
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
When I click on <targetpage> "link" in the "region-main" "region"
|
||||
And I add the "Recent activity" block
|
||||
And I open the action menu in "Recent activity" "block"
|
||||
And I click on "Delete Recent activity block" "link"
|
||||
And I click on "Delete" "button" in the "Delete block?" "dialogue"
|
||||
And <belowpage> "section" <should_see_other_sections> exist
|
||||
And <belowpage> "section" <should_see_other_sections> exist
|
||||
And I open "Test forum name 1" actions menu
|
||||
And I click on "Edit settings" "link" in the "Test forum name 1" activity
|
||||
@@ -100,10 +95,6 @@ Feature: Course activity controls works as expected
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
When I click on <targetpage> "link" in the "region-main" "region"
|
||||
And I add the "Recent activity" block
|
||||
And I open the action menu in "Recent activity" "block"
|
||||
And I click on "Delete Recent activity block" "link"
|
||||
And I press "Yes"
|
||||
And <belowpage> "section" <should_see_other_sections> exist
|
||||
And I click on "Edit settings" "link" in the "Test forum name 1" activity
|
||||
And I should see "Updating Forum"
|
||||
|
||||
@@ -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' => [
|
||||
|
||||
@@ -9,6 +9,7 @@ Feature: Users can auto-enrol themself in courses where self enrolment is allowe
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| student2 | Student | 2 | student2@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
@@ -64,13 +65,13 @@ Feature: Users can auto-enrol themself in courses where self enrolment is allowe
|
||||
Scenario: Self-enrolment enabled requiring a group enrolment key
|
||||
Given I log in as "teacher1"
|
||||
When I add "Self enrolment" enrolment method in "Course 1" with:
|
||||
| Custom instance name | Test student enrolment |
|
||||
| Enrolment key | moodle_rules |
|
||||
| Use group enrolment keys | Yes |
|
||||
| Custom instance name | Test student enrolment |
|
||||
| Enrolment key | moodle_rules |
|
||||
| Use group enrolment keys | Yes |
|
||||
And I am on the "Course 1" "groups" page
|
||||
And I press "Create group"
|
||||
And I set the following fields to these values:
|
||||
| Group name | Group 1 |
|
||||
| Group name | Group 1 |
|
||||
| Enrolment key | Test-groupenrolkey1 |
|
||||
And I press "Save changes"
|
||||
And I log out
|
||||
@@ -82,6 +83,16 @@ Feature: Users can auto-enrol themself in courses where self enrolment is allowe
|
||||
Then I should see "Topic 1"
|
||||
And I should not see "Enrolment options"
|
||||
And I should not see "Enrol me in this course"
|
||||
And I am on the "Course 1" course page logged in as student2
|
||||
And I set the following fields to these values:
|
||||
| Enrolment key | moodle_rules |
|
||||
And I press "Enrol me"
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
And I navigate to course participants
|
||||
And the following should exist in the "participants" table:
|
||||
| First name | Email address | Roles | Groups |
|
||||
| Student 1 | student1@example.com | Student | Group 1 |
|
||||
| Student 2 | student2@example.com | Student | No groups |
|
||||
|
||||
@javascript
|
||||
Scenario: Edit a self-enrolled user's enrolment from the course participants page
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -28,6 +28,8 @@ Feature: Within the grader report, test that we can open our generic filter drop
|
||||
| activity | course | idnumber | name |
|
||||
| assign | C1 | a1 | Test assignment one |
|
||||
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
|
||||
# This is required for now to prevent the overflow region affecting the report.
|
||||
And I change window size to "large"
|
||||
|
||||
Scenario: A teacher can open the filter component
|
||||
Given I should see "Filter by name"
|
||||
|
||||
@@ -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,41 @@
|
||||
<?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';
|
||||
$string['cliincorrectvalueerror'] = 'Error, valor incorrecte "{$a->value}" for "{$a->option}"';
|
||||
$string['cliincorrectvalueretry'] = 'Valor incorrecte, per favor essaya novemente';
|
||||
$string['clitypevalue'] = 'valor de typo';
|
||||
$string['clitypevaluedefault'] = 'valor de typo,pressa Enter per usar le vaor predefinite ({$a})';
|
||||
$string['cliunknowoption'] = 'Uotiones non recognoscite:
|
||||
{$a}
|
||||
Per favor usa le option --help.';
|
||||
$string['cliyesnoprompt'] = 'typa s (significa si) o n (significa no)';
|
||||
@@ -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';
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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['language'] = 'Linguage';
|
||||
$string['moodlelogo'] = 'Logo de Moodle';
|
||||
$string['next'] = 'Proxime';
|
||||
$string['previous'] = 'Previe';
|
||||
$string['reload'] = 'Recarga';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user