Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 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  namespace tool_lpmigrate;
  18  
  19  use core_competency\course_competency;
  20  use core_competency\course_module_competency;
  21  
  22  /**
  23   * Framework processor testcase.
  24   *
  25   * @package    tool_lpmigrate
  26   * @copyright  2016 Frédéric Massart - FMCorz.net
  27   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  28   */
  29  class processor_test extends \advanced_testcase {
  30  
  31      /**
  32       * This sets up a few things, and assign class variables.
  33       *
  34       * We create 2 frameworks, each with 2 matching competencies and 1 foreign.
  35       * Then we create 2 courses, and in each 1 CM.
  36       * Then we attach some competencies from the first framework to courses and CM.
  37       */
  38      public function setUp(): void {
  39          $this->resetAfterTest(true);
  40          $dg = $this->getDataGenerator();
  41          $lpg = $dg->get_plugin_generator('core_competency');
  42  
  43          $f1 = $lpg->create_framework(array('idnumber' => 'BIO2015'));
  44          $f2 = $lpg->create_framework(array('idnumber' => 'BIO2016'));
  45  
  46          $f1comps = array();
  47          $f1comps['A1'] = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'idnumber' => 'A1'));
  48          $f1comps['A2'] = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'idnumber' => 'A2'));
  49          $f1comps['A3'] = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'idnumber' => 'A3'));
  50          $f1comps['X1'] = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'idnumber' => 'X1'));
  51  
  52          $f2comps = array();
  53          $f2comps['A1'] = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id'), 'idnumber' => 'A1'));
  54          $f2comps['A2'] = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id'), 'idnumber' => 'A2'));
  55          $f2comps['A3'] = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id'), 'idnumber' => 'A3'));
  56          $f2comps['Y1'] = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id'), 'idnumber' => 'Y1'));
  57  
  58          $c1 = $dg->create_course(array('startdate' => time() - 72000));
  59          $c2 = $dg->create_course(array('startdate' => time() + 72000));
  60          $cms = array(
  61              $c1->id => array(
  62                  'F1' => $dg->create_module('forum', (object) array('course' => $c1->id)),
  63                  'P1' => $dg->create_module('page', (object) array('course' => $c1->id)),
  64                  'EmptyA' => $dg->create_module('page', (object) array('course' => $c1->id)),
  65              ),
  66              $c2->id => array(
  67                  'F1' => $dg->create_module('forum', (object) array('course' => $c2->id)),
  68                  'EmptyB' => $dg->create_module('page', (object) array('course' => $c2->id)),
  69              ),
  70          );
  71  
  72          // Course CompetencieS.
  73          $ccs = array(
  74              $c1->id => array(
  75                  $f1comps['A1']->get('id') => $lpg->create_course_competency(array('courseid' => $c1->id,
  76                      'competencyid' => $f1comps['A1']->get('id'))),
  77                  $f1comps['A3']->get('id') => $lpg->create_course_competency(array('courseid' => $c1->id,
  78                      'competencyid' => $f1comps['A3']->get('id'))),
  79                  $f1comps['X1']->get('id') => $lpg->create_course_competency(array('courseid' => $c1->id,
  80                      'competencyid' => $f1comps['X1']->get('id'))),
  81              ),
  82              $c2->id => array(
  83                  $f1comps['A2']->get('id') => $lpg->create_course_competency(array('courseid' => $c2->id,
  84                      'competencyid' => $f1comps['A2']->get('id'))),
  85                  $f1comps['A3']->get('id') => $lpg->create_course_competency(array('courseid' => $c2->id,
  86                      'competencyid' => $f1comps['A3']->get('id'))),
  87              )
  88          );
  89  
  90          // Course Module CompetencieS.
  91          $cmcs = array(
  92              $cms[$c1->id]['F1']->cmid => array(
  93                  $f1comps['A1']->get('id') => $lpg->create_course_module_competency(array(
  94                      'cmid' => $cms[$c1->id]['F1']->cmid,
  95                      'competencyid' => $f1comps['A1']->get('id')
  96                  )),
  97                  $f1comps['X1']->get('id') => $lpg->create_course_module_competency(array(
  98                      'cmid' => $cms[$c1->id]['F1']->cmid,
  99                      'competencyid' => $f1comps['X1']->get('id')
 100                  )),
 101              ),
 102              $cms[$c1->id]['P1']->cmid => array(
 103                  $f1comps['A3']->get('id') => $lpg->create_course_module_competency(array(
 104                      'cmid' => $cms[$c1->id]['P1']->cmid,
 105                      'competencyid' => $f1comps['A3']->get('id')
 106                  )),
 107              ),
 108              $cms[$c2->id]['F1']->cmid => array(
 109                  $f1comps['A2']->get('id') => $lpg->create_course_module_competency(array(
 110                      'cmid' => $cms[$c2->id]['F1']->cmid,
 111                      'competencyid' => $f1comps['A2']->get('id')
 112                  )),
 113                  $f1comps['A3']->get('id') => $lpg->create_course_module_competency(array(
 114                      'cmid' => $cms[$c2->id]['F1']->cmid,
 115                      'competencyid' => $f1comps['A3']->get('id')
 116                  )),
 117              ),
 118          );
 119  
 120          $this->assertCourseCompetencyExists($c1, $f1comps['A1']);
 121          $this->assertCourseCompetencyExists($c1, $f1comps['A3']);
 122          $this->assertCourseCompetencyExists($c1, $f1comps['X1']);
 123          $this->assertCourseCompetencyExists($c2, $f1comps['A2']);
 124          $this->assertCourseCompetencyExists($c2, $f1comps['A3']);
 125          $this->assertModuleCompetencyExists($cms[$c1->id]['F1'], $f1comps['A1']);
 126          $this->assertModuleCompetencyExists($cms[$c1->id]['P1'], $f1comps['A3']);
 127          $this->assertModuleCompetencyExists($cms[$c1->id]['F1'], $f1comps['X1']);
 128          $this->assertModuleCompetencyExists($cms[$c2->id]['F1'], $f1comps['A2']);
 129          $this->assertModuleCompetencyExists($cms[$c2->id]['F1'], $f1comps['A3']);
 130  
 131          $this->f1 = $f1;
 132          $this->f1comps = $f1comps;
 133          $this->f2 = $f2;
 134          $this->f2comps = $f2comps;
 135          $this->c1 = $c1;
 136          $this->c2 = $c2;
 137          $this->cms = $cms;
 138          $this->ccs = $ccs;
 139          $this->cmcs = $cmcs;
 140      }
 141  
 142      public function test_simple_migration() {
 143          $this->setAdminUser();
 144  
 145          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 146          $mapper->automap();
 147          $processor = new framework_processor($mapper);
 148          $processor->proceed();
 149  
 150          $this->assertEquals(2, $processor->get_courses_found_count());
 151          $this->assertEquals(5, $processor->get_expected_course_competency_migrations());
 152          $this->assertEquals(4, $processor->get_course_competency_migrations());
 153          $this->assertEquals(4, $processor->get_course_competency_removals());
 154  
 155          $this->assertEquals(3, $processor->get_cms_found_count());
 156          $this->assertEquals(5, $processor->get_expected_module_competency_migrations());
 157          $this->assertEquals(4, $processor->get_module_competency_migrations());
 158          $this->assertEquals(4, $processor->get_module_competency_removals());
 159  
 160          $this->assertEquals(array(), $processor->get_warnings());
 161          $this->assertEquals(array(), $processor->get_errors());
 162          $this->assertEquals(array($this->f1comps['X1']->get('id') => true), $processor->get_missing_mappings());
 163  
 164          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A1'], $this->f2comps['A1']);
 165          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A3'], $this->f2comps['A3']);
 166          $this->assertCourseCompetencyMigrated($this->c2, $this->f1comps['A2'], $this->f2comps['A2']);
 167          $this->assertCourseCompetencyMigrated($this->c2, $this->f1comps['A3'], $this->f2comps['A3']);
 168  
 169          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['F1'], $this->f1comps['A1'], $this->f2comps['A1']);
 170          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['P1'], $this->f1comps['A3'], $this->f2comps['A3']);
 171          $this->assertModuleCompetencyMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A2'], $this->f2comps['A2']);
 172          $this->assertModuleCompetencyMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A3'], $this->f2comps['A3']);
 173  
 174          $this->assertCourseCompetencyExists($this->c1, $this->f1comps['X1']);
 175          $this->assertModuleCompetencyExists($this->cms[$this->c1->id]['F1'], $this->f1comps['X1']);
 176      }
 177  
 178      public function test_remove_when_missing() {
 179          $this->setAdminUser();
 180  
 181          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 182          $mapper->automap();
 183          $processor = new framework_processor($mapper);
 184          $processor->set_remove_when_mapping_is_missing(true);
 185          $processor->proceed();
 186  
 187          $this->assertEquals(2, $processor->get_courses_found_count());
 188          $this->assertEquals(5, $processor->get_expected_course_competency_migrations());
 189          $this->assertEquals(4, $processor->get_course_competency_migrations());
 190          $this->assertEquals(5, $processor->get_course_competency_removals());
 191  
 192          $this->assertEquals(3, $processor->get_cms_found_count());
 193          $this->assertEquals(5, $processor->get_expected_module_competency_migrations());
 194          $this->assertEquals(4, $processor->get_module_competency_migrations());
 195          $this->assertEquals(5, $processor->get_module_competency_removals());
 196  
 197          $this->assertCount(0, $processor->get_errors());
 198          $this->assertCount(0, $processor->get_warnings());
 199  
 200          $this->assertCourseCompetencyNotExists($this->c1, $this->f1comps['X1']);
 201          $this->assertModuleCompetencyNotExists($this->cms[$this->c1->id]['F1'], $this->f1comps['X1']);
 202      }
 203  
 204      public function test_allowed_courses() {
 205          $this->setAdminUser();
 206  
 207          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 208          $mapper->automap();
 209          $processor = new framework_processor($mapper);
 210          $processor->set_allowedcourses(array($this->c1->id));
 211          $processor->proceed();
 212  
 213          $this->assertEquals(1, $processor->get_courses_found_count());
 214          $this->assertEquals(3, $processor->get_expected_course_competency_migrations());
 215          $this->assertEquals(2, $processor->get_course_competency_migrations());
 216          $this->assertEquals(2, $processor->get_course_competency_removals());
 217  
 218          $this->assertEquals(2, $processor->get_cms_found_count());
 219          $this->assertEquals(3, $processor->get_expected_module_competency_migrations());
 220          $this->assertEquals(2, $processor->get_module_competency_migrations());
 221          $this->assertEquals(2, $processor->get_module_competency_removals());
 222  
 223          $this->assertCount(0, $processor->get_errors());
 224          $this->assertCount(0, $processor->get_warnings());
 225  
 226          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A1'], $this->f2comps['A1']);
 227          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A3'], $this->f2comps['A3']);
 228          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['F1'], $this->f1comps['A1'], $this->f2comps['A1']);
 229          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['P1'], $this->f1comps['A3'], $this->f2comps['A3']);
 230  
 231          $this->assertCourseCompetencyNotMigrated($this->c2, $this->f1comps['A2'], $this->f2comps['A2']);
 232          $this->assertCourseCompetencyNotMigrated($this->c2, $this->f1comps['A3'], $this->f2comps['A3']);
 233          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A2'], $this->f2comps['A2']);
 234          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A3'], $this->f2comps['A3']);
 235      }
 236  
 237      public function test_disallowed_courses() {
 238          $this->setAdminUser();
 239  
 240          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 241          $mapper->automap();
 242          $processor = new framework_processor($mapper);
 243          $processor->set_disallowedcourses(array($this->c2->id));
 244          $processor->proceed();
 245  
 246          $this->assertEquals(1, $processor->get_courses_found_count());
 247          $this->assertEquals(3, $processor->get_expected_course_competency_migrations());
 248          $this->assertEquals(2, $processor->get_course_competency_migrations());
 249          $this->assertEquals(2, $processor->get_course_competency_removals());
 250  
 251          $this->assertEquals(2, $processor->get_cms_found_count());
 252          $this->assertEquals(3, $processor->get_expected_module_competency_migrations());
 253          $this->assertEquals(2, $processor->get_module_competency_migrations());
 254          $this->assertEquals(2, $processor->get_module_competency_removals());
 255  
 256          $this->assertCount(0, $processor->get_errors());
 257          $this->assertCount(0, $processor->get_warnings());
 258  
 259          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A1'], $this->f2comps['A1']);
 260          $this->assertCourseCompetencyMigrated($this->c1, $this->f1comps['A3'], $this->f2comps['A3']);
 261          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['F1'], $this->f1comps['A1'], $this->f2comps['A1']);
 262          $this->assertModuleCompetencyMigrated($this->cms[$this->c1->id]['P1'], $this->f1comps['A3'], $this->f2comps['A3']);
 263  
 264          $this->assertCourseCompetencyNotMigrated($this->c2, $this->f1comps['A2'], $this->f2comps['A2']);
 265          $this->assertCourseCompetencyNotMigrated($this->c2, $this->f1comps['A3'], $this->f2comps['A3']);
 266          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A2'], $this->f2comps['A2']);
 267          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A3'], $this->f2comps['A3']);
 268      }
 269  
 270      public function test_course_start_date_from() {
 271          $this->setAdminUser();
 272  
 273          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 274          $mapper->automap();
 275          $processor = new framework_processor($mapper);
 276          $processor->set_course_start_date_from(time());
 277          $processor->proceed();
 278  
 279          $this->assertEquals(1, $processor->get_courses_found_count());
 280          $this->assertEquals(2, $processor->get_expected_course_competency_migrations());
 281          $this->assertEquals(2, $processor->get_course_competency_migrations());
 282          $this->assertEquals(2, $processor->get_course_competency_removals());
 283  
 284          $this->assertEquals(1, $processor->get_cms_found_count());
 285          $this->assertEquals(2, $processor->get_expected_module_competency_migrations());
 286          $this->assertEquals(2, $processor->get_module_competency_migrations());
 287          $this->assertEquals(2, $processor->get_module_competency_removals());
 288  
 289          $this->assertCount(0, $processor->get_errors());
 290          $this->assertCount(0, $processor->get_warnings());
 291  
 292          $this->assertCourseCompetencyNotMigrated($this->c1, $this->f1comps['A1'], $this->f2comps['A1']);
 293          $this->assertCourseCompetencyNotMigrated($this->c1, $this->f1comps['A3'], $this->f2comps['A3']);
 294          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c1->id]['F1'], $this->f1comps['A1'], $this->f2comps['A1']);
 295          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c1->id]['P1'], $this->f1comps['A3'], $this->f2comps['A3']);
 296  
 297          $this->assertCourseCompetencyMigrated($this->c2, $this->f1comps['A2'], $this->f2comps['A2']);
 298          $this->assertCourseCompetencyMigrated($this->c2, $this->f1comps['A3'], $this->f2comps['A3']);
 299          $this->assertModuleCompetencyMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A2'], $this->f2comps['A2']);
 300          $this->assertModuleCompetencyMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A3'], $this->f2comps['A3']);
 301      }
 302  
 303      public function test_destination_competency_exists() {
 304          $this->setAdminUser();
 305          $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
 306  
 307          // Pre-add the new competency to course 1.
 308          $lpg->create_course_competency(array('courseid' => $this->c1->id, 'competencyid' => $this->f2comps['A1']->get('id')));
 309  
 310          // Pre-add the new competency to module in course 2.
 311          $lpg->create_course_module_competency(array(
 312              'cmid' => $this->cms[$this->c2->id]['F1']->cmid,
 313              'competencyid' => $this->f2comps['A2']->get('id')
 314          ));
 315  
 316          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 317          $mapper->automap();
 318          $processor = new framework_processor($mapper);
 319          $processor->proceed();
 320  
 321          $this->assertEquals(2, $processor->get_courses_found_count());
 322          $this->assertEquals(5, $processor->get_expected_course_competency_migrations());
 323          $this->assertEquals(3, $processor->get_course_competency_migrations());
 324          $this->assertEquals(2, $processor->get_course_competency_removals());
 325  
 326          $this->assertEquals(3, $processor->get_cms_found_count());
 327          $this->assertEquals(5, $processor->get_expected_module_competency_migrations());
 328          $this->assertEquals(3, $processor->get_module_competency_migrations());
 329          $this->assertEquals(3, $processor->get_module_competency_removals());
 330  
 331          $this->assertEquals(array(), $processor->get_errors());
 332          $warnings = $processor->get_warnings();
 333          $this->assertCount(2, $warnings);
 334  
 335          $warning = array_shift($warnings);
 336          $this->assertEquals($this->c1->id, $warning['courseid']);
 337          $this->assertEquals($this->f1comps['A1']->get('id'), $warning['competencyid']);
 338          $this->assertEquals(null, $warning['cmid']);
 339          $this->assertMatchesRegularExpression('/competency already exists/', $warning['message']);
 340  
 341          $warning = array_shift($warnings);
 342          $this->assertEquals($this->c2->id, $warning['courseid']);
 343          $this->assertEquals($this->f1comps['A2']->get('id'), $warning['competencyid']);
 344          $this->assertEquals($this->cms[$this->c2->id]['F1']->cmid, $warning['cmid']);
 345          $this->assertMatchesRegularExpression('/competency already exists/', $warning['message']);
 346  
 347          $this->assertCourseCompetencyExists($this->c1, $this->f1comps['A1']);
 348          $this->assertModuleCompetencyExists($this->cms[$this->c2->id]['F1'], $this->f1comps['A2']);
 349      }
 350  
 351      public function test_destination_competency_exists_remove_original() {
 352          $this->setAdminUser();
 353          $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
 354  
 355          // Pre-add the new competency to course 1.
 356          $lpg->create_course_competency(array('courseid' => $this->c1->id, 'competencyid' => $this->f2comps['A1']->get('id')));
 357  
 358          // Pre-add the new competency to module in course 2.
 359          $lpg->create_course_module_competency(array(
 360              'cmid' => $this->cms[$this->c2->id]['F1']->cmid,
 361              'competencyid' => $this->f2comps['A2']->get('id')
 362          ));
 363  
 364          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 365          $mapper->automap();
 366          $processor = new framework_processor($mapper);
 367          $processor->set_remove_original_when_destination_already_present(true);
 368          $processor->proceed();
 369  
 370          $this->assertEquals(2, $processor->get_courses_found_count());
 371          $this->assertEquals(5, $processor->get_expected_course_competency_migrations());
 372          $this->assertEquals(3, $processor->get_course_competency_migrations());
 373          $this->assertEquals(4, $processor->get_course_competency_removals());
 374  
 375          $this->assertEquals(3, $processor->get_cms_found_count());
 376          $this->assertEquals(5, $processor->get_expected_module_competency_migrations());
 377          $this->assertEquals(3, $processor->get_module_competency_migrations());
 378          $this->assertEquals(4, $processor->get_module_competency_removals());
 379  
 380          $this->assertEquals(array(), $processor->get_errors());
 381          $this->assertEquals(array(), $processor->get_warnings());
 382  
 383          $this->assertCourseCompetencyNotExists($this->c1, $this->f1comps['A1']);
 384          $this->assertModuleCompetencyNotExists($this->cms[$this->c2->id]['F1'], $this->f1comps['A2']);
 385      }
 386  
 387      public function test_permission_exception() {
 388  
 389          $this->preventResetByRollback(); // Test uses transactions, so we cannot use them for speedy reset.
 390  
 391          $dg = $this->getDataGenerator();
 392          $u = $dg->create_user();
 393          $role = $dg->create_role();
 394          $sysctx = \context_system::instance();
 395  
 396          $dg->enrol_user($u->id, $this->c1->id, 'editingteacher');
 397          $dg->enrol_user($u->id, $this->c2->id, 'editingteacher');
 398          assign_capability('moodle/competency:coursecompetencymanage', CAP_PROHIBIT, $role, $sysctx->id);
 399          role_assign($role, $u->id, \context_course::instance($this->c1->id)->id);
 400          role_assign($role, $u->id, \context_module::instance($this->cms[$this->c2->id]['F1']->cmid)->id);
 401  
 402          accesslib_clear_all_caches_for_unit_testing();
 403          $this->setUser($u);
 404  
 405          // Do C1 first.
 406          $mapper = new framework_mapper($this->f1->get('id'), $this->f2->get('id'));
 407          $mapper->automap();
 408          $processor = new framework_processor($mapper);
 409          $processor->set_allowedcourses(array($this->c1->id));
 410          $processor->proceed();
 411  
 412          $this->assertEquals(1, $processor->get_courses_found_count());
 413          $this->assertEquals(3, $processor->get_expected_course_competency_migrations());
 414          $this->assertEquals(0, $processor->get_course_competency_migrations());
 415          $this->assertEquals(0, $processor->get_course_competency_removals());
 416  
 417          $this->assertEquals(2, $processor->get_cms_found_count());
 418          $this->assertEquals(3, $processor->get_expected_module_competency_migrations());
 419          $this->assertEquals(0, $processor->get_module_competency_migrations());
 420          $this->assertEquals(0, $processor->get_module_competency_removals());
 421  
 422          $this->assertEquals(array(), $processor->get_warnings());
 423          $errors = $processor->get_errors();
 424          $this->assertCount(2, $errors);
 425          $this->assertEquals($this->c1->id, $errors[0]['courseid']);
 426          $this->assertEquals($this->f1comps['A1']->get('id'), $errors[0]['competencyid']);
 427          $this->assertEquals(null, $errors[0]['cmid']);
 428          $this->assertMatchesRegularExpression('/Sorry, but you do not currently have permissions to do that/',
 429              $errors[0]['message']);
 430          $this->assertEquals($this->f1comps['A3']->get('id'), $errors[1]['competencyid']);
 431  
 432          $this->assertCourseCompetencyNotMigrated($this->c1, $this->f1comps['A1'], $this->f2comps['A1']);
 433          $this->assertCourseCompetencyNotMigrated($this->c1, $this->f1comps['A3'], $this->f2comps['A3']);
 434          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c1->id]['F1'], $this->f1comps['A1'], $this->f2comps['A1']);
 435          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c1->id]['P1'], $this->f1comps['A3'], $this->f2comps['A3']);
 436  
 437          // Do C2 now.
 438          $processor = new framework_processor($mapper);
 439          $processor->set_allowedcourses(array($this->c2->id));
 440          $processor->proceed();
 441  
 442          $this->assertEquals(1, $processor->get_courses_found_count());
 443          $this->assertEquals(2, $processor->get_expected_course_competency_migrations());
 444          $this->assertEquals(2, $processor->get_course_competency_migrations());
 445          $this->assertEquals(0, $processor->get_course_competency_removals());
 446  
 447          $this->assertEquals(1, $processor->get_cms_found_count());
 448          $this->assertEquals(2, $processor->get_expected_module_competency_migrations());
 449          $this->assertEquals(0, $processor->get_module_competency_migrations());
 450          $this->assertEquals(0, $processor->get_module_competency_removals());
 451  
 452          $this->assertEquals(array(), $processor->get_warnings());
 453          $errors = $processor->get_errors();
 454          $this->assertCount(2, $errors);
 455          $this->assertEquals($this->c2->id, $errors[0]['courseid']);
 456          $this->assertEquals($this->f1comps['A2']->get('id'), $errors[0]['competencyid']);
 457          $this->assertEquals($this->cms[$this->c2->id]['F1']->cmid, $errors[0]['cmid']);
 458          $this->assertMatchesRegularExpression('/Sorry, but you do not currently have permissions to do that/',
 459              $errors[0]['message']);
 460          $this->assertEquals($this->f1comps['A3']->get('id'), $errors[1]['competencyid']);
 461  
 462          // The new competencies were added to the course, but the old ones were not removed because they are still in modules.
 463          $this->assertCourseCompetencyExists($this->c2, $this->f1comps['A2']);
 464          $this->assertCourseCompetencyExists($this->c2, $this->f1comps['A3']);
 465          $this->assertCourseCompetencyExists($this->c2, $this->f2comps['A2']);
 466          $this->assertCourseCompetencyExists($this->c2, $this->f2comps['A3']);
 467  
 468          // Module competencies were not migrated because permissions are lacking.
 469          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A2'], $this->f2comps['A2']);
 470          $this->assertModuleCompetencyNotMigrated($this->cms[$this->c2->id]['F1'], $this->f1comps['A3'], $this->f2comps['A2']);
 471      }
 472  
 473      /**
 474       * Assert that the course competency exists.
 475       *
 476       * @param \stdClass $course The course.
 477       * @param competency $competency The competency.
 478       */
 479      protected function assertCourseCompetencyExists($course, $competency) {
 480          $this->assertTrue(course_competency::record_exists_select("courseid = :courseid AND competencyid = :competencyid",
 481              array('courseid' => $course->id, 'competencyid' => $competency->get('id'))));
 482      }
 483  
 484      /**
 485       * Assert that the course competency does not exist.
 486       *
 487       * @param \stdClass $course The course.
 488       * @param competency $competency The competency.
 489       */
 490      protected function assertCourseCompetencyNotExists($course, $competency) {
 491          $this->assertFalse(course_competency::record_exists_select("courseid = :courseid AND competencyid = :competencyid",
 492              array('courseid' => $course->id, 'competencyid' => $competency->get('id'))));
 493      }
 494  
 495      /**
 496       * Assert that the course competency was migrated.
 497       *
 498       * @param \stdClass $course The course.
 499       * @param competency $compfrom The competency from.
 500       * @param competency $compto The competency to.
 501       */
 502      protected function assertCourseCompetencyMigrated($course, $compfrom, $compto) {
 503          $ccs = $this->ccs[$course->id];
 504  
 505          $this->assertCourseCompetencyNotExists($course, $compfrom);
 506          $this->assertCourseCompetencyExists($course, $compto);
 507  
 508          $before = $ccs[$compfrom->get('id')];
 509          $after = course_competency::get_record(array(
 510              'courseid' => $course->id,
 511              'competencyid' => $compto->get('id')
 512          ));
 513  
 514          $this->assertNotEquals($before->get('id'), $after->get('id'));
 515          $this->assertEquals($before->get('courseid'), $after->get('courseid'));
 516          $this->assertEquals($before->get('sortorder'), $after->get('sortorder'));
 517          $this->assertEquals($before->get('ruleoutcome'), $after->get('ruleoutcome'));
 518      }
 519  
 520      /**
 521       * Assert that the course competency was not migrated.
 522       *
 523       * @param \stdClass $course The course.
 524       * @param competency $compfrom The competency from.
 525       * @param competency $compto The competency to.
 526       */
 527      protected function assertCourseCompetencyNotMigrated($course, $compfrom, $compto) {
 528          $ccs = $this->ccs[$course->id];
 529  
 530          $this->assertCourseCompetencyExists($course, $compfrom);
 531          $this->assertCourseCompetencyNotExists($course, $compto);
 532  
 533          $before = $ccs[$compfrom->get('id')];
 534          $after = $ccs[$compfrom->get('id')];
 535  
 536          $this->assertEquals($before->get('id'), $after->get('id'));
 537          $this->assertEquals($before->get('courseid'), $after->get('courseid'));
 538          $this->assertEquals($before->get('sortorder'), $after->get('sortorder'));
 539          $this->assertEquals($before->get('ruleoutcome'), $after->get('ruleoutcome'));
 540      }
 541  
 542      /**
 543       * Assert that the course module competency exists.
 544       *
 545       * @param \stdClass $cm The CM.
 546       * @param competency $competency The competency.
 547       */
 548      protected function assertModuleCompetencyExists($cm, $competency) {
 549          $this->assertTrue(course_module_competency::record_exists_select("cmid = :cmid AND competencyid = :competencyid",
 550              array('cmid' => $cm->cmid, 'competencyid' => $competency->get('id'))));
 551      }
 552  
 553      /**
 554       * Assert that the course module competency does not exist.
 555       *
 556       * @param \stdClass $cm The CM.
 557       * @param competency $competency The competency.
 558       */
 559      protected function assertModuleCompetencyNotExists($cm, $competency) {
 560          $this->assertFalse(course_module_competency::record_exists_select("cmid = :cmid AND competencyid = :competencyid",
 561              array('cmid' => $cm->cmid, 'competencyid' => $competency->get('id'))));
 562      }
 563  
 564      /**
 565       * Assert that the course module competency was migrated.
 566       *
 567       * @param \stdClass $cm The CM.
 568       * @param competency $compfrom The competency from.
 569       * @param competency $compto The competency to.
 570       */
 571      protected function assertModuleCompetencyMigrated($cm, $compfrom, $compto) {
 572          $cmcs = $this->cmcs[$cm->cmid];
 573  
 574          $this->assertModuleCompetencyNotExists($cm, $compfrom);
 575          $this->assertModuleCompetencyExists($cm, $compto);
 576  
 577          $before = $cmcs[$compfrom->get('id')];
 578          $after = course_module_competency::get_record(array(
 579              'cmid' => $cm->cmid,
 580              'competencyid' => $compto->get('id')
 581          ));
 582  
 583          $this->assertNotEquals($before->get('id'), $after->get('id'));
 584          $this->assertEquals($before->get('cmid'), $after->get('cmid'));
 585          $this->assertEquals($before->get('sortorder'), $after->get('sortorder'));
 586          $this->assertEquals($before->get('ruleoutcome'), $after->get('ruleoutcome'));
 587      }
 588  
 589      /**
 590       * Assert that the course module competency was not migrated.
 591       *
 592       * @param \stdClass $cm The CM.
 593       * @param competency $compfrom The competency from.
 594       * @param competency $compto The competency to.
 595       */
 596      protected function assertModuleCompetencyNotMigrated($cm, $compfrom, $compto) {
 597          $cmcs = $this->cmcs[$cm->cmid];
 598  
 599          $this->assertModuleCompetencyExists($cm, $compfrom);
 600          $this->assertModuleCompetencyNotExists($cm, $compto);
 601  
 602          $before = $cmcs[$compfrom->get('id')];
 603          $after = $cmcs[$compfrom->get('id')];
 604  
 605          $this->assertEquals($before->get('id'), $after->get('id'));
 606          $this->assertEquals($before->get('cmid'), $after->get('cmid'));
 607          $this->assertEquals($before->get('sortorder'), $after->get('sortorder'));
 608          $this->assertEquals($before->get('ruleoutcome'), $after->get('ruleoutcome'));
 609      }
 610  }