language: php
php:
- # Moodle supports versions 5.4, 5.5, and 5.6 of PHP.
- # Order by fastest to slowest.
- # We currently only run the highest and lowest versions to reduce the load on travis-ci.org.
- - 5.6
+ # We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
+ - 7.0
+ # - 5.6
# - 5.5
- 5.4
- # We hope to offer PHP 7 support in the near future.
- - nightly
-
-services:
- # Ensure that memcached and mongodb are running for testing of those MUC stores.
- - memcached
- - mongodb
-
env:
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
# start first so that the total run time is not too high.
# It will not stop the jobs from running.
fast_finish: true
- # Always allow failure on nightly.
- # It's a nightly build and failures can happen.
- allow_failures:
- - php: nightly
-
exclude:
- # PHP 7 is not yet supported for actual runs.
- # Exclude it by default - we include it for CITEST only later.
- - php: nightly
-
# MySQL - it's just too slow.
- # Exclude it on all versions except for 5.6.
+ # Exclude it on all versions except for 7.0
+ # - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
+ # php: 5.6
+ #
# - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
# php: 5.5
- env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
php: 5.4
- include:
- # Attempt to run the CITEST set on PHP 7.
- - php: nightly
- env: DB=none PHPUNIT=false INSTALL=false CITEST=true
-
cache:
directories:
- $HOME/.composer/cache
install:
+ # Disable xdebug. We aren't generating code coverage, and it has a huge impact upon test performance.
+ - rm /home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
+
# Set the encrypted GITHUB_TOKEN if it's available to raise the API limit.
- if [ -n "$GITHUB_APITOKEN" ]; then composer config github-oauth.github.com $GITHUB_APITOKEN; fi
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
- travis_retry composer install --prefer-dist --no-interaction
- - echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- - echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
-
before_script:
- >
if [ "$INSTALL" = 'true' -o "$PHPUNIT" = 'true' ];
sed -i \
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
- -e "/require_once/i define('TEST_CACHESTORE_MEMCACHE_TESTSERVERS', '127.0.0.1:11211');" \
- -e "/require_once/i define('TEST_CACHESTORE_MEMCACHED_TESTSERVERS', '127.0.0.1:11211');" \
- -e "/require_once/i define('TEST_CACHESTORE_MONGODB_TESTSERVER', 'mongodb://localhost:27017');" \
config.php ;
# Initialise PHPUnit for Moodle.
var path = require('path'),
fs = require('fs'),
tasks = {},
- cwd = process.env.PWD || process.cwd();
+ cwd = process.env.PWD || process.cwd(),
+ inAMD = path.basename(cwd) == 'amd';
// Project configuration.
grunt.initConfig({
jshint: {
options: {jshintrc: '.jshintrc'},
- files: ['**/amd/src/*.js']
+ files: [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js']
},
uglify: {
dynamic_mappings: {
}
)
}
+ },
+ less: {
+ bootstrapbase: {
+ files: {
+ "theme/bootstrapbase/style/moodle.css": "theme/bootstrapbase/less/moodle.less",
+ "theme/bootstrapbase/style/editor.css": "theme/bootstrapbase/less/editor.less",
+ },
+ options: {
+ compress: true
+ }
+ }
}
});
args.push('--lint-stderr');
}
+ if (grunt.option('no-color')) {
+ args.push('--color=false');
+ }
+
var execShifter = function() {
shifter = exec("node", args, {
if (path.basename(path.resolve(cwd, '../../')) == 'yui') {
grunt.task.run('shifter');
// Are we in an AMD directory?
- } else if (path.basename(cwd) == 'amd') {
- grunt.task.run('jshint');
- grunt.task.run('uglify');
+ } else if (inAMD) {
+ grunt.task.run('amd');
} else {
// Run them all!.
- grunt.task.run('shifter');
- grunt.task.run('jshint');
- grunt.task.run('uglify');
+ grunt.task.run('css');
+ grunt.task.run('js');
}
};
// Register NPM tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-less');
- // Register the shifter task.
+ // Register JS tasks.
grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
+ grunt.registerTask('amd', ['jshint', 'uglify']);
+ grunt.registerTask('js', ['amd', 'shifter']);
+
+ // Register CSS taks.
+ grunt.registerTask('css', ['less:bootstrapbase']);
// Register the startup task.
grunt.registerTask('startup', 'Run the correct tasks for the current directory', tasks.startup);
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.4.4" level="required">
- <RESTRICT function="restrict_php_version_7" message="unsupportedphpversion7" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
$registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOODLEORGHUBURL, 'confirmed' => 1));
// Check if there are any cache warnings.
$cachewarnings = cache_helper::warnings();
+// Check if there are events 1 API handlers.
+$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
admin_externalpage_setup('adminnotifications');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
- $registered, $cachewarnings);
+ $registered, $cachewarnings, $eventshandlers);
* @param array|null $availableupdates array of \core\update\info objects or null
* @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
* @param string[] $cachewarnings An array containing warnings from the Cache API.
+ * @param array $eventshandlers Events 1 API handlers.
*
* @return string HTML to output.
*/
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
- $buggyiconvnomb, $registered, array $cachewarnings = array()) {
+ $buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0) {
global $CFG;
$output = '';
$output .= $this->db_problems($dbproblems);
$output .= $this->maintenance_mode_warning($maintenancemode);
$output .= $this->cache_warnings($cachewarnings);
+ $output .= $this->events_handlers($eventshandlers);
$output .= $this->registration_warning($registered);
//////////////////////////////////////////////////////////////////////////////////////////////////
return join("\n", array_map(array($this, 'warning'), $cachewarnings));
}
+ /**
+ * Renders events 1 API handlers warning.
+ *
+ * @param array $eventshandlers
+ * @return string
+ */
+ public function events_handlers($eventshandlers) {
+ if ($eventshandlers) {
+ $components = '';
+ foreach ($eventshandlers as $eventhandler) {
+ $components .= $eventhandler->component . ', ';
+ }
+ $components = rtrim($components, ', ');
+ return $this->warning(get_string('eventshandlersinuse', 'admin', $components));
+ }
+ }
+
/**
* Render an appropriate message if the site in in maintenance mode.
* @param bool $maintenancemode
} else {
// Updating role.
$DB->update_record('role', $this->role);
+
+ // This will ensure the course contacts cache is purged so name changes get updated in
+ // the UI. It would be better to do this only when we know that fields affected are
+ // updated. But thats getting into the weeds of the coursecat cache and role edits
+ // should not be that frequent, so here is the ugly brutal approach.
+ coursecat::role_assignment_changed($this->role->id, context_system::instance());
}
// Assignable contexts.
// Create a page for general import configuration and defaults.
$temp = new admin_settingpage('importgeneralsettings', new lang_string('importgeneralsettings', 'backup'), 'moodle/backup:backupcourse');
$temp->add(new admin_setting_configtext('backup/import_general_maxresults', new lang_string('importgeneralmaxresults', 'backup'), new lang_string('importgeneralmaxresults_desc', 'backup'), 10));
+ $temp->add(new admin_setting_configcheckbox('backup/import_general_duplicate_admin_allowed',
+ new lang_string('importgeneralduplicateadminallowed', 'backup'),
+ new lang_string('importgeneralduplicateadminallowed_desc', 'backup'), 0));
$ADMIN->add('backups', $temp);
// Create a page for automated backups configuration and defaults.
$options = array();
foreach ($availablelangs as $alang) {
if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !$controller->is_installed_lang($alang[0], $alang[1])) {
- $options[$alang[0]] = $alang[2].' ('.$alang[0].')';
+ $options[$alang[0]] = $alang[2].' ‎('.$alang[0].')‎';
}
}
if (!empty($options)) {
if (empty($interface) || ($reader instanceof $interface)) {
$return[$plugin] = $reader;
}
- // TODO MDL-49291 These conditions should be removed as part of the 2nd stage deprecation.
- if ($reader instanceof \core\log\sql_internal_reader) {
- debugging('\core\log\sql_internal_reader has been deprecated in favour of \core\log\sql_internal_table_reader.' .
- ' Update ' . get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
- } else if ($reader instanceof \core\log\sql_select_reader) {
- debugging('\core\log\sql_select_reader has been deprecated in favour of \core\log\sql_reader. Update ' .
- get_class($reader) . ' to use the new interface.', DEBUG_DEVELOPER);
- }
- }
-
- // TODO MDL-49291 This section below (until the final return) should be removed as part of the 2nd stage deprecation.
- $isselectreader = (ltrim($interface, '\\') === 'core\log\sql_select_reader');
- $isinternalreader = (ltrim($interface, '\\') === 'core\log\sql_internal_reader');
- if ($isselectreader || $isinternalreader) {
-
- if ($isselectreader) {
- $alternative = '\core\log\sql_reader';
- } else {
- $alternative = '\core\log\sql_internal_table_reader';
- }
-
- if (count($return) === 0) {
- // If there are no classes implementing the provided interface and the provided interface is one of
- // the deprecated ones, we return the non-deprecated alternatives. It should be safe as the new interface
- // is adding a new method but not changing the existing ones.
- debugging($interface . ' has been deprecated in favour of ' . $alternative . '. Returning ' . $alternative .
- ' instances instead. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
- $return = $this->get_readers($alternative);
- } else {
- debugging($interface . ' has been deprecated in favour of ' . $alternative .
- '. Please call get_readers() using the new interface.', DEBUG_DEVELOPER);
- }
}
return $return;
$this->data = $coursedata;
$this->enrolmentdata = tool_uploadcourse_helper::get_enrolment_data($this->rawdata);
+ if (isset($this->rawdata['tags']) && strval($this->rawdata['tags']) !== '') {
+ $this->data['tags'] = preg_split('/\s*,\s*/', trim($this->rawdata['tags']), -1, PREG_SPLIT_NO_EMPTY);
+ }
+
// Restore data.
// TODO Speed up things by not really extracting the backup just yet, but checking that
// the backup file or shortname passed are valid. Extraction should happen in proceed().
'groupmode' => '2',
'groupmodeforce' => '1',
'enablecompletion' => '1',
+ 'tags' => 'Cat, Dog',
'role_teacher' => 'Knight',
'role_manager' => 'Jedi',
$this->assertEquals($data['groupmode'], $course->groupmode);
$this->assertEquals($data['groupmodeforce'], $course->groupmodeforce);
$this->assertEquals($data['enablecompletion'], $course->enablecompletion);
+ $this->assertEquals($data['tags'], join(', ', core_tag_tag::get_item_tags_array('core', 'course', $course->id)));
// Roles.
$roleids = array();
'suspended', // 1 means suspend user account, 0 means activate user account, nothing means keep as is for existing users
'deleted', // 1 means delete user
'mnethostid', // Can not be used for adding, updating or deleting of users - only for enrolments, groups, cohorts and suspending.
+ 'interests',
);
// Include all name fields.
$STD_FIELDS = array_merge($STD_FIELDS, get_all_user_name_fields());
if (isset($USER->$key) and is_array($USER->$key)) {
// this must be some hacky field that is abusing arrays to store content and format
$user->$key = array();
- $user->$key['text'] = $value;
- $user->$key['format'] = FORMAT_MOODLE;
+ $user->{$key['text']} = $value;
+ $user->{$key['format']} = FORMAT_MOODLE;
} else {
$user->$key = trim($value);
}
}
}
+ // Update user interests.
+ if (isset($user->interests) && strval($user->interests) !== '') {
+ useredit_update_interests($user, preg_split('/\s*,\s*/', $user->interests, -1, PREG_SPLIT_NO_EMPTY));
+ }
// add to cohort first, it might trigger enrolments indirectly - do NOT create cohorts here!
foreach ($filecolumns as $column) {
-@core @core_admin @_file_upload
+@tool @tool_uploaduser @_file_upload
Feature: Upload users
In order to add users to the system
As an admin
And I follow "Groups"
And I set the field "groups" to "Section 1 (1)"
And the "members" select box should contain "Tom Jones"
+
+ @javascript
+ Scenario: Upload users with custom profile fields
+ # Create user profile field.
+ Given I log in as "admin"
+ And I navigate to "User profile fields" node in "Site administration > Users > Accounts"
+ And I set the field "datatype" to "Text area"
+ And I set the following fields to these values:
+ | Short name | superfield |
+ | Name | Super field |
+ And I click on "Save changes" "button"
+ # Upload users.
+ When I navigate to "Upload users" node in "Site administration > Users > Accounts"
+ And I upload "lib/tests/fixtures/upload_users_profile.csv" file to "File" filemanager
+ And I press "Upload users"
+ And I press "Upload users"
+ # Check that users were created and the superfield is filled.
+ And I navigate to "Browse list of users" node in "Site administration > Users > Accounts"
+ And I follow "Tom Jones"
+ And I should see "Super field"
+ And I should see "The big guy"
+ And I log out
$descparams = new stdClass();
$descparams->atag = $atag;
$descparams->mode = get_string('debugnormal', 'admin');
- $amfclienturl = new moodle_url('/webservice/amf/testclient/index.php');
- $amfclientatag =html_writer::tag('a', get_string('amftestclient', 'webservice'),
- array('href' => $amfclienturl));
- $descparams->amfatag = $amfclientatag;
echo get_string('testclientdescription', 'webservice', $descparams);
echo $OUTPUT->box_end();
/**
* Constructor.
*/
- function auth_plugin_cas() {
+ public function __construct() {
$this->authtype = 'cas';
$this->roleauth = 'auth_cas';
$this->errorlogtag = '[AUTH CAS] ';
$this->init_plugin($this->authtype);
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_cas() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
function prevent_local_passwords() {
return true;
}
$this->cleanup_auth_database();
}
+
+ /**
+ * Testing the function _colonscope() from ADOdb.
+ */
+ public function test_adodb_colonscope() {
+ global $CFG;
+ require_once($CFG->libdir.'/adodb/adodb.inc.php');
+ require_once($CFG->libdir.'/adodb/drivers/adodb-odbc.inc.php');
+ require_once($CFG->libdir.'/adodb/drivers/adodb-db2ora.inc.php');
+
+ $this->resetAfterTest(false);
+
+ $sql = "select * from table WHERE column=:1 AND anothercolumn > :0";
+ $arr = array('b', 1);
+ list($sqlout, $arrout) = _colonscope($sql,$arr);
+ $this->assertEquals("select * from table WHERE column=? AND anothercolumn > ?", $sqlout);
+ $this->assertEquals(array(1, 'b'), $arrout);
+ }
}
/**
* Constructor.
*/
- function auth_plugin_email() {
+ public function __construct() {
$this->authtype = 'email';
$this->config = get_config('auth/email');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_email() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_fc() {
+ public function __construct() {
$this->authtype = 'fc';
$this->config = get_config('auth/fc');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_fc() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
var $_debug = FALSE; // set to true to see some debug info
// class constructor
- function fcFPP($host="localhost", $port="3333")
+ public function __construct($host="localhost", $port="3333")
{
$this->_hostname = $host;
$this->_port = $port;
$this->_pwd = "";
}
+ function fcFPP($host="localhost", $port="3333")
+ {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct($host, $port);
+ }
+
// open a connection to the FirstClass server
function open()
{
/**
* Constructor.
*/
- function auth_plugin_imap() {
+ public function __construct() {
$this->authtype = 'imap';
$this->config = get_config('auth/imap');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_imap() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor with initialisation.
*/
- function auth_plugin_ldap() {
+ public function __construct() {
$this->authtype = 'ldap';
$this->roleauth = 'auth_ldap';
$this->errorlogtag = '[AUTH LDAP] ';
$this->init_plugin($this->authtype);
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_ldap() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_manual() {
+ public function __construct() {
$this->authtype = 'manual';
$config = get_config(self::COMPONENT_NAME);
$legacyconfig = get_config(self::LEGACY_COMPONENT_NAME);
$this->config = (object)array_merge((array)$legacyconfig, (array)$config);
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_manual() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist. (Non-mnet accounts only!)
/**
* Constructor.
*/
- function auth_plugin_mnet() {
+ public function __construct() {
$this->authtype = 'mnet';
$this->config = get_config('auth_mnet');
$this->mnet = get_mnet_environment();
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_mnet() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* This function is normally used to determine if the username and password
* are correct for local logins. Always returns false, as local users do not
/**
* Constructor.
*/
- function auth_plugin_nntp() {
+ public function __construct() {
$this->authtype = 'nntp';
$this->config = get_config('auth/nntp');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_nntp() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_nologin() {
+ public function __construct() {
$this->authtype = 'nologin';
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_nologin() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Do not allow any login.
*
/**
* Constructor.
*/
- function auth_plugin_none() {
+ public function __construct() {
$this->authtype = 'none';
$this->config = get_config('auth/none');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_none() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work or don't exist and false
* if the user exists and the password is wrong.
/**
* Constructor.
*/
- function auth_plugin_pam() {
+ public function __construct() {
$this->authtype = 'pam';
$this->config = get_config('auth/pam');
$this->errormessage = '';
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_pam() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_pop3() {
+ public function __construct() {
$this->authtype = 'pop3';
$this->config = get_config('auth/pop3');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_pop3() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_radius() {
+ public function __construct() {
$this->authtype = 'radius';
$this->config = get_config('auth/radius');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_radius() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_shibboleth() {
+ public function __construct() {
$this->authtype = 'shibboleth';
$this->config = get_config('auth/shibboleth');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_shibboleth() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
/**
* Constructor.
*/
- function auth_plugin_webservice() {
+ public function __construct() {
$this->authtype = 'webservice';
$this->config = get_config('auth/webservice');
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function auth_plugin_webservice() {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct();
+ }
+
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
private $css;
private $html;
- function cssparser($html = true) {
+ public function __construct($html = true) {
// Register "destructor"
core_shutdown_manager::register_function(array(&$this, "finalize"));
$this->html = ($html != false);
$this->Clear();
}
+ /**
+ * Old syntax of class constructor. Deprecated in PHP7.
+ *
+ * @deprecated since Moodle 3.1
+ */
+ public function cssparser($html = true) {
+ debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
+ self::__construct($html);
+ }
+
function finalize() {
unset($this->css);
}
}
return $result;
}
-}
\ No newline at end of file
+}
$data = (object)$data;
- if (!empty($CFG->usetags)) { // if enabled in server
- // TODO: This is highly inneficient. Each time we add one tag
- // we fetch all the existing because tag_set() deletes them
- // so everything must be reinserted on each call
- $tags = array();
- $existingtags = tag_get_tags('course', $this->get_courseid());
- // Re-add all the existitng tags
- foreach ($existingtags as $existingtag) {
- $tags[] = $existingtag->rawname;
- }
- // Add the one being restored
- $tags[] = $data->rawname;
- // Send all the tags back to the course
- tag_set('course', $this->get_courseid(), $tags, 'core',
- context_course::instance($this->get_courseid())->id);
- }
+ core_tag_tag::add_item_tag('core', 'course', $this->get_courseid(),
+ context_course::instance($this->get_courseid()), $data->rawname);
}
public function process_allowed_module($data) {
return;
}
- if (!empty($CFG->usetags)) { // if enabled in server
- // TODO: This is highly inefficient. Each time we add one tag
- // we fetch all the existing because tag_set() deletes them
- // so everything must be reinserted on each call
- $tags = array();
- $existingtags = tag_get_tags('question', $newquestion);
- // Re-add all the existitng tags
- foreach ($existingtags as $existingtag) {
- $tags[] = $existingtag->rawname;
- }
- // Add the one being restored
- $tags[] = $data->rawname;
+ if (core_tag_tag::is_enabled('core_question', 'question')) {
+ $tagname = $data->rawname;
// Get the category, so we can then later get the context.
$categoryid = $this->get_new_parentid('question_category');
if (empty($this->cachedcategory) || $this->cachedcategory->id != $categoryid) {
$this->cachedcategory = $DB->get_record('question_categories', array('id' => $categoryid));
}
- // Send all the tags back to the question
- tag_set('question', $newquestion, $tags, 'core_question', $this->cachedcategory->contextid);
+ // Add the tag to the question.
+ core_tag_tag::add_item_tag('core_question', 'question', $newquestion,
+ context::instance_by_id($this->cachedcategory->contextid),
+ $tagname);
}
}
}
// Process tags
- if (!empty($CFG->usetags) && isset($user->tags)) { // if enabled in server and present in backup
+ if (core_tag_tag::is_enabled('core', 'user') && isset($user->tags)) { // If enabled in server and present in backup.
$tags = array();
foreach($user->tags['tag'] as $usertag) {
$usertag = (object)$usertag;
$tags[] = $usertag->rawname;
}
- if (empty($newuserctxid)) {
- $newuserctxid = null; // Tag apis expect a null contextid not 0.
- }
- tag_set('user', $newuserid, $tags, 'core', $newuserctxid);
+ core_tag_tag::set_item_tags('core', 'user', $newuserid,
+ context_user::instance($newuserid), $tags);
}
// Process preferences
* 1F - None of the above, return true => User needs to be created
*
* if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
- * 2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
+ * 2A - Normal check:
+ * 2A1 - If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
+ * 2A2 - Exceptional handling (MDL-21912): Match "admin" username. Then, if import_general_duplicate_admin_allowed is
+ * enabled, attempt to map the admin user to the user 'admin_[oldsiteid]' if it exists. If not,
+ * the user 'admin_[oldsiteid]' will be created in precheck_included users
* 2B - Handle users deleted in DB and "alive" in backup file:
* 2B1 - If match by mnethost and user is deleted in DB and not empty email = md5(username) and
* (username LIKE 'backup_email.%' or non-zero firstaccess) => ok, return target user
* Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
* hence we are looking there for usernames if not empty. See delete_user()
*/
- protected static function precheck_user($user, $samesite) {
+ protected static function precheck_user($user, $samesite, $siteid = null) {
global $CFG, $DB;
// Handle checks from same site backups
// Handle checks from different site backups
} else {
- // 2A - If match by username and mnethost and
+ // 2A1 - If match by username and mnethost and
// (email or non-zero firstaccess) => ok, return target user
if ($rec = $DB->get_record_sql("SELECT *
FROM {user} u
return $rec; // Matching user found, return it
}
+ // 2A2 - If we're allowing conflicting admins, attempt to map user to admin_[oldsiteid].
+ if (get_config('backup', 'import_general_duplicate_admin_allowed') && $user->username === 'admin' && $siteid
+ && $user->mnethostid == $CFG->mnet_localhost_id) {
+ if ($rec = $DB->get_record('user', array('username' => 'admin_' . $siteid))) {
+ return $rec;
+ }
+ }
+
// 2B - Handle users deleted in DB and "alive" in backup file
// Note: for DB deleted users email is stored in username field, hence we
// are looking there for emails. See delete_user()
// Calculate the context we are going to use for capability checking
$context = context_course::instance($courseid);
+ // When conflicting users are detected we may need original site info.
+ $restoreinfo = restore_controller_dbops::load_controller($restoreid)->get_info();
+
// Calculate if we have perms to create users, by checking:
// to 'moodle/restore:createuser' and 'moodle/restore:userinfo'
// and also observe $CFG->disableusercreationonrestore
}
// Now, precheck that user and, based on returned results, annotate action/problem
- $usercheck = self::precheck_user($user, $samesite);
+ $usercheck = self::precheck_user($user, $samesite, $restoreinfo->original_site_identifier_hash);
if (is_object($usercheck)) { // No problem, we have found one user in DB to be mapped to
// Annotate it, for later process. Set newitemid to mapping user->id
self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, $usercheck->id);
} else if ($usercheck === false) { // Found conflict, report it as problem
- $problems[] = get_string('restoreuserconflict', '', $user->username);
+ if (!get_config('backup', 'import_general_duplicate_admin_allowed')) {
+ $problems[] = get_string('restoreuserconflict', '', $user->username);
+ } else if ($user->username == 'admin') {
+ if (!$cancreateuser) {
+ $problems[] = get_string('restorecannotcreateuser', '', $user->username);
+ }
+ if ($user->mnethostid != $CFG->mnet_localhost_id) {
+ $problems[] = get_string('restoremnethostidmismatch', '', $user->username);
+ }
+ if (!$problems) {
+ // Duplicate admin allowed, append original site idenfitier to username.
+ $user->username .= '_' . $restoreinfo->original_site_identifier_hash;
+ self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, 0, null, (array)$user);
+ }
+ }
} else if ($usercheck === true) { // User needs to be created, check if we are able
if ($cancreateuser) { // Can create user, set newitemid to 0 so will be created later
}
// Arrived here log is empty, no rule was able to perform the conversion, log the problem
if (empty($newlog)) {
- self::$task->log('Log module-action "' . $keyname . '" process problem. Not restored', backup::LOG_DEBUG);
+ self::$task->log('Log module-action "' . $keyname . '" process problem. Not restored. ' .
+ json_encode($log), backup::LOG_DEBUG);
}
} else { // Action not found log the problem
- self::$task->log('Log module-action "' . $keyname . '" unknown. Not restored', backup::LOG_DEBUG);
+ self::$task->log('Log module-action "' . $keyname . '" unknown. Not restored. '.json_encode($log), backup::LOG_DEBUG);
$newlog = false;
}
}
// Decode file.php calls
$search = array ("$@FILEPHP@$");
- $replace = array(get_file_url($this->courseid));
+ $replace = array(moodle_url::make_legacyfile_url($this->courseid, null));
$result = str_replace($search, $replace, $cdata);
// Now $@SLASH@$ and $@FORCEDOWNLOAD@$ MDL-18799
$search = array('$@SLASH@$', '$@FORCEDOWNLOAD@$');
* @return void
*/
protected function add_subplugin_structure($subplugintype, $element, $multiple, $plugintype = null, $pluginname = null) {
+ global $CFG;
+ // This global declaration is required, because where we do require_once($backupfile);
+ // That file may in turn try to do require_once($CFG->dirroot ...).
+ // That worked in the past, we should keep it working.
// Verify if this is a BC call for an activity backup. See NOTE above for this special case.
if ($plugintype === null and $pluginname === null) {
* @return void
*/
protected function add_subplugin_structure($subplugintype, $element, $plugintype = null, $pluginname = null) {
+ global $CFG;
+ // This global declaration is required, because where we do require_once($backupfile);
+ // That file may in turn try to do require_once($CFG->dirroot ...).
+ // That worked in the past, we should keep it working.
// Verify if this is a BC call for an activity restore. See NOTE above for this special case.
if ($plugintype === null and $pluginname === null) {
} catch (exception $e) {
$this->assertTrue($e instanceof base_setting_exception);
$this->assertEquals($e->errorcode, 'incorrect_object_passed');
+ } catch (TypeError $e) {
+ // On PHP7+ we get a TypeError raised, lets check we've the right error.
+ $this->assertRegexp('/must be an instance of backup_setting_ui/', $e->getMessage());
}
restore_error_handler();
} catch (exception $e) {
$this->assertTrue($e instanceof base_setting_exception);
$this->assertEquals($e->errorcode, 'incorrect_object_passed');
+ } catch (TypeError $e) {
+ // On PHP7+ we get a TypeError raised, lets check we've the right error.
+ $this->assertRegexp('/must be an instance of backup_setting_ui/', $e->getMessage());
}
restore_error_handler();
} catch (exception $e) {
$this->assertTrue($e instanceof backup_setting_exception);
$this->assertEquals($e->errorcode, 'incorrect_object_passed');
+ } catch (TypeError $e) {
+ // On PHP7+ we get a TypeError raised, lets check we've the right error.
+ $this->assertRegexp('/must be an instance of base_setting/', $e->getMessage());
}
restore_error_handler();
global $CFG;
require_once($CFG->libdir . '/badgeslib.php');
+require_once($CFG->dirroot . '/badges/lib.php');
class core_badges_badgeslib_testcase extends advanced_testcase {
protected $badgeid;
$this->assertStringMatchesFormat($testassertion->class, json_encode($assertion->get_badge_class()));
$this->assertStringMatchesFormat($testassertion->issuer, json_encode($assertion->get_issuer()));
}
+
+ /**
+ * Tests the core_badges_myprofile_navigation() function.
+ */
+ public function test_core_badges_myprofile_navigation() {
+ // Set up the test.
+ $tree = new \core_user\output\myprofile\tree();
+ $this->setAdminUser();
+ $badge = new badge($this->badgeid);
+ $badge->issue($this->user->id, true);
+ $iscurrentuser = true;
+ $course = null;
+
+ // Enable badges.
+ set_config('enablebadges', true);
+
+ // Check the node tree is correct.
+ core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course);
+ $reflector = new ReflectionObject($tree);
+ $nodes = $reflector->getProperty('nodes');
+ $nodes->setAccessible(true);
+ $this->assertArrayHasKey('localbadges', $nodes->getValue($tree));
+ }
+
+ /**
+ * Tests the core_badges_myprofile_navigation() function with badges disabled..
+ */
+ public function test_core_badges_myprofile_navigation_badges_disabled() {
+ // Set up the test.
+ $tree = new \core_user\output\myprofile\tree();
+ $this->setAdminUser();
+ $badge = new badge($this->badgeid);
+ $badge->issue($this->user->id, true);
+ $iscurrentuser = false;
+ $course = null;
+
+ // Disable badges.
+ set_config('enablebadges', false);
+
+ // Check the node tree is correct.
+ core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course);
+ $reflector = new ReflectionObject($tree);
+ $nodes = $reflector->getProperty('nodes');
+ $nodes->setAccessible(true);
+ $this->assertArrayNotHasKey('localbadges', $nodes->getValue($tree));
+ }
+
+ /**
+ * Tests the core_badges_myprofile_navigation() function with a course badge.
+ */
+ public function test_core_badges_myprofile_navigation_with_course_badge() {
+ // Set up the test.
+ $tree = new \core_user\output\myprofile\tree();
+ $this->setAdminUser();
+ $badge = new badge($this->coursebadge);
+ $badge->issue($this->user->id, true);
+ $iscurrentuser = false;
+
+ // Check the node tree is correct.
+ core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $this->course);
+ $reflector = new ReflectionObject($tree);
+ $nodes = $reflector->getProperty('nodes');
+ $nodes->setAccessible(true);
+ $this->assertArrayHasKey('localbadges', $nodes->getValue($tree));
+ }
}
--- /dev/null
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+ In order to be display student scores as scales
+ As a user
+ I need to see the activity results block
+
+ Background:
+ Given the following "users" exist:
+ | username | firstname | lastname | email | idnumber |
+ | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+ | student1 | Student | 1 | student1@example.com | S1 |
+ | student2 | Student | 2 | student2@example.com | S2 |
+ | student3 | Student | 3 | student3@example.com | S3 |
+ | student4 | Student | 4 | student4@example.com | S4 |
+ | student5 | Student | 5 | student5@example.com | S5 |
+ And the following "courses" exist:
+ | fullname | shortname | category |
+ | Course 1 | C1 | 0 |
+ And the following "course enrolments" exist:
+ | user | course | role |
+ | teacher1 | C1 | editingteacher |
+ | student1 | C1 | student |
+ | student2 | C1 | student |
+ | student3 | C1 | student |
+ | student4 | C1 | student |
+ | student5 | C1 | student |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I navigate to "Grades" node in "Course administration"
+ And I navigate to "Scales" node in "Grade administration"
+ And I press "Add a new scale"
+ And I set the following fields to these values:
+ | Name | My Scale |
+ | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+ And I press "Save changes"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add a "Assignment" to section "1" and I fill the form with:
+ | Assignment name | Test assignment |
+ | Description | Offline text |
+ | assignsubmission_file_enabled | 0 |
+ | id_modgrade_type | Scale |
+ | id_modgrade_scale | My Scale |
+ And I follow "Course 1"
+ And I navigate to "Grades" node in "Course administration"
+ And I turn editing mode on
+ And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+ And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+ And I give the grade "Good" to the user "Student 3" for the grade item "Test assignment"
+ And I give the grade "Average" to the user "Student 4" for the grade item "Test assignment"
+ And I give the grade "Not good enough" to the user "Student 5" for the grade item "Test assignment"
+ And I press "Save changes"
+ And I follow "Course 1"
+
+ Scenario: Configure the block on the course page to show 1 high score
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 1 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display full names |
+ | id_config_decimalpoints | 0 |
+ And I press "Save changes"
+ Then I should see "Student 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using full names
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display full names |
+ And I press "Save changes"
+ Then I should see "Student 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "Student 2" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "Student 3" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display only ID numbers |
+ And I press "Save changes"
+ Then I should see "User S1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "User S2" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "User S3" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Anonymous results |
+ And I press "Save changes"
+ Then I should see "User" in the "Activity results" "block"
+ And I should not see "Student 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should not see "Student 2" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should not see "Student 3" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
--- /dev/null
+@block @block_activity_results
+Feature: The activity results block displays student scores as scales
+ In order to be display student scores as scales
+ As a user
+ I need to see the activity results block
+
+ Background:
+ Given the following "users" exist:
+ | username | firstname | lastname | email | idnumber |
+ | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+ | student1 | Student | 1 | student1@example.com | S1 |
+ | student2 | Student | 2 | student2@example.com | S2 |
+ | student3 | Student | 3 | student3@example.com | S3 |
+ | student4 | Student | 4 | student4@example.com | S4 |
+ | student5 | Student | 5 | student5@example.com | S5 |
+ | student6 | Student | 6 | student6@example.com | S6 |
+ And the following "courses" exist:
+ | fullname | shortname | category |
+ | Course 1 | C1 | 0 |
+ And the following "groups" exist:
+ | name | course | idnumber |
+ | Group 1 | C1 | G1 |
+ | Group 2 | C1 | G2 |
+ | Group 3 | C1 | G3 |
+ | Group 4 | C1 | G4 |
+ | Group 5 | C1 | G5 |
+ And the following "course enrolments" exist:
+ | user | course | role |
+ | teacher1 | C1 | editingteacher |
+ | student1 | C1 | student |
+ | student2 | C1 | student |
+ | student3 | C1 | student |
+ | student4 | C1 | student |
+ | student5 | C1 | student |
+ | student6 | C1 | student |
+ And the following "group members" exist:
+ | user | group |
+ | student1 | G1 |
+ | student2 | G1 |
+ | student3 | G2 |
+ | student4 | G2 |
+ | student5 | G3 |
+ | student6 | G3 |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I navigate to "Grades" node in "Course administration"
+ And I navigate to "Scales" node in "Grade administration"
+ And I press "Add a new scale"
+ And I set the following fields to these values:
+ | Name | My Scale |
+ | Scale | Disappointing, Not good enough, Average, Good, Very good, Excellent! |
+ And I press "Save changes"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add a "Assignment" to section "1" and I fill the form with:
+ | Assignment name | Test assignment |
+ | Description | Offline text |
+ | assignsubmission_file_enabled | 0 |
+ | id_modgrade_type | Scale |
+ | id_modgrade_scale | My Scale |
+ | Group mode | Separate groups |
+ And I follow "Course 1"
+ And I navigate to "Grades" node in "Course administration"
+ And I turn editing mode on
+ And I give the grade "Excellent!" to the user "Student 1" for the grade item "Test assignment"
+ And I give the grade "Very good" to the user "Student 2" for the grade item "Test assignment"
+ And I give the grade "Very good" to the user "Student 3" for the grade item "Test assignment"
+ And I give the grade "Good" to the user "Student 4" for the grade item "Test assignment"
+ And I give the grade "Good" to the user "Student 5" for the grade item "Test assignment"
+ And I give the grade "Average" to the user "Student 6" for the grade item "Test assignment"
+ And I press "Save changes"
+ And I follow "Course 1"
+
+ Scenario: Try to configure the block on the course page to show 1 high score
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 1 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display full names |
+ | id_config_usegroups | Yes |
+ And I press "Save changes"
+ Then I should see "Group 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I should see "Student 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using full names
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display full names |
+ | id_config_usegroups | Yes |
+ And I press "Save changes"
+ Then I should see "Group 1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "Group 2" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "Group 3" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+ And I log out
+ And I log in as "student3"
+ And I follow "Course 1"
+ And I should see "Student 3" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "Student 4" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Display only ID numbers |
+ | id_config_usegroups | Yes |
+ And I press "Save changes"
+ Then I should see "Group" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I should see "User S1" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "User S2" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+
+ Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
+ Given I add the "Activity results" block
+ When I configure the "Activity results" block
+ And I set the following fields to these values:
+ | id_config_showbest | 3 |
+ | id_config_showworst | 0 |
+ | id_config_nameformat | Anonymous results |
+ | id_config_usegroups | Yes |
+ And I press "Save changes"
+ Then I should see "Group" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
+ And I should see "Good" in the "Activity results" "block"
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I should see "User" in the "Activity results" "block"
+ And I should see "Excellent!" in the "Activity results" "block"
+ And I should see "Very good" in the "Activity results" "block"
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
-
- @javascript
- Scenario: Configure the block on the course page to show 1 high score
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+ And the following "group members" exist:
+ | user | group |
+ | student1 | G1 |
+ | student2 | G1 |
+ | student3 | G2 |
+ | student4 | G2 |
+ | student5 | G3 |
+ | student6 | G3 |
+ And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
And I press "Save changes"
And I follow "Course 1"
- And I add the "Activity results" block
+
+ Scenario: Configure the block on the course page to show 1 high score
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 1 |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show 1 high score as a fraction
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 1 |
And I should see "Student 1" in the "Activity results" "block"
And I should see "100.00/100.00" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show 1 high score as a absolute numbers
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 1 |
And I should see "Student 1" in the "Activity results" "block"
And I should see "100.00" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show multiple high scores as percentages
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 3 |
And I should see "Student 2" in the "Activity results" "block"
And I should see "90%" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show multiple high scores as fractions
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 3 |
And I should see "Student 4" in the "Activity results" "block"
And I should see "80.00/100.00" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show multiple high scores as absolute numbers
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 3 |
And I should see "Student 2" in the "Activity results" "block"
And I should see "90.00" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show multiple high scores using ID numbers
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 3 |
And I should see "User S2" in the "Activity results" "block"
And I should see "90.00%" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show multiple high scores using anonymous names
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Separate groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment"
- And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
- And I press "Save changes"
- And I follow "Course 1"
- And I add the "Activity results" block
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 3 |
| student4 | C1 | student |
| student5 | C1 | student |
| student6 | C1 | student |
-
- @javascript
- Scenario: Configure the block on the course page to show 1 high score
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
+ And the following "group members" exist:
+ | user | group |
+ | student1 | G1 |
+ | student2 | G1 |
+ | student3 | G2 |
+ | student4 | G2 |
+ | student5 | G3 |
+ | student6 | G3 |
+ And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
And I give the grade "70.00" to the user "Student 6" for the grade item "Test assignment"
And I press "Save changes"
And I follow "Course 1"
- And I add the "Activity results" block
+
+ Scenario: Configure the block on the course page to show 1 high score
+ Given I add the "Activity results" block
When I configure the "Activity results" block
And I set the following fields to these values:
| id_config_showbest | 1 |
Then I should see "Group 1" in the "Activity results" "block"
And I should see "95%" in the "Activity results" "block"
- @javascript
Scenario: Try to configure the block on the course page to show 1 high score as a fraction
- Given I log in as "teacher1"
- And I follow "Course 1"
- And I expand "Users" node
- And I follow "Groups"
- And I add "Student 1 (student1@example.com)" user to "Group 1" group members
- And I add "Student 2 (student2@example.com)" user to "Group 1" group members
- And I add "Student 3 (student3@example.com)" user to "Group 2" group members
- And I add "Student 4 (student4@example.com)" user to "Group 2" group members
- And I add "Student 5 (student5@example.com)" user to "Group 3" group members
- And I add "Student 6 (student6@example.com)" user to "Group 3" group members
- And I follow "Course 1"
- And I turn editing mode on
- And I add a "Assignment" to section "1" and I fill the form with:
- | Assignment name | Test assignment |
- | Description | Offline text |
- | assignsubmission_file_enabled | 0 |
- | Group mode | Visible groups |
- And I follow "Course 1"
- And I navigate to "Grades" node in "Course administration"
- And I turn editing mode on
- And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 2" for the grade item "Test assignment"
- And I give the grade "90.00" to the user "Student 3" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 4" for the grade item "Test assignment"
- And I give the grade "80.00" to the user "Student 5" for the grade item "Test assignment&qu