2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * External database enrolment sync tests, this also tests adodb drivers
19 * that are matching our four supported Moodle database drivers.
21 * @package enrol_database
23 * @copyright 2011 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') ||
die();
29 class enrol_database_testcase
extends advanced_testcase
{
30 protected static $courses = array();
31 protected static $users = array();
32 protected static $roles = array();
34 /** @var string Original error log */
37 protected function init_enrol_database() {
40 // Discard error logs from AdoDB.
41 $this->oldlog
= ini_get('error_log');
42 ini_set('error_log', "$CFG->dataroot/testlog.log");
44 $dbman = $DB->get_manager();
46 set_config('dbencoding', 'utf-8', 'enrol_database');
48 set_config('dbhost', $CFG->dbhost
, 'enrol_database');
49 set_config('dbuser', $CFG->dbuser
, 'enrol_database');
50 set_config('dbpass', $CFG->dbpass
, 'enrol_database');
51 set_config('dbname', $CFG->dbname
, 'enrol_database');
53 if (!empty($CFG->dboptions
['dbport'])) {
54 set_config('dbhost', $CFG->dbhost
.':'.$CFG->dboptions
['dbport'], 'enrol_database');
57 switch ($DB->get_dbfamily()) {
60 set_config('dbtype', 'mysqli', 'enrol_database');
61 set_config('dbsetupsql', "SET NAMES 'UTF-8'", 'enrol_database');
62 set_config('dbsybasequoting', '0', 'enrol_database');
63 if (!empty($CFG->dboptions
['dbsocket'])) {
64 $dbsocket = $CFG->dboptions
['dbsocket'];
65 if ((strpos($dbsocket, '/') === false and strpos($dbsocket, '\\') === false)) {
66 $dbsocket = ini_get('mysqli.default_socket');
68 set_config('dbtype', 'mysqli://'.rawurlencode($CFG->dbuser
).':'.rawurlencode($CFG->dbpass
).'@'.rawurlencode($CFG->dbhost
).'/'.rawurlencode($CFG->dbname
).'?socket='.rawurlencode($dbsocket), 'enrol_database');
73 set_config('dbtype', 'oci8po', 'enrol_database');
74 set_config('dbsybasequoting', '1', 'enrol_database');
78 set_config('dbtype', 'postgres7', 'enrol_database');
79 $setupsql = "SET NAMES 'UTF-8'";
80 if (!empty($CFG->dboptions
['dbschema'])) {
81 $setupsql .= "; SET search_path = '".$CFG->dboptions
['dbschema']."'";
83 set_config('dbsetupsql', $setupsql, 'enrol_database');
84 set_config('dbsybasequoting', '0', 'enrol_database');
85 if (!empty($CFG->dboptions
['dbsocket']) and ($CFG->dbhost
=== 'localhost' or $CFG->dbhost
=== '127.0.0.1')) {
86 if (strpos($CFG->dboptions
['dbsocket'], '/') !== false) {
87 $socket = $CFG->dboptions
['dbsocket'];
88 if (!empty($CFG->dboptions
['dbport'])) {
89 $socket .= ':' . $CFG->dboptions
['dbport'];
91 set_config('dbhost', $socket, 'enrol_database');
93 set_config('dbhost', '', 'enrol_database');
99 if (get_class($DB) == 'mssql_native_moodle_database') {
100 set_config('dbtype', 'mssql_n', 'enrol_database');
102 set_config('dbtype', 'mssqlnative', 'enrol_database');
104 set_config('dbsybasequoting', '1', 'enrol_database');
108 throw new exception('Unknown database driver '.get_class($DB));
111 // NOTE: It is stongly discouraged to create new tables in advanced_testcase classes,
112 // but there is no other simple way to test ext database enrol sync, so let's
113 // disable transactions are try to cleanup after the tests.
115 $table = new xmldb_table('enrol_database_test_enrols');
116 $table->add_field('id', XMLDB_TYPE_INTEGER
, '10', null, XMLDB_NOTNULL
, XMLDB_SEQUENCE
, null);
117 $table->add_field('courseid', XMLDB_TYPE_CHAR
, '255', null, null, null);
118 $table->add_field('userid', XMLDB_TYPE_CHAR
, '255', null, null, null);
119 $table->add_field('roleid', XMLDB_TYPE_CHAR
, '255', null, null, null);
120 $table->add_field('otheruser', XMLDB_TYPE_CHAR
, '1', null, XMLDB_NOTNULL
, null, '0');
121 $table->add_key('primary', XMLDB_KEY_PRIMARY
, array('id'));
122 if ($dbman->table_exists($table)) {
123 $dbman->drop_table($table);
125 $dbman->create_table($table);
126 set_config('remoteenroltable', $CFG->prefix
.'enrol_database_test_enrols', 'enrol_database');
127 set_config('remotecoursefield', 'courseid', 'enrol_database');
128 set_config('remoteuserfield', 'userid', 'enrol_database');
129 set_config('remoterolefield', 'roleid', 'enrol_database');
130 set_config('remoteotheruserfield', 'otheruser', 'enrol_database');
132 $table = new xmldb_table('enrol_database_test_courses');
133 $table->add_field('id', XMLDB_TYPE_INTEGER
, '10', null, XMLDB_NOTNULL
, XMLDB_SEQUENCE
, null);
134 $table->add_field('fullname', XMLDB_TYPE_CHAR
, '255', null, null, null);
135 $table->add_field('shortname', XMLDB_TYPE_CHAR
, '255', null, null, null);
136 $table->add_field('idnumber', XMLDB_TYPE_CHAR
, '255', null, null, null);
137 $table->add_field('category', XMLDB_TYPE_CHAR
, '255', null, null, null);
138 $table->add_key('primary', XMLDB_KEY_PRIMARY
, array('id'));
139 if ($dbman->table_exists($table)) {
140 $dbman->drop_table($table);
142 $dbman->create_table($table);
143 set_config('newcoursetable', $CFG->prefix
.'enrol_database_test_courses', 'enrol_database');
144 set_config('newcoursefullname', 'fullname', 'enrol_database');
145 set_config('newcourseshortname', 'shortname', 'enrol_database');
146 set_config('newcourseidnumber', 'idnumber', 'enrol_database');
147 set_config('newcoursecategory', 'category', 'enrol_database');
149 // Create some test users and courses.
150 for ($i = 1; $i <= 4; $i++
) {
151 self
::$courses[$i] = $this->getDataGenerator()->create_course(array('fullname' => 'Test course '.$i, 'shortname' => 'tc'.$i, 'idnumber' => 'courseid'.$i));
154 for ($i = 1; $i <= 10; $i++
) {
155 self
::$users[$i] = $this->getDataGenerator()->create_user(array('username' => 'username'.$i, 'idnumber' => 'userid'.$i, 'email' => 'user'.$i.'@example.com'));
158 foreach (get_all_roles() as $role) {
159 self
::$roles[$role->shortname
] = $role;
163 protected function cleanup_enrol_database() {
166 $dbman = $DB->get_manager();
167 $table = new xmldb_table('enrol_database_test_enrols');
168 $dbman->drop_table($table);
169 $table = new xmldb_table('enrol_database_test_courses');
170 $dbman->drop_table($table);
172 self
::$courses = null;
176 ini_set('error_log', $this->oldlog
);
179 protected function reset_enrol_database() {
182 $DB->delete_records('enrol_database_test_enrols', array());
183 $DB->delete_records('enrol_database_test_courses', array());
185 $plugin = enrol_get_plugin('database');
186 $instances = $DB->get_records('enrol', array('enrol' => 'database'));
187 foreach($instances as $instance) {
188 $plugin->delete_instance($instance);
192 protected function assertIsEnrolled($userindex, $courseindex, $status=null, $rolename = null) {
194 $dbinstance = $DB->get_record('enrol', array('courseid' => self
::$courses[$courseindex]->id
, 'enrol' => 'database'), '*', MUST_EXIST
);
196 $conditions = array('enrolid' => $dbinstance->id
, 'userid' => self
::$users[$userindex]->id
);
197 if ($status !== null) {
198 $conditions['status'] = $status;
200 $this->assertTrue($DB->record_exists('user_enrolments', $conditions));
202 $this->assertHasRoleAssignment($userindex, $courseindex, $rolename);
205 protected function assertHasRoleAssignment($userindex, $courseindex, $rolename = null) {
207 $dbinstance = $DB->get_record('enrol', array('courseid' => self
::$courses[$courseindex]->id
, 'enrol' => 'database'), '*', MUST_EXIST
);
209 $coursecontext = context_course
::instance(self
::$courses[$courseindex]->id
);
210 if ($rolename === false) {
211 $this->assertFalse($DB->record_exists('role_assignments', array('component' => 'enrol_database', 'itemid' => $dbinstance->id
, 'userid' => self
::$users[$userindex]->id
, 'contextid' => $coursecontext->id
)));
212 } else if ($rolename !== null) {
213 $this->assertTrue($DB->record_exists('role_assignments', array('component' => 'enrol_database', 'itemid' => $dbinstance->id
, 'userid' => self
::$users[$userindex]->id
, 'contextid' => $coursecontext->id
, 'roleid' => self
::$roles[$rolename]->id
)));
217 protected function assertIsNotEnrolled($userindex, $courseindex) {
219 if (!$dbinstance = $DB->get_record('enrol', array('courseid' => self
::$courses[$courseindex]->id
, 'enrol' => 'database'))) {
222 $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid' => $dbinstance->id
, 'userid' => self
::$users[$userindex]->id
)));
225 public function test_sync_user_enrolments() {
228 $this->init_enrol_database();
230 $this->resetAfterTest(false);
231 $this->preventResetByRollback();
233 $plugin = enrol_get_plugin('database');
235 // Test basic enrol sync for one user after login.
237 $this->reset_enrol_database();
238 $plugin->set_config('localcoursefield', 'idnumber');
239 $plugin->set_config('localuserfield', 'idnumber');
240 $plugin->set_config('localrolefield', 'shortname');
242 $plugin->set_config('defaultrole', self
::$roles['student']->id
);
244 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
245 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid2', 'roleid' => 'teacher'));
246 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid2', 'courseid' => 'courseid1', 'roleid' => null));
247 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid4', 'courseid' => 'courseid4', 'roleid' => 'editingteacher', 'otheruser' => '1'));
248 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'xxxxxxx', 'courseid' => 'courseid1', 'roleid' => 'student')); // Bogus record to be ignored.
249 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'xxxxxxxxx', 'roleid' => 'student')); // Bogus record to be ignored.
251 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
252 $this->assertEquals(0, $DB->count_records('enrol', array('enrol' => 'database')));
253 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
255 $plugin->sync_user_enrolments(self
::$users[1]);
256 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
257 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
258 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
259 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
260 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
262 // Make sure there are no errors or changes on the next login.
264 $plugin->sync_user_enrolments(self
::$users[1]);
265 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
266 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
267 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
268 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
269 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
271 $plugin->sync_user_enrolments(self
::$users[2]);
272 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
273 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
274 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
275 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
276 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
277 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
279 $plugin->sync_user_enrolments(self
::$users[4]);
280 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
281 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
282 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
283 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
284 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
285 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
286 $this->assertIsNotEnrolled(4, 4);
287 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
289 // Enrolment removals.
291 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
292 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP
);
293 $plugin->sync_user_enrolments(self
::$users[1]);
294 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
295 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
296 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
297 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
298 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
301 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND
);
302 $plugin->sync_user_enrolments(self
::$users[1]);
303 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
304 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
305 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
306 $this->assertIsEnrolled(1, 1, ENROL_USER_SUSPENDED
, 'student');
307 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
309 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
310 $plugin->sync_user_enrolments(self
::$users[1]);
311 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
312 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
313 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
314 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
315 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
318 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
319 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES
);
320 $plugin->sync_user_enrolments(self
::$users[1]);
321 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
322 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
323 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
324 $this->assertIsEnrolled(1, 1, ENROL_USER_SUSPENDED
, false);
325 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
327 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
328 $plugin->sync_user_enrolments(self
::$users[1]);
329 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
330 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
331 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
332 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
333 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
336 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
337 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL
);
338 $plugin->sync_user_enrolments(self
::$users[1]);
339 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
340 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
341 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
342 $this->assertIsNotEnrolled(1, 1);
343 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
345 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid4', 'courseid' => 'courseid4', 'roleid' => 'editingteacher'));
346 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES
);
347 $plugin->sync_user_enrolments(self
::$users[4]);
348 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
349 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
350 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
351 $this->assertIsNotEnrolled(4, 4);
352 $this->assertHasRoleAssignment(4, 4, false);
354 // Test all other mapping options.
356 $this->reset_enrol_database();
358 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
359 $this->assertEquals(0, $DB->count_records('enrol', array('enrol' => 'database')));
360 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
362 $plugin->set_config('localcoursefield', 'id');
363 $plugin->set_config('localuserfield', 'id');
364 $plugin->set_config('localrolefield', 'id');
366 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->id
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
367 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->id
, 'courseid' => self
::$courses[2]->id
, 'roleid' => self
::$roles['teacher']->id
));
368 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->id
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
370 $plugin->sync_user_enrolments(self
::$users[1]);
371 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
372 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
373 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
374 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
375 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
378 $this->reset_enrol_database();
379 $plugin->set_config('localcoursefield', 'shortname');
380 $plugin->set_config('localuserfield', 'email');
381 $plugin->set_config('localrolefield', 'id');
383 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->email
, 'courseid' => self
::$courses[1]->shortname
, 'roleid' => self
::$roles['student']->id
));
384 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->email
, 'courseid' => self
::$courses[2]->shortname
, 'roleid' => self
::$roles['teacher']->id
));
385 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->email
, 'courseid' => self
::$courses[1]->shortname
, 'roleid' => self
::$roles['student']->id
));
387 $plugin->sync_user_enrolments(self
::$users[1]);
388 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
389 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
390 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
391 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
392 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
395 $this->reset_enrol_database();
396 $plugin->set_config('localcoursefield', 'id');
397 $plugin->set_config('localuserfield', 'username');
398 $plugin->set_config('localrolefield', 'id');
400 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
401 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[2]->id
, 'roleid' => self
::$roles['teacher']->id
));
402 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
404 $plugin->sync_user_enrolments(self
::$users[1]);
405 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
406 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
407 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
408 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
409 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
413 * @depends test_sync_user_enrolments
415 public function test_sync_users() {
418 $this->resetAfterTest(false);
419 $this->preventResetByRollback();
420 $this->reset_enrol_database();
422 $plugin = enrol_get_plugin('database');
424 $trace = new null_progress_trace();
426 // Test basic enrol sync for one user after login.
428 $this->reset_enrol_database();
429 $plugin->set_config('localcoursefield', 'idnumber');
430 $plugin->set_config('localuserfield', 'idnumber');
431 $plugin->set_config('localrolefield', 'shortname');
433 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
434 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid2', 'roleid' => 'editingteacher'));
435 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid2', 'courseid' => 'courseid1', 'roleid' => 'student'));
436 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid4', 'courseid' => 'courseid4', 'roleid' => 'editingteacher', 'otheruser' => '1'));
437 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'xxxxxxx', 'courseid' => 'courseid1', 'roleid' => 'student')); // Bogus record to be ignored.
438 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'xxxxxxxxx', 'roleid' => 'student')); // Bogus record to be ignored.
439 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
440 $this->assertEquals(0, $DB->count_records('enrol', array('enrol' => 'database')));
441 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
443 $plugin->sync_enrolments($trace);
444 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
445 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
446 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
447 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
448 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
449 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
450 $this->assertIsNotEnrolled(4, 4);
451 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
453 $plugin->set_config('defaultrole', self
::$roles['teacher']->id
);
454 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid3', 'courseid' => 'courseid3'));
455 $plugin->sync_enrolments($trace);
456 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
457 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
458 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
459 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
460 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
461 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
462 $this->assertIsNotEnrolled(4, 4);
463 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
464 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
467 // Test different unenrolment options.
469 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
470 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP
);
471 $plugin->sync_enrolments($trace);
472 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
473 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
474 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
475 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
476 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
477 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
478 $this->assertIsNotEnrolled(4, 4);
479 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
480 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
483 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND
);
484 $plugin->sync_enrolments($trace);
485 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
486 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
487 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
488 $this->assertIsEnrolled(1, 1, ENROL_USER_SUSPENDED
, 'student');
489 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
490 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
491 $this->assertIsNotEnrolled(4, 4);
492 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
493 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
495 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
496 $plugin->sync_enrolments($trace);
497 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
498 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
499 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
500 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
501 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
502 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
503 $this->assertIsNotEnrolled(4, 4);
504 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
505 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
508 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
509 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES
);
510 $plugin->sync_enrolments($trace);
511 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
512 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
513 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
514 $this->assertIsEnrolled(1, 1, ENROL_USER_SUSPENDED
, false);
515 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
516 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
517 $this->assertIsNotEnrolled(4, 4);
518 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
519 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
521 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
522 $plugin->sync_enrolments($trace);
523 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
524 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
525 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
526 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
527 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
528 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
529 $this->assertIsNotEnrolled(4, 4);
530 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
531 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
534 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
535 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL
);
536 $plugin->sync_enrolments($trace);
537 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
538 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
539 $this->assertEquals(4, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
540 $this->assertIsNotEnrolled(1, 1);
541 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
542 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
543 $this->assertIsNotEnrolled(4, 4);
544 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
545 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
547 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'student'));
548 $DB->insert_record('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'teacher'));
549 $plugin->sync_enrolments($trace);
550 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
551 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
552 $this->assertEquals(6, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
553 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
554 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'teacher');
555 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
556 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
557 $this->assertIsNotEnrolled(4, 4);
558 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
559 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
561 $DB->delete_records('enrol_database_test_enrols', array('userid' => 'userid1', 'courseid' => 'courseid1', 'roleid' => 'teacher'));
562 $plugin->sync_enrolments($trace);
563 $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
564 $this->assertEquals(4, $DB->count_records('enrol', array('enrol' => 'database')));
565 $this->assertEquals(5, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
566 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
567 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'editingteacher');
568 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
569 $this->assertIsNotEnrolled(4, 4);
570 $this->assertHasRoleAssignment(4, 4, 'editingteacher');
571 $this->assertIsEnrolled(3, 3, ENROL_USER_ACTIVE
, 'teacher');
574 // Test all other mapping options.
576 $this->reset_enrol_database();
578 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
579 $this->assertEquals(0, $DB->count_records('enrol', array('enrol' => 'database')));
580 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
582 $plugin->set_config('localcoursefield', 'id');
583 $plugin->set_config('localuserfield', 'id');
584 $plugin->set_config('localrolefield', 'id');
586 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->id
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
587 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->id
, 'courseid' => self
::$courses[2]->id
, 'roleid' => self
::$roles['teacher']->id
));
588 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->id
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
590 $plugin->sync_enrolments($trace);
591 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
592 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
593 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
594 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
595 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
596 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
599 $this->reset_enrol_database();
600 $plugin->set_config('localcoursefield', 'shortname');
601 $plugin->set_config('localuserfield', 'email');
602 $plugin->set_config('localrolefield', 'id');
604 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->email
, 'courseid' => self
::$courses[1]->shortname
, 'roleid' => self
::$roles['student']->id
));
605 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->email
, 'courseid' => self
::$courses[2]->shortname
, 'roleid' => self
::$roles['teacher']->id
));
606 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->email
, 'courseid' => self
::$courses[1]->shortname
, 'roleid' => self
::$roles['student']->id
));
608 $plugin->sync_enrolments($trace);
609 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
610 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
611 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
612 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
613 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
614 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
617 $this->reset_enrol_database();
618 $plugin->set_config('localcoursefield', 'id');
619 $plugin->set_config('localuserfield', 'username');
620 $plugin->set_config('localrolefield', 'id');
622 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
623 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[2]->id
, 'roleid' => self
::$roles['teacher']->id
));
624 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
626 $plugin->sync_enrolments($trace);
627 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
628 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
629 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
630 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
631 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
632 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
635 // Test sync of one course only.
637 $this->reset_enrol_database();
639 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
640 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[1]->username
, 'courseid' => self
::$courses[2]->id
, 'roleid' => self
::$roles['teacher']->id
));
641 $DB->insert_record('enrol_database_test_enrols', array('userid' => self
::$users[2]->username
, 'courseid' => self
::$courses[1]->id
, 'roleid' => self
::$roles['student']->id
));
643 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
644 $this->assertEquals(0, $DB->count_records('enrol', array('enrol' => 'database')));
645 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
647 $plugin->sync_enrolments($trace, self
::$courses[3]->id
);
648 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
649 $this->assertEquals(1, $DB->count_records('enrol', array('enrol' => 'database')));
650 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
652 $plugin->sync_enrolments($trace, self
::$courses[1]->id
);
653 $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
654 $this->assertEquals(2, $DB->count_records('enrol', array('enrol' => 'database')));
655 $this->assertEquals(2, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
656 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
657 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
659 $plugin->sync_enrolments($trace, self
::$courses[2]->id
);
660 $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
661 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
662 $this->assertEquals(3, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
663 $this->assertIsEnrolled(1, 1, ENROL_USER_ACTIVE
, 'student');
664 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
665 $this->assertIsEnrolled(2, 1, ENROL_USER_ACTIVE
, 'student');
668 $plugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL
);
670 $DB->delete_records('enrol_database_test_enrols', array());
672 $plugin->sync_enrolments($trace, self
::$courses[1]->id
);
673 $this->assertEquals(1, $DB->count_records('user_enrolments', array()));
674 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
675 $this->assertEquals(1, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
676 $this->assertIsEnrolled(1, 2, ENROL_USER_ACTIVE
, 'teacher');
678 $plugin->sync_enrolments($trace, self
::$courses[2]->id
);
679 $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
680 $this->assertEquals(3, $DB->count_records('enrol', array('enrol' => 'database')));
681 $this->assertEquals(0, $DB->count_records('role_assignments', array('component' => 'enrol_database')));
685 * @depends test_sync_users
687 public function test_sync_courses() {
690 $this->resetAfterTest(true);
691 $this->preventResetByRollback();
692 $this->reset_enrol_database();
694 $plugin = enrol_get_plugin('database');
696 $trace = new null_progress_trace();
698 $plugin->set_config('localcategoryfield', 'id');
699 $coursecat = $this->getDataGenerator()->create_category(array('name' => 'Test category 1', 'idnumber' => 'tcid1'));
700 $defcat = $DB->get_record('course_categories', array('id' => $plugin->get_config('defaultcategory')));
702 $course1 = array('fullname' => 'New course 1', 'shortname' => 'nc1', 'idnumber' => 'ncid1', 'category' => $coursecat->id
);
703 $course2 = array('fullname' => 'New course 2', 'shortname' => 'nc2', 'idnumber' => 'ncid2', 'category' => null);
704 // Duplicate records are to be ignored.
705 $course3 = array('fullname' => 'New course 3', 'shortname' => 'xx', 'idnumber' => 'yy2', 'category' => $defcat->id
);
706 $course4 = array('fullname' => 'New course 4', 'shortname' => 'xx', 'idnumber' => 'yy3', 'category' => $defcat->id
);
707 $course5 = array('fullname' => 'New course 5', 'shortname' => 'xx1', 'idnumber' => 'yy', 'category' => $defcat->id
);
708 $course6 = array('fullname' => 'New course 6', 'shortname' => 'xx2', 'idnumber' => 'yy', 'category' => $defcat->id
);
710 $DB->insert_record('enrol_database_test_courses', $course1);
711 $DB->insert_record('enrol_database_test_courses', $course2);
712 $DB->insert_record('enrol_database_test_courses', $course3);
713 $DB->insert_record('enrol_database_test_courses', $course4);
714 $DB->insert_record('enrol_database_test_courses', $course5);
715 $DB->insert_record('enrol_database_test_courses', $course6);
717 $this->assertEquals(1+
count(self
::$courses), $DB->count_records('course'));
719 $plugin->sync_courses($trace);
721 $this->assertEquals(4+
1+
count(self
::$courses), $DB->count_records('course'));
723 $this->assertTrue($DB->record_exists('course', $course1));
724 $course2['category'] = $defcat->id
;
725 $this->assertTrue($DB->record_exists('course', $course2));
728 // People should NOT push duplicates there because the results are UNDEFINED! But anyway skip the duplicates.
730 $this->assertEquals(1, $DB->count_records('course', array('idnumber' => 'yy')));
731 $this->assertEquals(1, $DB->count_records('course', array('shortname' => 'xx')));
734 // Test category mapping via idnumber.
736 $plugin->set_config('localcategoryfield', 'idnumber');
737 $course7 = array('fullname' => 'New course 7', 'shortname' => 'nc7', 'idnumber' => 'ncid7', 'category' => 'tcid1');
738 $DB->insert_record('enrol_database_test_courses', $course7);
739 $plugin->sync_courses($trace);
741 $this->assertEquals(1+
4+
1+
count(self
::$courses), $DB->count_records('course'));
742 $this->assertTrue($DB->record_exists('course', $course1));
743 $this->assertTrue($DB->record_exists('course', $course2));
744 $course7['category'] = $coursecat->id
;
745 $this->assertTrue($DB->record_exists('course', $course7));
748 // Test course template.
750 $template = $this->getDataGenerator()->create_course(array('numsections' => 666, 'shortname' => 'crstempl'));
751 $plugin->set_config('templatecourse', 'crstempl');
753 $course8 = array('fullname' => 'New course 8', 'shortname' => 'nc8', 'idnumber' => 'ncid8', 'category' => null);
754 $DB->insert_record('enrol_database_test_courses', $course8);
755 $plugin->sync_courses($trace);
757 $this->assertEquals(2+
1+
4+
1+
count(self
::$courses), $DB->count_records('course'));
758 $course8['category'] = $defcat->id
;
759 $record = $DB->get_record('course', $course8);
760 $this->assertFalse(empty($record));
761 $courseformatoptions = course_get_format($record)->get_format_options();
762 $this->assertEquals($courseformatoptions['numsections'], 666);
764 // Test invalid category.
766 $course9 = array('fullname' => 'New course 9', 'shortname' => 'nc9', 'idnumber' => 'ncid9', 'category' => 'xxxxxxx');
767 $DB->insert_record('enrol_database_test_courses', $course9);
768 $plugin->sync_courses($trace);
769 $this->assertEquals(2+
1+
4+
1+
count(self
::$courses), $DB->count_records('course'));
770 $this->assertFalse($DB->record_exists('course', array('idnumber' => 'ncid9')));
773 // Test when categories not specified.
775 $plugin->set_config('newcoursecategory', '');
776 $plugin->sync_courses($trace);
777 $this->assertEquals(1+
2+
1+
4+
1+
count(self
::$courses), $DB->count_records('course'));
778 $this->assertTrue($DB->record_exists('course', array('idnumber' => 'ncid9')));
781 // Final cleanup - remove extra tables, fixtures and caches.
782 $this->cleanup_enrol_database();