Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   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.
   8  //
   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.
  13  //
  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/>.
  16  
  17  /**
  18   * LDAP enrolment plugin tests.
  19   *
  20   * NOTE: in order to execute this test you need to set up
  21   *       OpenLDAP server with core, cosine, nis and internet schemas
  22   *       and add configuration constants to config.php or phpunit.xml configuration file:
  23   *
  24   * define('TEST_ENROL_LDAP_HOST_URL', 'ldap://127.0.0.1');
  25   * define('TEST_ENROL_LDAP_BIND_DN', 'cn=someuser,dc=example,dc=local');
  26   * define('TEST_ENROL_LDAP_BIND_PW', 'somepassword');
  27   * define('TEST_ENROL_LDAP_DOMAIN', 'dc=example,dc=local');
  28   *
  29   * @package    enrol_ldap
  30   * @category   phpunit
  31   * @copyright  2013 Petr Skoda {@link http://skodak.org}
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  
  35  defined('MOODLE_INTERNAL') || die();
  36  
  37  global $CFG;
  38  
  39  
  40  class enrol_ldap_testcase extends advanced_testcase {
  41  
  42      /**
  43       * Data provider for enrol_ldap tests
  44       *
  45       * Used to ensure that all the paged stuff works properly, irrespectively
  46       * of the pagesize configured (that implies all the chunking and paging
  47       * built in the plugis is doing its work consistently). Both searching and
  48       * not searching within subcontexts.
  49       *
  50       * @return array[]
  51       */
  52      public function enrol_ldap_provider() {
  53          $pagesizes = [1, 3, 5, 1000];
  54          $subcontexts = [0, 1];
  55          $combinations = [];
  56          foreach ($pagesizes as $pagesize) {
  57              foreach ($subcontexts as $subcontext) {
  58                  $combinations["pagesize {$pagesize}, subcontexts {$subcontext}"] = [$pagesize, $subcontext];
  59              }
  60          }
  61          return $combinations;
  62      }
  63  
  64      /**
  65       * General enrol_ldap testcase
  66       *
  67       * @dataProvider enrol_ldap_provider
  68       * @param int $pagesize Value to be configured in settings controlling page size.
  69       * @param int $subcontext Value to be configured in settings controlling searching in subcontexts.
  70       */
  71      public function test_enrol_ldap(int $pagesize, int $subcontext) {
  72          global $CFG, $DB;
  73  
  74          if (!extension_loaded('ldap')) {
  75              $this->markTestSkipped('LDAP extension is not loaded.');
  76          }
  77  
  78          $this->resetAfterTest();
  79  
  80          require_once($CFG->dirroot.'/enrol/ldap/lib.php');
  81          require_once($CFG->libdir.'/ldaplib.php');
  82  
  83          if (!defined('TEST_ENROL_LDAP_HOST_URL') or !defined('TEST_ENROL_LDAP_BIND_DN') or !defined('TEST_ENROL_LDAP_BIND_PW') or !defined('TEST_ENROL_LDAP_DOMAIN')) {
  84              $this->markTestSkipped('External LDAP test server not configured.');
  85          }
  86  
  87          // Make sure we can connect the server.
  88          $debuginfo = '';
  89          if (!$connection = ldap_connect_moodle(TEST_ENROL_LDAP_HOST_URL, 3, 'rfc2307', TEST_ENROL_LDAP_BIND_DN, TEST_ENROL_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
  90              $this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
  91          }
  92  
  93          $this->enable_plugin();
  94  
  95          // Create new empty test container.
  96          $topdn = 'dc=moodletest,'.TEST_ENROL_LDAP_DOMAIN;
  97  
  98          $this->recursive_delete($connection, TEST_ENROL_LDAP_DOMAIN, 'dc=moodletest');
  99  
 100          $o = array();
 101          $o['objectClass'] = array('dcObject', 'organizationalUnit');
 102          $o['dc']         = 'moodletest';
 103          $o['ou']         = 'MOODLETEST';
 104          if (!ldap_add($connection, 'dc=moodletest,'.TEST_ENROL_LDAP_DOMAIN, $o)) {
 105              $this->markTestSkipped('Can not create test LDAP container.');
 106          }
 107  
 108          // Configure enrol plugin.
 109          /** @var enrol_ldap_plugin $enrol */
 110          $enrol = enrol_get_plugin('ldap');
 111          $enrol->set_config('host_url', TEST_ENROL_LDAP_HOST_URL);
 112          $enrol->set_config('start_tls', 0);
 113          $enrol->set_config('ldap_version', 3);
 114          $enrol->set_config('ldapencoding', 'utf-8');
 115          $enrol->set_config('pagesize', $pagesize);
 116          $enrol->set_config('bind_dn', TEST_ENROL_LDAP_BIND_DN);
 117          $enrol->set_config('bind_pw', TEST_ENROL_LDAP_BIND_PW);
 118          $enrol->set_config('course_search_sub', $subcontext);
 119          $enrol->set_config('memberattribute_isdn', 0);
 120          $enrol->set_config('user_contexts', '');
 121          $enrol->set_config('user_search_sub', 0);
 122          $enrol->set_config('user_type', 'rfc2307');
 123          $enrol->set_config('opt_deref', LDAP_DEREF_NEVER);
 124          $enrol->set_config('objectclass', '(objectClass=posixGroup)');
 125          $enrol->set_config('course_idnumber', 'cn');
 126          $enrol->set_config('course_shortname', 'cn');
 127          $enrol->set_config('course_fullname', 'cn');
 128          $enrol->set_config('course_summary', '');
 129          $enrol->set_config('ignorehiddencourses', 0);
 130          $enrol->set_config('nested_groups', 0);
 131          $enrol->set_config('autocreate', 0);
 132          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 133  
 134          $roles = get_all_roles();
 135          foreach ($roles as $role) {
 136              $enrol->set_config('contexts_role'.$role->id, '');
 137              $enrol->set_config('memberattribute_role'.$role->id, '');
 138          }
 139  
 140          // Create group for teacher enrolments.
 141          $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
 142          $this->assertNotEmpty($teacherrole);
 143          $o = array();
 144          $o['objectClass'] = array('organizationalUnit');
 145          $o['ou']          = 'teachers';
 146          ldap_add($connection, 'ou=teachers,'.$topdn, $o);
 147          $enrol->set_config('contexts_role'.$teacherrole->id, 'ou=teachers,'.$topdn);
 148          $enrol->set_config('memberattribute_role'.$teacherrole->id, 'memberuid');
 149  
 150          // Create group for student enrolments.
 151          $studentrole = $DB->get_record('role', array('shortname'=>'student'));
 152          $this->assertNotEmpty($studentrole);
 153          $o = array();
 154          $o['objectClass'] = array('organizationalUnit');
 155          $o['ou']          = 'students';
 156          ldap_add($connection, 'ou=students,'.$topdn, $o);
 157          $enrol->set_config('contexts_role'.$studentrole->id, 'ou=students,'.$topdn);
 158          $enrol->set_config('memberattribute_role'.$studentrole->id, 'memberuid');
 159  
 160          // Create some users and courses.
 161          $user1 = $this->getDataGenerator()->create_user(array('idnumber'=>'user1', 'username'=>'user1'));
 162          $user2 = $this->getDataGenerator()->create_user(array('idnumber'=>'user2', 'username'=>'user2'));
 163          $user3 = $this->getDataGenerator()->create_user(array('idnumber'=>'user3', 'username'=>'user3'));
 164          $user4 = $this->getDataGenerator()->create_user(array('idnumber'=>'user4', 'username'=>'user4'));
 165          $user5 = $this->getDataGenerator()->create_user(array('idnumber'=>'user5', 'username'=>'user5'));
 166          $user6 = $this->getDataGenerator()->create_user(array('idnumber'=>'user6', 'username'=>'user6'));
 167  
 168          $course1 = $this->getDataGenerator()->create_course(array('idnumber'=>'course1', 'shortname'=>'course1'));
 169          $course2 = $this->getDataGenerator()->create_course(array('idnumber'=>'course2', 'shortname'=>'course2'));
 170          $course3 = $this->getDataGenerator()->create_course(array('idnumber'=>'course3', 'shortname'=>'course3'));
 171  
 172          // Set up some ldap data.
 173          $o = array();
 174          $o['objectClass'] = array('posixGroup');
 175          $o['cn']          = 'course1';
 176          $o['gidNumber']   = '1';
 177          $o['memberUid']   = array('user1', 'user2', 'user3', 'userx');
 178          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 179          $o = array();
 180          $o['objectClass'] = array('posixGroup');
 181          $o['cn']          = 'course1';
 182          $o['gidNumber']   = '2';
 183          $o['memberUid']   = array('user5');
 184          ldap_add($connection, 'cn='.$o['cn'].',ou=teachers,'.$topdn, $o);
 185  
 186          $o = array();
 187          $o['objectClass'] = array('posixGroup');
 188          $o['cn']          = 'course2';
 189          $o['gidNumber']   = '3';
 190          $o['memberUid']   = array('user1', 'user2', 'user3', 'user4');
 191          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 192  
 193          $o = array();
 194          $o['objectClass'] = array('posixGroup');
 195          $o['cn']          = 'course4';
 196          $o['gidNumber']   = '4';
 197          $o['memberUid']   = array('user1', 'user2');
 198          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 199          $o = array();
 200          $o['objectClass'] = array('posixGroup');
 201          $o['cn']          = 'course4';
 202          $o['gidNumber']   = '5';
 203          $o['memberUid']   = array('user5', 'user6');
 204          ldap_add($connection, 'cn='.$o['cn'].',ou=teachers,'.$topdn, $o);
 205  
 206  
 207          // Test simple test without creation.
 208  
 209          $this->assertEquals(0, $DB->count_records('user_enrolments'));
 210          $this->assertEquals(0, $DB->count_records('role_assignments'));
 211          $this->assertEquals(4, $DB->count_records('course'));
 212  
 213          $enrol->sync_enrolments(new null_progress_trace());
 214  
 215          $this->assertEquals(8, $DB->count_records('user_enrolments'));
 216          $this->assertEquals(8, $DB->count_records('role_assignments'));
 217          $this->assertEquals(4, $DB->count_records('course'));
 218  
 219          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id);
 220          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id);
 221          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id);
 222          $this->assertIsEnrolled($course1->id, $user5->id, $teacherrole->id);
 223  
 224          $this->assertIsEnrolled($course2->id, $user1->id, $studentrole->id);
 225          $this->assertIsEnrolled($course2->id, $user2->id, $studentrole->id);
 226          $this->assertIsEnrolled($course2->id, $user3->id, $studentrole->id);
 227          $this->assertIsEnrolled($course2->id, $user4->id, $studentrole->id);
 228  
 229  
 230          // Test course creation.
 231          $enrol->set_config('autocreate', 1);
 232  
 233          $enrol->sync_enrolments(new null_progress_trace());
 234  
 235          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 236          $this->assertEquals(12, $DB->count_records('role_assignments'));
 237          $this->assertEquals(5, $DB->count_records('course'));
 238  
 239          $course4 = $DB->get_record('course', array('idnumber'=>'course4'), '*', MUST_EXIST);
 240  
 241          $this->assertIsEnrolled($course4->id, $user1->id, $studentrole->id);
 242          $this->assertIsEnrolled($course4->id, $user2->id, $studentrole->id);
 243          $this->assertIsEnrolled($course4->id, $user5->id, $teacherrole->id);
 244          $this->assertIsEnrolled($course4->id, $user6->id, $teacherrole->id);
 245  
 246  
 247          // Test unenrolment.
 248          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 249          $o = array();
 250          $o['objectClass'] = array('posixGroup');
 251          $o['cn']          = 'course1';
 252          $o['gidNumber']   = '1';
 253          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 254  
 255          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 256          $enrol->sync_enrolments(new null_progress_trace());
 257          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 258          $this->assertEquals(12, $DB->count_records('role_assignments'));
 259          $this->assertEquals(5, $DB->count_records('course'));
 260  
 261          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND);
 262          $enrol->sync_enrolments(new null_progress_trace());
 263          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 264          $this->assertEquals(12, $DB->count_records('role_assignments'));
 265          $this->assertEquals(5, $DB->count_records('course'));
 266          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_SUSPENDED);
 267          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_SUSPENDED);
 268          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_SUSPENDED);
 269  
 270          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 271          $o = array();
 272          $o['objectClass'] = array('posixGroup');
 273          $o['cn']          = 'course1';
 274          $o['gidNumber']   = '1';
 275          $o['memberUid']   = array('user1', 'user2', 'user3');
 276          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 277  
 278          $enrol->sync_enrolments(new null_progress_trace());
 279          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 280          $this->assertEquals(12, $DB->count_records('role_assignments'));
 281          $this->assertEquals(5, $DB->count_records('course'));
 282          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 283          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_ACTIVE);
 284          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_ACTIVE);
 285  
 286          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 287          $o = array();
 288          $o['objectClass'] = array('posixGroup');
 289          $o['cn']          = 'course1';
 290          $o['gidNumber']   = '1';
 291          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 292  
 293          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
 294          $enrol->sync_enrolments(new null_progress_trace());
 295          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 296          $this->assertEquals(9, $DB->count_records('role_assignments'));
 297          $this->assertEquals(5, $DB->count_records('course'));
 298          $this->assertIsEnrolled($course1->id, $user1->id, 0, ENROL_USER_SUSPENDED);
 299          $this->assertIsEnrolled($course1->id, $user2->id, 0, ENROL_USER_SUSPENDED);
 300          $this->assertIsEnrolled($course1->id, $user3->id, 0, ENROL_USER_SUSPENDED);
 301  
 302          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 303          $o = array();
 304          $o['objectClass'] = array('posixGroup');
 305          $o['cn']          = 'course1';
 306          $o['gidNumber']   = '1';
 307          $o['memberUid']   = array('user1', 'user2', 'user3');
 308          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 309  
 310          $enrol->sync_enrolments(new null_progress_trace());
 311          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 312          $this->assertEquals(12, $DB->count_records('role_assignments'));
 313          $this->assertEquals(5, $DB->count_records('course'));
 314          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 315          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_ACTIVE);
 316          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_ACTIVE);
 317  
 318          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 319          $o = array();
 320          $o['objectClass'] = array('posixGroup');
 321          $o['cn']          = 'course1';
 322          $o['gidNumber']   = '1';
 323          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 324  
 325          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
 326          $enrol->sync_enrolments(new null_progress_trace());
 327          $this->assertEquals(9, $DB->count_records('user_enrolments'));
 328          $this->assertEquals(9, $DB->count_records('role_assignments'));
 329          $this->assertEquals(5, $DB->count_records('course'));
 330          $this->assertIsNotEnrolled($course1->id, $user1->id);
 331          $this->assertIsNotEnrolled($course1->id, $user2->id);
 332          $this->assertIsNotEnrolled($course1->id, $user3->id);
 333  
 334  
 335          // Individual user enrolments-
 336  
 337          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 338          $o = array();
 339          $o['objectClass'] = array('posixGroup');
 340          $o['cn']          = 'course1';
 341          $o['gidNumber']   = '1';
 342          $o['memberUid']   = array('user1', 'user2', 'user3');
 343          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 344  
 345          $enrol->sync_user_enrolments($user1);
 346          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 347          $this->assertEquals(10, $DB->count_records('role_assignments'));
 348          $this->assertEquals(5, $DB->count_records('course'));
 349          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 350  
 351          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 352          $o = array();
 353          $o['objectClass'] = array('posixGroup');
 354          $o['cn']          = 'course1';
 355          $o['gidNumber']   = '1';
 356          $o['memberUid']   = array('user2', 'user3');
 357          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 358  
 359          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 360          $enrol->sync_user_enrolments($user1);
 361          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 362          $this->assertEquals(10, $DB->count_records('role_assignments'));
 363          $this->assertEquals(5, $DB->count_records('course'));
 364          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 365  
 366          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND);
 367          $enrol->sync_user_enrolments($user1);
 368          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 369          $this->assertEquals(10, $DB->count_records('role_assignments'));
 370          $this->assertEquals(5, $DB->count_records('course'));
 371          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_SUSPENDED);
 372  
 373          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 374          $o = array();
 375          $o['objectClass'] = array('posixGroup');
 376          $o['cn']          = 'course1';
 377          $o['gidNumber']   = '1';
 378          $o['memberUid']   = array('user1', 'user2', 'user3');
 379          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 380  
 381          $enrol->sync_user_enrolments($user1);
 382          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 383          $this->assertEquals(10, $DB->count_records('role_assignments'));
 384          $this->assertEquals(5, $DB->count_records('course'));
 385          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 386  
 387          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 388          $o = array();
 389          $o['objectClass'] = array('posixGroup');
 390          $o['cn']          = 'course1';
 391          $o['gidNumber']   = '1';
 392          $o['memberUid']   = array('user2', 'user3');
 393          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 394  
 395          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
 396          $enrol->sync_user_enrolments($user1);
 397          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 398          $this->assertEquals(9, $DB->count_records('role_assignments'));
 399          $this->assertEquals(5, $DB->count_records('course'));
 400          $this->assertIsEnrolled($course1->id, $user1->id, 0, ENROL_USER_SUSPENDED);
 401  
 402          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 403          $o = array();
 404          $o['objectClass'] = array('posixGroup');
 405          $o['cn']          = 'course1';
 406          $o['gidNumber']   = '1';
 407          $o['memberUid']   = array('user1', 'user2', 'user3');
 408          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 409  
 410          $enrol->sync_user_enrolments($user1);
 411          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 412          $this->assertEquals(10, $DB->count_records('role_assignments'));
 413          $this->assertEquals(5, $DB->count_records('course'));
 414          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 415  
 416          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 417          $o = array();
 418          $o['objectClass'] = array('posixGroup');
 419          $o['cn']          = 'course1';
 420          $o['gidNumber']   = '1';
 421          $o['memberUid']   = array('user2', 'user3');
 422          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 423  
 424          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
 425          $enrol->sync_user_enrolments($user1);
 426          $this->assertEquals(9, $DB->count_records('user_enrolments'));
 427          $this->assertEquals(9, $DB->count_records('role_assignments'));
 428          $this->assertEquals(5, $DB->count_records('course'));
 429          $this->assertIsNotEnrolled($course1->id, $user1->id);
 430  
 431          $this->recursive_delete($connection, TEST_ENROL_LDAP_DOMAIN, 'dc=moodletest');
 432          ldap_close($connection);
 433  
 434          // NOTE: multiple roles in one course is not supported, sorry
 435      }
 436  
 437      public function assertIsEnrolled($courseid, $userid, $roleid, $status=null) {
 438          global $DB;
 439  
 440          $context = context_course::instance($courseid);
 441          $instance = $DB->get_record('enrol', array('courseid'=>$courseid, 'enrol'=>'ldap'));
 442          $this->assertNotEmpty($instance);
 443          $ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid));
 444          $this->assertNotEmpty($ue);
 445          if (isset($status)) {
 446              $this->assertEquals($status, $ue->status);
 447          }
 448          if ($roleid) {
 449              $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$userid, 'roleid'=>$roleid, 'component'=>'enrol_ldap')));
 450          } else {
 451              $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$userid, 'component'=>'enrol_ldap')));
 452          }
 453      }
 454  
 455      public function assertIsNotEnrolled($courseid, $userid) {
 456          $context = context_course::instance($courseid);
 457          $this->assertFalse(is_enrolled($context, $userid));
 458      }
 459  
 460      protected function enable_plugin() {
 461          $enabled = enrol_get_plugins(true);
 462          $enabled['ldap'] = true;
 463          $enabled = array_keys($enabled);
 464          set_config('enrol_plugins_enabled', implode(',', $enabled));
 465      }
 466  
 467      protected function disable_plugin() {
 468          $enabled = enrol_get_plugins(true);
 469          unset($enabled['ldap']);
 470          $enabled = array_keys($enabled);
 471          set_config('enrol_plugins_enabled', implode(',', $enabled));
 472      }
 473  
 474      protected function recursive_delete($connection, $dn, $filter) {
 475          if ($res = ldap_list($connection, $dn, $filter, array('dn'))) {
 476              $info = ldap_get_entries($connection, $res);
 477              ldap_free_result($res);
 478              if ($info['count'] > 0) {
 479                  if ($res = ldap_search($connection, "$filter,$dn", 'cn=*', array('dn'))) {
 480                      $info = ldap_get_entries($connection, $res);
 481                      ldap_free_result($res);
 482                      foreach ($info as $i) {
 483                          if (isset($i['dn'])) {
 484                              ldap_delete($connection, $i['dn']);
 485                          }
 486                      }
 487                  }
 488                  if ($res = ldap_search($connection, "$filter,$dn", 'ou=*', array('dn'))) {
 489                      $info = ldap_get_entries($connection, $res);
 490                      ldap_free_result($res);
 491                      foreach ($info as $i) {
 492                          if (isset($i['dn']) and $info[0]['dn'] != $i['dn']) {
 493                              ldap_delete($connection, $i['dn']);
 494                          }
 495                      }
 496                  }
 497                  ldap_delete($connection, "$filter,$dn");
 498              }
 499          }
 500      }
 501  
 502      /**
 503       * Test that normalisation of the use objectclass is completed successfully.
 504       *
 505       * @dataProvider objectclass_fetch_provider
 506       * @param string $usertype The supported user type
 507       * @param string $expected The expected filter value
 508       */
 509      public function test_objectclass_fetch($usertype, $expected) {
 510          $this->resetAfterTest();
 511          // Set the user type - this must be performed before the plugin is instantiated.
 512          set_config('user_type', $usertype, 'enrol_ldap');
 513  
 514          // Fetch the plugin.
 515          $instance = enrol_get_plugin('ldap');
 516  
 517          // Use reflection to sneak a look at the plugin.
 518          $rc = new ReflectionClass('enrol_ldap_plugin');
 519          $rcp = $rc->getProperty('userobjectclass');
 520          $rcp->setAccessible(true);
 521  
 522          // Fetch the current userobjectclass value.
 523          $value = $rcp->getValue($instance);
 524          $this->assertEquals($expected, $value);
 525      }
 526  
 527      /**
 528       * Data provider for the test_objectclass_fetch testcase.
 529       *
 530       * @return array of testcases.
 531       */
 532      public function objectclass_fetch_provider() {
 533          return array(
 534              // This is the list of values from ldap_getdefaults() normalised.
 535              'edir' => array(
 536                  'edir',
 537                  '(objectClass=user)'
 538              ),
 539              'rfc2307' => array(
 540                  'rfc2307',
 541                  '(objectClass=posixaccount)'
 542              ),
 543              'rfc2307bis' => array(
 544                  'rfc2307bis',
 545                  '(objectClass=posixaccount)'
 546              ),
 547              'samba' => array(
 548                  'samba',
 549                  '(objectClass=sambasamaccount)'
 550              ),
 551              'ad' => array(
 552                  'ad',
 553                  '(samaccounttype=805306368)'
 554              ),
 555              'default' => array(
 556                  'default',
 557                  '(objectClass=*)'
 558              ),
 559          );
 560      }
 561  }