Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
  • Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 37 and 311] [Versions 38 and 311] [Versions 39 and 311]

       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  namespace enrol_cohort;
      18  
      19  defined('MOODLE_INTERNAL') || die();
      20  
      21  global $CFG;
      22  require_once($CFG->dirroot.'/enrol/cohort/locallib.php');
      23  require_once($CFG->dirroot.'/cohort/lib.php');
      24  require_once($CFG->dirroot.'/group/lib.php');
      25  
      26  /**
      27   * Cohort enrolment sync functional test.
      28   *
      29   * @package    enrol_cohort
      30   * @category   test
      31   * @copyright  2012 Petr Skoda {@link http://skodak.org}
      32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      33   */
      34  class sync_test extends \advanced_testcase {
      35  
      36      protected function enable_plugin() {
      37          $enabled = enrol_get_plugins(true);
      38          $enabled['cohort'] = true;
      39          $enabled = array_keys($enabled);
      40          set_config('enrol_plugins_enabled', implode(',', $enabled));
      41      }
      42  
      43      protected function disable_plugin() {
      44          $enabled = enrol_get_plugins(true);
      45          unset($enabled['cohort']);
      46          $enabled = array_keys($enabled);
      47          set_config('enrol_plugins_enabled', implode(',', $enabled));
      48      }
      49  
      50      public function test_handler_sync() {
      51          global $DB;
      52  
      53          $this->resetAfterTest();
      54          $trace = new \null_progress_trace();
      55  
      56          // Setup a few courses and categories.
      57  
      58          $cohortplugin = enrol_get_plugin('cohort');
      59          $manualplugin = enrol_get_plugin('manual');
      60  
      61          $studentrole = $DB->get_record('role', array('shortname'=>'student'));
      62          $this->assertNotEmpty($studentrole);
      63          $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
      64          $this->assertNotEmpty($teacherrole);
      65          $managerrole = $DB->get_record('role', array('shortname'=>'manager'));
      66          $this->assertNotEmpty($managerrole);
      67  
      68          $cat1 = $this->getDataGenerator()->create_category();
      69          $cat2 = $this->getDataGenerator()->create_category();
      70  
      71          $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
      72          $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
      73          $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
      74          $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
      75          $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
      76  
      77          $user1 = $this->getDataGenerator()->create_user();
      78          $user2 = $this->getDataGenerator()->create_user();
      79          $user3 = $this->getDataGenerator()->create_user();
      80          $user4 = $this->getDataGenerator()->create_user();
      81  
      82          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
      83          $cohort2 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat2->id)->id));
      84          $cohort3 = $this->getDataGenerator()->create_cohort();
      85  
      86          $this->enable_plugin();
      87  
      88          $manualplugin->enrol_user($maninstance1, $user4->id, $teacherrole->id);
      89          $manualplugin->enrol_user($maninstance1, $user3->id, $managerrole->id);
      90  
      91          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
      92          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
      93  
      94          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id));
      95          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
      96  
      97          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort2->id, 'roleid'=>$teacherrole->id));
      98          $cohortinstance2 = $DB->get_record('enrol', array('id'=>$id));
      99  
     100          $id = $cohortplugin->add_instance($course2, array('customint1'=>$cohort2->id, 'roleid'=>$studentrole->id));
     101          $cohortinstance3 = $DB->get_record('enrol', array('id'=>$id));
     102  
     103          $id = $cohortplugin->add_instance($course2, array('customint1' => $cohort2->id, 'roleid' => $studentrole->id, 'status' => ENROL_INSTANCE_DISABLED));
     104          $cohortinstance4 = $DB->get_record('enrol', array('id' => $id));
     105  
     106          // Test cohort member add event.
     107  
     108          cohort_add_member($cohort1->id, $user1->id);
     109          cohort_add_member($cohort1->id, $user2->id);
     110          cohort_add_member($cohort1->id, $user4->id);
     111          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     112          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
     113          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
     114          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user4->id)));
     115          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     116          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     117          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     118          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     119  
     120          cohort_add_member($cohort2->id, $user3->id);
     121          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     122          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     123          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance3->id, 'userid'=>$user3->id)));
     124          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid' => $cohortinstance4->id, 'userid' => $user3->id)));
     125          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     126          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     127          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course2->id)->id, 'userid'=>$user3->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance3->id)));
     128  
     129          cohort_add_member($cohort3->id, $user3->id);
     130          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     131          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     132  
     133          // Test cohort remove action.
     134  
     135          $this->assertEquals(ENROL_EXT_REMOVED_UNENROL, $cohortplugin->get_config('unenrolaction'));
     136          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     137  
     138          cohort_remove_member($cohort1->id, $user2->id);
     139          cohort_remove_member($cohort1->id, $user4->id);
     140          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     141          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     142          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     143          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     144  
     145          cohort_add_member($cohort1->id, $user2->id);
     146          cohort_add_member($cohort1->id, $user4->id);
     147          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     148          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     149          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     150          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     151  
     152          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     153          cohort_remove_member($cohort1->id, $user2->id);
     154          cohort_remove_member($cohort1->id, $user4->id);
     155          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     156          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
     157          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user4->id)));
     158  
     159          cohort_remove_member($cohort2->id, $user3->id);
     160          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     161          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     162          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance3->id, 'userid'=>$user3->id)));
     163          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     164          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     165          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course2->id)->id, 'userid'=>$user3->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance3->id)));
     166  
     167          // Test cohort deleting.
     168  
     169          cohort_add_member($cohort1->id, $user2->id);
     170          cohort_add_member($cohort1->id, $user4->id);
     171          cohort_add_member($cohort2->id, $user3->id);
     172          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     173          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     174  
     175          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     176          cohort_delete_cohort($cohort2);
     177          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     178          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     179  
     180          $cohortinstance2 = $DB->get_record('enrol', array('id'=>$cohortinstance2->id), '*', MUST_EXIST);
     181          $cohortinstance3 = $DB->get_record('enrol', array('id'=>$cohortinstance3->id), '*', MUST_EXIST);
     182  
     183          $this->assertEquals(ENROL_INSTANCE_DISABLED, $cohortinstance2->status);
     184          $this->assertEquals(ENROL_INSTANCE_DISABLED, $cohortinstance3->status);
     185          $this->assertFalse($DB->record_exists('role_assignments', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     186          $this->assertFalse($DB->record_exists('role_assignments', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance3->id)));
     187  
     188          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     189          cohort_delete_cohort($cohort1);
     190          $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
     191          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     192          $this->assertFalse($DB->record_exists('enrol', array('id'=>$cohortinstance1->id)));
     193          $this->assertFalse($DB->record_exists('role_assignments', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     194  
     195          // Cleanup after previous test (remove the extra user_enrolment).
     196          enrol_cohort_sync($trace, $course1->id);
     197          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     198  
     199          // Test group sync.
     200  
     201          $id = groups_create_group((object)array('name'=>'Group 1', 'courseid'=>$course1->id));
     202          $group1 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     203          $id = groups_create_group((object)array('name'=>'Group 2', 'courseid'=>$course1->id));
     204          $group2 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     205  
     206          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
     207          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id, 'customint2'=>$group1->id));
     208          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
     209  
     210          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     211          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     212  
     213          $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4));
     214          $this->assertTrue(groups_add_member($group1, $user4));
     215          $this->assertTrue(groups_add_member($group2, $user4));
     216  
     217          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     218          cohort_add_member($cohort1->id, $user1->id);
     219          $this->assertTrue(groups_is_member($group1->id, $user1->id));
     220          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     221  
     222          cohort_add_member($cohort1->id, $user4->id);
     223          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     224          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     225  
     226          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     227  
     228          cohort_remove_member($cohort1->id, $user1->id);
     229          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     230  
     231          cohort_remove_member($cohort1->id, $user4->id);
     232          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     233          $this->assertTrue(groups_is_member($group2->id, $user4->id));
     234  
     235          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     236          cohort_add_member($cohort1->id, $user1->id);
     237  
     238          cohort_remove_member($cohort1->id, $user1->id);
     239          $this->assertTrue(groups_is_member($group1->id, $user1->id));
     240  
     241  
     242          // Test deleting of instances.
     243  
     244          cohort_add_member($cohort1->id, $user1->id);
     245          cohort_add_member($cohort1->id, $user2->id);
     246          cohort_add_member($cohort1->id, $user3->id);
     247  
     248          $this->assertEquals(6, $DB->count_records('user_enrolments', array()));
     249          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     250          $this->assertEquals(3, $DB->count_records('role_assignments', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     251          $this->assertEquals(5, $DB->count_records('groups_members', array()));
     252          $this->assertEquals(3, $DB->count_records('groups_members', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     253  
     254          $cohortplugin->delete_instance($cohortinstance1);
     255  
     256          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     257          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     258          $this->assertEquals(0, $DB->count_records('role_assignments', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     259          $this->assertEquals(2, $DB->count_records('groups_members', array()));
     260          $this->assertEquals(0, $DB->count_records('groups_members', array('component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     261      }
     262  
     263      public function test_sync_course() {
     264          global $DB;
     265          $this->resetAfterTest();
     266  
     267          $trace = new \null_progress_trace();
     268  
     269          // Setup a few courses and categories.
     270  
     271          $cohortplugin = enrol_get_plugin('cohort');
     272          $manualplugin = enrol_get_plugin('manual');
     273  
     274          $studentrole = $DB->get_record('role', array('shortname'=>'student'));
     275          $this->assertNotEmpty($studentrole);
     276          $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
     277          $this->assertNotEmpty($teacherrole);
     278          $managerrole = $DB->get_record('role', array('shortname'=>'manager'));
     279          $this->assertNotEmpty($managerrole);
     280  
     281          $cat1 = $this->getDataGenerator()->create_category();
     282          $cat2 = $this->getDataGenerator()->create_category();
     283  
     284          $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
     285          $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
     286          $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
     287          $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
     288          $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
     289  
     290          $user1 = $this->getDataGenerator()->create_user();
     291          $user2 = $this->getDataGenerator()->create_user();
     292          $user3 = $this->getDataGenerator()->create_user();
     293          $user4 = $this->getDataGenerator()->create_user();
     294  
     295          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
     296          $cohort2 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat2->id)->id));
     297          $cohort3 = $this->getDataGenerator()->create_cohort();
     298  
     299          $this->disable_plugin(); // Prevents event sync.
     300  
     301          $manualplugin->enrol_user($maninstance1, $user4->id, $teacherrole->id);
     302          $manualplugin->enrol_user($maninstance1, $user3->id, $managerrole->id);
     303  
     304          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     305          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     306  
     307          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id));
     308          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
     309  
     310          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort2->id, 'roleid'=>$teacherrole->id));
     311          $cohortinstance2 = $DB->get_record('enrol', array('id'=>$id));
     312  
     313          $id = $cohortplugin->add_instance($course2, array('customint1'=>$cohort2->id, 'roleid'=>$studentrole->id));
     314          $cohortinstance3 = $DB->get_record('enrol', array('id'=>$id));
     315  
     316          $id = $cohortplugin->add_instance($course2, array('customint1' => $cohort2->id, 'roleid' => $studentrole->id, 'status' => ENROL_INSTANCE_DISABLED));
     317          $cohortinstance4 = $DB->get_record('enrol', array('id' => $id));
     318  
     319          cohort_add_member($cohort1->id, $user1->id);
     320          cohort_add_member($cohort1->id, $user2->id);
     321          cohort_add_member($cohort1->id, $user4->id);
     322          cohort_add_member($cohort2->id, $user3->id);
     323          cohort_add_member($cohort3->id, $user3->id);
     324  
     325          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     326          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     327  
     328  
     329          // Test sync of one course only.
     330  
     331          enrol_cohort_sync($trace, $course1->id);
     332          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     333          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     334  
     335  
     336          $this->enable_plugin();
     337          enrol_cohort_sync($trace, $course2->id);
     338          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     339          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     340          $DB->delete_records('cohort_members', array('cohortid'=>$cohort3->id)); // Use low level DB api to prevent events!
     341          $DB->delete_records('cohort', array('id'=>$cohort3->id)); // Use low level DB api to prevent events!
     342  
     343          enrol_cohort_sync($trace, $course1->id);
     344          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     345          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
     346          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
     347          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user4->id)));
     348          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     349          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid' => $cohortinstance4->id, 'userid' => $user3->id)));
     350          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     351          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     352          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     353          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     354          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     355  
     356          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     357          $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
     358          enrol_cohort_sync($trace, $course1->id);
     359          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     360          $this->assertEquals(6, $DB->count_records('role_assignments', array()));
     361          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     362  
     363          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     364          $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
     365          enrol_cohort_sync($trace, $course1->id);
     366          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     367          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     368          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
     369          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     370          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     371          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     372  
     373          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     374          $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
     375          $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
     376          enrol_cohort_sync($trace, $course1->id);
     377          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     378          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     379  
     380          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     381          enrol_cohort_sync($trace, $course1->id);
     382          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     383          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     384  
     385  
     386          // Test group sync.
     387  
     388          $this->disable_plugin(); // No event sync.
     389  
     390          // Trigger sync to remove left over role assignments.
     391          enrol_cohort_sync($trace, $course1->id);
     392          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     393  
     394          $id = groups_create_group((object)array('name'=>'Group 1', 'courseid'=>$course1->id));
     395          $group1 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     396          $id = groups_create_group((object)array('name'=>'Group 2', 'courseid'=>$course1->id));
     397          $group2 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     398  
     399          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
     400          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id, 'customint2'=>$group1->id));
     401          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
     402  
     403          $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4));
     404          $this->assertTrue(groups_add_member($group1, $user4));
     405          $this->assertTrue(groups_add_member($group2, $user4));
     406  
     407          $this->enable_plugin(); // No event sync.
     408  
     409          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     410          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     411  
     412          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     413          cohort_add_member($cohort1->id, $user1->id);
     414          cohort_add_member($cohort1->id, $user4->id);
     415          cohort_add_member($cohort2->id, $user4->id);
     416  
     417          enrol_cohort_sync($trace, $course1->id);
     418  
     419          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     420          // This used to be 7 - but now add_instance triggers an immediate sync.
     421          $this->assertEquals(6, $DB->count_records('role_assignments', array()));
     422  
     423          $this->assertTrue(groups_is_member($group1->id, $user1->id));
     424          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     425  
     426          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     427          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     428  
     429          $cohortinstance1->customint2 = $group2->id;
     430          $DB->update_record('enrol', $cohortinstance1);
     431  
     432          enrol_cohort_sync($trace, $course1->id);
     433          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     434          $this->assertTrue(groups_is_member($group2->id, $user1->id));
     435          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     436  
     437          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     438          $this->assertTrue(groups_is_member($group2->id, $user4->id));
     439          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     440          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     441  
     442          cohort_remove_member($cohort1->id, $user1->id);
     443          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     444  
     445          cohort_remove_member($cohort1->id, $user4->id);
     446          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     447          $this->assertTrue(groups_is_member($group2->id, $user4->id));
     448      }
     449  
     450      public function test_sync_all_courses() {
     451          global $DB;
     452  
     453          $this->resetAfterTest();
     454  
     455          $trace = new \null_progress_trace();
     456  
     457          // Setup a few courses and categories.
     458  
     459          $cohortplugin = enrol_get_plugin('cohort');
     460          $manualplugin = enrol_get_plugin('manual');
     461  
     462          $studentrole = $DB->get_record('role', array('shortname'=>'student'));
     463          $this->assertNotEmpty($studentrole);
     464          $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
     465          $this->assertNotEmpty($teacherrole);
     466          $managerrole = $DB->get_record('role', array('shortname'=>'manager'));
     467          $this->assertNotEmpty($managerrole);
     468  
     469          $cat1 = $this->getDataGenerator()->create_category();
     470          $cat2 = $this->getDataGenerator()->create_category();
     471  
     472          $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
     473          $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id));
     474          $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
     475          $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id));
     476          $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
     477  
     478          $user1 = $this->getDataGenerator()->create_user();
     479          $user2 = $this->getDataGenerator()->create_user();
     480          $user3 = $this->getDataGenerator()->create_user();
     481          $user4 = $this->getDataGenerator()->create_user();
     482  
     483          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
     484          $cohort2 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat2->id)->id));
     485          $cohort3 = $this->getDataGenerator()->create_cohort();
     486  
     487          $this->disable_plugin(); // Prevents event sync.
     488  
     489          $manualplugin->enrol_user($maninstance1, $user4->id, $teacherrole->id);
     490          $manualplugin->enrol_user($maninstance1, $user3->id, $managerrole->id);
     491  
     492          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     493          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     494  
     495          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id));
     496          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
     497  
     498          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort2->id, 'roleid'=>$teacherrole->id));
     499          $cohortinstance2 = $DB->get_record('enrol', array('id'=>$id));
     500  
     501          $id = $cohortplugin->add_instance($course2, array('customint1'=>$cohort2->id, 'roleid'=>$studentrole->id));
     502          $cohortinstance3 = $DB->get_record('enrol', array('id'=>$id));
     503  
     504          cohort_add_member($cohort1->id, $user1->id);
     505          cohort_add_member($cohort1->id, $user2->id);
     506          cohort_add_member($cohort1->id, $user4->id);
     507          cohort_add_member($cohort2->id, $user3->id);
     508          cohort_add_member($cohort3->id, $user3->id);
     509  
     510          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     511          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     512  
     513  
     514          // Test sync of one course only.
     515  
     516          enrol_cohort_sync($trace, null);
     517          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     518          $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
     519  
     520  
     521          $this->enable_plugin();
     522          enrol_cohort_sync($trace, null);
     523          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     524          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
     525          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
     526          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user4->id)));
     527          $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     528          $this->assertEquals(7, $DB->count_records('role_assignments', array()));
     529          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     530          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     531          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     532          $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     533  
     534          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     535          $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
     536          enrol_cohort_sync($trace, $course1->id);
     537          $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
     538          $this->assertEquals(6, $DB->count_records('role_assignments', array()));
     539          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     540  
     541          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     542          $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
     543          enrol_cohort_sync($trace, $course1->id);
     544          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     545          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
     546          $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
     547          $this->assertEquals(5, $DB->count_records('role_assignments', array()));
     548          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
     549          $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>\context_course::instance($course1->id)->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     550  
     551          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     552          $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
     553          $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
     554          enrol_cohort_sync($trace, $course1->id);
     555          $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
     556          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     557  
     558          $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     559          enrol_cohort_sync($trace, $course1->id);
     560          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     561          $this->assertEquals(3, $DB->count_records('role_assignments', array()));
     562  
     563  
     564          // Test group sync.
     565  
     566          $this->disable_plugin(); // No event sync
     567          // Trigger sync to remove extra role assignments.
     568          enrol_cohort_sync($trace, $course1->id);
     569          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     570  
     571          $id = groups_create_group((object)array('name'=>'Group 1', 'courseid'=>$course1->id));
     572          $group1 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     573          $id = groups_create_group((object)array('name'=>'Group 2', 'courseid'=>$course1->id));
     574          $group2 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     575          $id = groups_create_group((object)array('name'=>'Group 2', 'courseid'=>$course2->id));
     576          $group3 = $DB->get_record('groups', array('id'=>$id), '*', MUST_EXIST);
     577  
     578          $cohort1 = $this->getDataGenerator()->create_cohort(array('contextid'=>\context_coursecat::instance($cat1->id)->id));
     579          $id = $cohortplugin->add_instance($course1, array('customint1'=>$cohort1->id, 'roleid'=>$studentrole->id, 'customint2'=>$group1->id));
     580          $cohortinstance1 = $DB->get_record('enrol', array('id'=>$id));
     581  
     582          $this->assertTrue(groups_add_member($group1, $user4));
     583          $this->assertTrue(groups_add_member($group2, $user4));
     584  
     585          $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
     586          $this->assertEquals(2, $DB->count_records('role_assignments', array()));
     587  
     588          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     589          cohort_add_member($cohort1->id, $user1->id);
     590          cohort_add_member($cohort1->id, $user4->id);
     591          cohort_add_member($cohort2->id, $user4->id);
     592          cohort_add_member($cohort2->id, $user3->id);
     593  
     594          $this->enable_plugin();
     595  
     596          enrol_cohort_sync($trace, null);
     597  
     598          $this->assertEquals(8, $DB->count_records('user_enrolments', array()));
     599          $this->assertEquals(8, $DB->count_records('role_assignments', array()));
     600  
     601          $this->assertTrue(groups_is_member($group1->id, $user1->id));
     602          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     603  
     604          $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4));
     605          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     606          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     607  
     608          $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user3));
     609          $this->assertFalse(groups_is_member($group3->id, $user3->id));
     610  
     611          $cohortinstance1->customint2 = $group2->id;
     612          $DB->update_record('enrol', $cohortinstance1);
     613          $cohortinstance3->customint2 = $group3->id;
     614          $DB->update_record('enrol', $cohortinstance3);
     615  
     616          enrol_cohort_sync($trace, null);
     617          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     618          $this->assertTrue(groups_is_member($group2->id, $user1->id));
     619          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     620  
     621          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     622          $this->assertTrue(groups_is_member($group2->id, $user4->id));
     623          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group1->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     624          $this->assertFalse($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user4->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
     625  
     626          $this->assertTrue(groups_is_member($group3->id, $user3->id));
     627          $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group3->id, 'userid'=>$user3->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance3->id)));
     628  
     629          cohort_remove_member($cohort1->id, $user1->id);
     630          $this->assertFalse(groups_is_member($group1->id, $user1->id));
     631  
     632          cohort_remove_member($cohort1->id, $user4->id);
     633          $this->assertTrue(groups_is_member($group1->id, $user4->id));
     634          $this->assertTrue(groups_is_member($group2->id, $user4->id));
     635      }
     636  }