[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * API tests. 19 * 20 * @package core_competency 21 * @copyright 2015 Frédéric Massart - FMCorz.net 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 global $CFG; 27 28 use core_competency\api; 29 use core_competency\competency; 30 use core_competency\competency_framework; 31 use core_competency\course_competency_settings; 32 use core_competency\evidence; 33 use core_competency\user_competency; 34 use core_competency\plan; 35 36 /** 37 * API tests. 38 * 39 * @package core_competency 40 * @copyright 2015 Frédéric Massart - FMCorz.net 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 class core_competency_api_testcase extends advanced_testcase { 44 45 public function test_get_framework_related_contexts() { 46 $this->resetAfterTest(true); 47 $dg = $this->getDataGenerator(); 48 $cat1 = $dg->create_category(); 49 $cat2 = $dg->create_category(array('parent' => $cat1->id)); 50 $cat3 = $dg->create_category(array('parent' => $cat2->id)); 51 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned. 52 53 $cat1ctx = context_coursecat::instance($cat1->id); 54 $cat2ctx = context_coursecat::instance($cat2->id); 55 $cat3ctx = context_coursecat::instance($cat3->id); 56 $sysctx = context_system::instance(); 57 58 $expected = array($cat1ctx->id => $cat1ctx); 59 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self')); 60 61 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx); 62 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children')); 63 64 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx); 65 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents')); 66 } 67 68 public function test_get_framework_related_contexts_with_capabilities() { 69 $this->resetAfterTest(true); 70 $dg = $this->getDataGenerator(); 71 $user = $dg->create_user(); 72 $cat1 = $dg->create_category(); 73 $cat2 = $dg->create_category(array('parent' => $cat1->id)); 74 $cat3 = $dg->create_category(array('parent' => $cat2->id)); 75 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned. 76 77 $cat1ctx = context_coursecat::instance($cat1->id); 78 $cat2ctx = context_coursecat::instance($cat2->id); 79 $cat3ctx = context_coursecat::instance($cat3->id); 80 $sysctx = context_system::instance(); 81 82 $roleallow = create_role('Allow', 'allow', 'Allow read'); 83 assign_capability('moodle/competency:competencyview', CAP_ALLOW, $roleallow, $sysctx->id); 84 role_assign($roleallow, $user->id, $sysctx->id); 85 86 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read'); 87 assign_capability('moodle/competency:competencyview', CAP_PROHIBIT, $roleprevent, $sysctx->id); 88 role_assign($roleprevent, $user->id, $cat2ctx->id); 89 90 accesslib_clear_all_caches_for_unit_testing(); 91 $this->setUser($user); 92 $this->assertFalse(has_capability('moodle/competency:competencyview', $cat2ctx)); 93 94 $requiredcap = array('moodle/competency:competencyview'); 95 96 $expected = array(); 97 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap)); 98 99 $expected = array($cat1ctx->id => $cat1ctx); 100 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap)); 101 102 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx); 103 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap)); 104 } 105 106 public function test_get_template_related_contexts() { 107 $this->resetAfterTest(true); 108 $dg = $this->getDataGenerator(); 109 $cat1 = $dg->create_category(); 110 $cat2 = $dg->create_category(array('parent' => $cat1->id)); 111 $cat3 = $dg->create_category(array('parent' => $cat2->id)); 112 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned. 113 114 $cat1ctx = context_coursecat::instance($cat1->id); 115 $cat2ctx = context_coursecat::instance($cat2->id); 116 $cat3ctx = context_coursecat::instance($cat3->id); 117 $sysctx = context_system::instance(); 118 119 $expected = array($cat1ctx->id => $cat1ctx); 120 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self')); 121 122 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx); 123 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children')); 124 125 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx); 126 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents')); 127 } 128 129 public function test_get_template_related_contexts_with_capabilities() { 130 $this->resetAfterTest(true); 131 $dg = $this->getDataGenerator(); 132 $user = $dg->create_user(); 133 $cat1 = $dg->create_category(); 134 $cat2 = $dg->create_category(array('parent' => $cat1->id)); 135 $cat3 = $dg->create_category(array('parent' => $cat2->id)); 136 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned. 137 138 $cat1ctx = context_coursecat::instance($cat1->id); 139 $cat2ctx = context_coursecat::instance($cat2->id); 140 $cat3ctx = context_coursecat::instance($cat3->id); 141 $sysctx = context_system::instance(); 142 143 $roleallow = create_role('Allow', 'allow', 'Allow read'); 144 assign_capability('moodle/competency:templateview', CAP_ALLOW, $roleallow, $sysctx->id); 145 role_assign($roleallow, $user->id, $sysctx->id); 146 147 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read'); 148 assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $roleprevent, $sysctx->id); 149 role_assign($roleprevent, $user->id, $cat2ctx->id); 150 151 accesslib_clear_all_caches_for_unit_testing(); 152 $this->setUser($user); 153 $this->assertFalse(has_capability('moodle/competency:templateview', $cat2ctx)); 154 155 $requiredcap = array('moodle/competency:templateview'); 156 157 $expected = array(); 158 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap)); 159 160 $expected = array($cat1ctx->id => $cat1ctx); 161 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap)); 162 163 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx); 164 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap)); 165 } 166 167 /** 168 * Test updating a template. 169 * 170 * @expectedException coding_exception 171 */ 172 public function test_update_template() { 173 $cat = $this->getDataGenerator()->create_category(); 174 $this->resetAfterTest(true); 175 $this->setAdminUser(); 176 177 $syscontext = context_system::instance(); 178 $template = api::create_template((object) array('shortname' => 'testing', 'contextid' => $syscontext->id)); 179 180 $this->assertEquals('testing', $template->get_shortname()); 181 $this->assertEquals($syscontext->id, $template->get_contextid()); 182 183 // Simple update. 184 api::update_template((object) array('id' => $template->get_id(), 'shortname' => 'success')); 185 $template = api::read_template($template->get_id()); 186 $this->assertEquals('success', $template->get_shortname()); 187 188 // Trying to change the context. 189 api::update_template((object) array('id' => $template->get_id(), 'contextid' => context_coursecat::instance($cat->id))); 190 } 191 192 /** 193 * Test listing framework with order param. 194 */ 195 public function test_list_frameworks() { 196 $this->resetAfterTest(true); 197 $this->setAdminUser(); 198 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 199 200 // Create a list of frameworks. 201 $framework1 = $lpg->create_framework(array( 202 'shortname' => 'shortname_alpha', 203 'idnumber' => 'idnumber_cinnamon', 204 'description' => 'description', 205 'descriptionformat' => FORMAT_HTML, 206 'visible' => true, 207 'contextid' => context_system::instance()->id 208 )); 209 210 $framework2 = $lpg->create_framework(array( 211 'shortname' => 'shortname_beetroot', 212 'idnumber' => 'idnumber_apple', 213 'description' => 'description', 214 'descriptionformat' => FORMAT_HTML, 215 'visible' => true, 216 'contextid' => context_system::instance()->id 217 )); 218 219 $framework3 = $lpg->create_framework(array( 220 'shortname' => 'shortname_crisps', 221 'idnumber' => 'idnumber_beer', 222 'description' => 'description', 223 'descriptionformat' => FORMAT_HTML, 224 'visible' => false, 225 'contextid' => context_system::instance()->id 226 )); 227 228 // Get frameworks list order by shortname desc. 229 $result = api::list_frameworks('shortname', 'DESC', null, 3, context_system::instance()); 230 231 $f = (object) array_shift($result); 232 $this->assertEquals($framework3->get_id(), $f->get_id()); 233 $f = (object) array_shift($result); 234 $this->assertEquals($framework2->get_id(), $f->get_id()); 235 $f = (object) array_shift($result); 236 $this->assertEquals($framework1->get_id(), $f->get_id()); 237 238 // Get frameworks list order by idnumber asc. 239 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance()); 240 241 $f = (object) array_shift($result); 242 $this->assertEquals($framework2->get_id(), $f->get_id()); 243 $f = (object) array_shift($result); 244 $this->assertEquals($framework3->get_id(), $f->get_id()); 245 $f = (object) array_shift($result); 246 $this->assertEquals($framework1->get_id(), $f->get_id()); 247 248 // Repeat excluding the non-visible ones. 249 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance(), 'self', true); 250 $this->assertCount(2, $result); 251 $f = (object) array_shift($result); 252 $this->assertEquals($framework2->get_id(), $f->get_id()); 253 $f = (object) array_shift($result); 254 $this->assertEquals($framework1->get_id(), $f->get_id()); 255 256 // Search by query string, trying match on shortname. 257 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance(), 'self', false, 'crisp'); 258 $this->assertCount(1, $result); 259 $f = (object) array_shift($result); 260 $this->assertEquals($framework3->get_id(), $f->get_id()); 261 262 // Search by query string, trying match on shortname, but hidden. 263 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance(), 'self', true, 'crisp'); 264 $this->assertCount(0, $result); 265 266 // Search by query string, trying match on ID number. 267 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance(), 'self', false, 'apple'); 268 $this->assertCount(1, $result); 269 $f = (object) array_shift($result); 270 $this->assertEquals($framework2->get_id(), $f->get_id()); 271 272 // Search by query string, trying match on both. 273 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance(), 'self', false, 'bee'); 274 $this->assertCount(2, $result); 275 $f = (object) array_shift($result); 276 $this->assertEquals($framework2->get_id(), $f->get_id()); 277 $f = (object) array_shift($result); 278 $this->assertEquals($framework3->get_id(), $f->get_id()); 279 } 280 281 /** 282 * Test duplicate a framework. 283 */ 284 public function test_duplicate_framework() { 285 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 286 $this->resetAfterTest(true); 287 $this->setAdminUser(); 288 289 $syscontext = context_system::instance(); 290 $params = array( 291 'shortname' => 'shortname_a', 292 'idnumber' => 'idnumber_c', 293 'description' => 'description', 294 'descriptionformat' => FORMAT_HTML, 295 'visible' => true, 296 'contextid' => $syscontext->id 297 ); 298 $framework = $lpg->create_framework($params); 299 $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 300 $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 301 $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 302 $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 303 $competency41 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 304 'parentid' => $competency4->get_id()) 305 ); 306 $competency42 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 307 'parentid' => $competency4->get_id()) 308 ); 309 $competencyidnumbers = array($competency1->get_idnumber(), 310 $competency2->get_idnumber(), 311 $competency3->get_idnumber(), 312 $competency4->get_idnumber(), 313 $competency41->get_idnumber(), 314 $competency42->get_idnumber() 315 ); 316 317 $config = json_encode(array( 318 'base' => array('points' => 4), 319 'competencies' => array( 320 array('id' => $competency41->get_id(), 'points' => 3, 'required' => 0), 321 array('id' => $competency42->get_id(), 'points' => 2, 'required' => 1), 322 ) 323 )); 324 $competency4->set_ruletype('core_competency\competency_rule_points'); 325 $competency4->set_ruleoutcome(\core_competency\competency::OUTCOME_EVIDENCE); 326 $competency4->set_ruleconfig($config); 327 $competency4->update(); 328 329 api::add_related_competency($competency1->get_id(), $competency2->get_id()); 330 api::add_related_competency($competency3->get_id(), $competency4->get_id()); 331 332 $frameworkduplicated1 = api::duplicate_framework($framework->get_id()); 333 $frameworkduplicated2 = api::duplicate_framework($framework->get_id()); 334 335 $this->assertEquals($framework->get_idnumber().'_1', $frameworkduplicated1->get_idnumber()); 336 $this->assertEquals($framework->get_idnumber().'_2', $frameworkduplicated2->get_idnumber()); 337 338 $competenciesfr1 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated1->get_id())); 339 $competenciesfr2 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated2->get_id())); 340 341 $competencyidsfr1 = array(); 342 $competencyidsfr2 = array(); 343 344 foreach ($competenciesfr1 as $cmp) { 345 $competencyidsfr1[] = $cmp->get_idnumber(); 346 } 347 foreach ($competenciesfr2 as $cmp) { 348 $competencyidsfr2[] = $cmp->get_idnumber(); 349 } 350 351 $this->assertEmpty(array_diff($competencyidsfr1, $competencyidnumbers)); 352 $this->assertEmpty(array_diff($competencyidsfr2, $competencyidnumbers)); 353 $this->assertCount(6, $competenciesfr1); 354 $this->assertCount(6, $competenciesfr2); 355 356 // Test the related competencies. 357 reset($competenciesfr1); 358 $compduplicated1 = current($competenciesfr1); 359 $relatedcompetencies = $compduplicated1->get_related_competencies(); 360 $comprelated = current($relatedcompetencies); 361 $this->assertEquals($comprelated->get_idnumber(), $competency2->get_idnumber()); 362 363 // Check if config rule have been ported correctly. 364 $competency4duplicated = competency::get_record(array( 365 'idnumber' => $competency4->get_idnumber(), 366 'competencyframeworkid' => $frameworkduplicated2->get_id() 367 )); 368 $configduplicated = json_decode($competency4duplicated->get_ruleconfig(), true); 369 $configorigin = json_decode($config, true); 370 // Check that the 2 config have the same base. 371 $this->assertEquals($configorigin['base'], $configduplicated['base']); 372 $this->assertEquals(count($configorigin['competencies']), count($configduplicated['competencies'])); 373 $competencyidsrules = array(); 374 foreach ($configduplicated['competencies'] as $key => $value) { 375 // Check that the only difference between the 2 config is id competency. 376 $this->assertEquals(1, count(array_diff($value, $configorigin['competencies'][$key]))); 377 $competencyidsrules[] = $value['id']; 378 } 379 $this->assertTrue($competency4duplicated->is_parent_of($competencyidsrules)); 380 381 // Test duplicate an empty framework. 382 $emptyfrm = $lpg->create_framework(); 383 $emptyfrmduplicated = api::duplicate_framework($emptyfrm->get_id()); 384 $this->assertEquals($emptyfrm->get_idnumber().'_1', $emptyfrmduplicated->get_idnumber()); 385 $nbcomp = api::count_competencies(array('competencyframeworkid' => $emptyfrmduplicated->get_id())); 386 $this->assertEquals(0, $nbcomp); 387 388 } 389 390 /** 391 * Test update plan. 392 */ 393 public function test_update_plan() { 394 $this->resetAfterTest(true); 395 $dg = $this->getDataGenerator(); 396 $usermanageowndraft = $dg->create_user(); 397 $usermanageown = $dg->create_user(); 398 $usermanagedraft = $dg->create_user(); 399 $usermanage = $dg->create_user(); 400 401 $syscontext = context_system::instance(); 402 403 // Creating specific roles. 404 $manageowndraftrole = $dg->create_role(array( 405 'name' => 'User manage own draft', 406 'shortname' => 'manage-own-draft' 407 )); 408 $manageownrole = $dg->create_role(array( 409 'name' => 'User manage own', 410 'shortname' => 'manage-own' 411 )); 412 $managedraftrole = $dg->create_role(array( 413 'name' => 'User manage draft', 414 'shortname' => 'manage-draft' 415 )); 416 $managerole = $dg->create_role(array( 417 'name' => 'User manage', 418 'shortname' => 'manage' 419 )); 420 421 assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id); 422 assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id); 423 424 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id); 425 assign_capability('moodle/competency:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id); 426 427 assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $managedraftrole, $syscontext->id); 428 assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $managedraftrole, $syscontext->id); 429 430 assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id); 431 assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id); 432 433 $dg->role_assign($manageowndraftrole, $usermanageowndraft->id, $syscontext->id); 434 $dg->role_assign($manageownrole, $usermanageown->id, $syscontext->id); 435 $dg->role_assign($managedraftrole, $usermanagedraft->id, $syscontext->id); 436 $dg->role_assign($managerole, $usermanage->id, $syscontext->id); 437 438 // Create first learning plan with user create draft. 439 $this->setUser($usermanageowndraft); 440 $plan = array ( 441 'name' => 'plan own draft', 442 'description' => 'plan own draft', 443 'userid' => $usermanageowndraft->id 444 ); 445 $plan = api::create_plan((object)$plan); 446 $record = $plan->to_record(); 447 $record->name = 'plan own draft modified'; 448 449 // Check if user create draft can edit the plan name. 450 $plan = api::update_plan($record); 451 $this->assertInstanceOf('\core_competency\plan', $plan); 452 453 // The status cannot be changed in this method. 454 $record->status = \core_competency\plan::STATUS_ACTIVE; 455 try { 456 $plan = api::update_plan($record); 457 $this->fail('Updating the status is not allowed.'); 458 } catch (coding_exception $e) { 459 $this->assertRegExp('/To change the status of a plan use the appropriate methods./', $e->getMessage()); 460 } 461 462 // Test when user with manage own plan capability try to edit other user plan. 463 $record->status = \core_competency\plan::STATUS_DRAFT; 464 $record->name = 'plan create draft modified 2'; 465 $this->setUser($usermanageown); 466 try { 467 $plan = api::update_plan($record); 468 $this->fail('User with manage own plan capability can only edit his own plan.'); 469 } catch (required_capability_exception $e) { 470 $this->assertTrue(true); 471 } 472 473 // User with manage plan capability cannot edit the other user plans with status draft. 474 $this->setUser($usermanage); 475 $record->name = 'plan create draft modified 3'; 476 try { 477 $plan = api::update_plan($record); 478 $this->fail('User with manage plan capability cannot edit the other user plans with status draft'); 479 } catch (required_capability_exception $e) { 480 $this->assertTrue(true); 481 } 482 483 // User with manage draft capability can edit other user's learning plan if the status is draft. 484 $this->setUser($usermanagedraft); 485 $record->status = \core_competency\plan::STATUS_DRAFT; 486 $record->name = 'plan manage draft modified 3'; 487 $plan = api::update_plan($record); 488 $this->assertInstanceOf('\core_competency\plan', $plan); 489 490 // User with manage plan capability can create/edit learning plan if status is active/complete. 491 $this->setUser($usermanage); 492 $plan = array ( 493 'name' => 'plan create', 494 'description' => 'plan create', 495 'userid' => $usermanage->id, 496 'status' => \core_competency\plan::STATUS_ACTIVE 497 ); 498 $plan = api::create_plan((object)$plan); 499 500 // Silently transition to complete status to avoid errors about transitioning to complete. 501 $plan->set_status(\core_competency\plan::STATUS_COMPLETE); 502 $plan->update(); 503 504 $record = $plan->to_record(); 505 $record->name = 'plan create own modified'; 506 try { 507 api::update_plan($record); 508 $this->fail('Completed plan can not be edited'); 509 } catch (coding_exception $e) { 510 $this->assertTrue(true); 511 } 512 } 513 514 /** 515 * @expectedException coding_exception 516 */ 517 public function test_create_plan_from_template() { 518 $this->resetAfterTest(true); 519 $this->setAdminUser(); 520 521 $u1 = $this->getDataGenerator()->create_user(); 522 $tpl = $this->getDataGenerator()->get_plugin_generator('core_competency')->create_template(); 523 524 // Creating a new plan. 525 $plan = api::create_plan_from_template($tpl, $u1->id); 526 $record = $plan->to_record(); 527 $this->assertInstanceOf('\core_competency\plan', $plan); 528 $this->assertTrue(\core_competency\plan::record_exists($plan->get_id())); 529 $this->assertEquals($tpl->get_id(), $plan->get_templateid()); 530 $this->assertEquals($u1->id, $plan->get_userid()); 531 $this->assertTrue($plan->is_based_on_template()); 532 533 // Creating a plan that already exists. 534 $plan = api::create_plan_from_template($tpl, $u1->id); 535 $this->assertFalse($plan); 536 537 // Check that api::create_plan cannot be used. 538 unset($record->id); 539 $plan = api::create_plan($record); 540 } 541 542 public function test_update_plan_based_on_template() { 543 $this->resetAfterTest(true); 544 $dg = $this->getDataGenerator(); 545 $lpg = $dg->get_plugin_generator('core_competency'); 546 $u1 = $dg->create_user(); 547 $u2 = $dg->create_user(); 548 549 $this->setAdminUser(); 550 $tpl1 = $lpg->create_template(); 551 $tpl2 = $lpg->create_template(); 552 $up1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id())); 553 $up2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => null)); 554 555 try { 556 // Trying to remove the template dependency. 557 $record = $up1->to_record(); 558 $record->templateid = null; 559 api::update_plan($record); 560 $this->fail('A plan cannot be unlinked using api::update_plan()'); 561 } catch (coding_exception $e) { 562 // All good. 563 } 564 565 try { 566 // Trying to switch to another template. 567 $record = $up1->to_record(); 568 $record->templateid = $tpl2->get_id(); 569 api::update_plan($record); 570 $this->fail('A plan cannot be moved to another template.'); 571 } catch (coding_exception $e) { 572 // All good. 573 } 574 575 try { 576 // Trying to switch to using a template. 577 $record = $up2->to_record(); 578 $record->templateid = $tpl1->get_id(); 579 api::update_plan($record); 580 $this->fail('A plan cannot be update to use a template.'); 581 } catch (coding_exception $e) { 582 // All good. 583 } 584 } 585 586 public function test_unlink_plan_from_template() { 587 $this->resetAfterTest(true); 588 $dg = $this->getDataGenerator(); 589 $lpg = $dg->get_plugin_generator('core_competency'); 590 $u1 = $dg->create_user(); 591 $u2 = $dg->create_user(); 592 593 $this->setAdminUser(); 594 $f1 = $lpg->create_framework(); 595 $f2 = $lpg->create_framework(); 596 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 597 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id())); 598 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 599 600 $tpl1 = $lpg->create_template(); 601 $tpl2 = $lpg->create_template(); 602 603 $tplc1a = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1a->get_id(), 604 'sortorder' => 9)); 605 $tplc1b = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1b->get_id(), 606 'sortorder' => 8)); 607 $tplc2a = $lpg->create_template_competency(array('templateid' => $tpl2->get_id(), 'competencyid' => $c2a->get_id())); 608 609 $plan1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_ACTIVE)); 610 $plan2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => $tpl2->get_id())); 611 $plan3 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_COMPLETE)); 612 613 // Check that we have what we expect at this stage. 614 $this->assertEquals(2, \core_competency\template_competency::count_records(array('templateid' => $tpl1->get_id()))); 615 $this->assertEquals(1, \core_competency\template_competency::count_records(array('templateid' => $tpl2->get_id()))); 616 $this->assertEquals(0, \core_competency\plan_competency::count_records(array('planid' => $plan1->get_id()))); 617 $this->assertEquals(0, \core_competency\plan_competency::count_records(array('planid' => $plan2->get_id()))); 618 $this->assertTrue($plan1->is_based_on_template()); 619 $this->assertTrue($plan2->is_based_on_template()); 620 621 // Let's do this! 622 $tpl1comps = \core_competency\template_competency::list_competencies($tpl1->get_id(), true); 623 $tpl2comps = \core_competency\template_competency::list_competencies($tpl2->get_id(), true); 624 625 api::unlink_plan_from_template($plan1); 626 627 $plan1->read(); 628 $plan2->read(); 629 $this->assertCount(2, $tpl1comps); 630 $this->assertCount(1, $tpl2comps); 631 $this->assertEquals(2, \core_competency\template_competency::count_records(array('templateid' => $tpl1->get_id()))); 632 $this->assertEquals(1, \core_competency\template_competency::count_records(array('templateid' => $tpl2->get_id()))); 633 $this->assertEquals(2, \core_competency\plan_competency::count_records(array('planid' => $plan1->get_id()))); 634 $this->assertEquals(0, \core_competency\plan_competency::count_records(array('planid' => $plan2->get_id()))); 635 $this->assertFalse($plan1->is_based_on_template()); 636 $this->assertEquals($tpl1->get_id(), $plan1->get_origtemplateid()); 637 $this->assertTrue($plan2->is_based_on_template()); 638 $this->assertEquals(null, $plan2->get_origtemplateid()); 639 640 // Check we can unlink draft plan. 641 try { 642 api::unlink_plan_from_template($plan2); 643 } catch (coding_exception $e) { 644 $this->fail('Fail to unlink draft plan.'); 645 } 646 647 // Check we can not unlink completed plan. 648 try { 649 api::unlink_plan_from_template($plan3); 650 $this->fail('We can not unlink completed plan.'); 651 } catch (coding_exception $e) { 652 // All good. 653 } 654 655 // Even the order remains. 656 $plan1comps = \core_competency\plan_competency::list_competencies($plan1->get_id()); 657 $before = reset($tpl1comps); 658 $after = reset($plan1comps); 659 $this->assertEquals($before->get_id(), $after->get_id()); 660 $this->assertEquals($before->get_sortorder(), $after->get_sortorder()); 661 $before = next($tpl1comps); 662 $after = next($plan1comps); 663 $this->assertEquals($before->get_id(), $after->get_id()); 664 $this->assertEquals($before->get_sortorder(), $after->get_sortorder()); 665 } 666 667 public function test_update_template_updates_plans() { 668 $this->resetAfterTest(true); 669 $this->setAdminUser(); 670 671 $dg = $this->getDataGenerator(); 672 $u1 = $dg->create_user(); 673 $u2 = $dg->create_user(); 674 $lpg = $dg->get_plugin_generator('core_competency'); 675 $tpl1 = $lpg->create_template(); 676 $tpl2 = $lpg->create_template(); 677 678 // Create plans with data not matching templates. 679 $time = time(); 680 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u1->id, 681 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_MARKDOWN)); 682 $plan2 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u2->id, 683 'name' => 'Not right name', 'duedate' => $time + 3601, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN)); 684 $plan3 = $lpg->create_plan(array('templateid' => $tpl2->get_id(), 'userid' => $u1->id, 685 'name' => 'Not sweet name', 'duedate' => $time + 3602, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN)); 686 687 // Prepare our expectations. 688 $plan1->read(); 689 $plan2->read(); 690 $plan3->read(); 691 692 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid()); 693 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid()); 694 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid()); 695 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name()); 696 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name()); 697 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name()); 698 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description()); 699 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description()); 700 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description()); 701 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat()); 702 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat()); 703 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat()); 704 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate()); 705 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate()); 706 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate()); 707 708 // Update the template without changing critical fields does not update the plans. 709 $data = $tpl1->to_record(); 710 $data->visible = 0; 711 api::update_template($data); 712 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name()); 713 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name()); 714 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name()); 715 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description()); 716 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description()); 717 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description()); 718 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat()); 719 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat()); 720 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat()); 721 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate()); 722 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate()); 723 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate()); 724 725 // Now really update the template. 726 $data = $tpl1->to_record(); 727 $data->shortname = 'Awesome!'; 728 $data->description = 'This is too awesome!'; 729 $data->descriptionformat = FORMAT_HTML; 730 $data->duedate = $time + 200; 731 api::update_template($data); 732 $tpl1->read(); 733 734 // Now confirm that the right plans were updated. 735 $plan1->read(); 736 $plan2->read(); 737 $plan3->read(); 738 739 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid()); 740 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid()); 741 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid()); 742 743 $this->assertEquals($tpl1->get_shortname(), $plan1->get_name()); 744 $this->assertEquals($tpl1->get_shortname(), $plan2->get_name()); 745 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name()); 746 $this->assertEquals($tpl1->get_description(), $plan1->get_description()); 747 $this->assertEquals($tpl1->get_description(), $plan2->get_description()); 748 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description()); 749 $this->assertEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat()); 750 $this->assertEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat()); 751 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat()); 752 $this->assertEquals($tpl1->get_duedate(), $plan1->get_duedate()); 753 $this->assertEquals($tpl1->get_duedate(), $plan2->get_duedate()); 754 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate()); 755 } 756 757 /** 758 * Test that the method to complete a plan. 759 * 760 * @expectedException coding_exception 761 */ 762 public function test_complete_plan() { 763 global $DB; 764 765 $this->resetAfterTest(true); 766 $this->setAdminUser(); 767 $dg = $this->getDataGenerator(); 768 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 769 $user = $dg->create_user(); 770 771 // Create a framework and assign competencies. 772 $framework = $lpg->create_framework(); 773 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 774 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 775 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 776 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 777 778 // Create two plans and assign competencies. 779 $plan = $lpg->create_plan(array('userid' => $user->id)); 780 $otherplan = $lpg->create_plan(array('userid' => $user->id)); 781 782 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id())); 783 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id())); 784 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id())); 785 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id())); 786 787 $uclist = array( 788 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id(), 789 'proficiency' => true, 'grade' => 1 )), 790 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id(), 791 'proficiency' => false, 'grade' => 2 )) 792 ); 793 794 $this->assertEquals(2, \core_competency\user_competency::count_records()); 795 $this->assertEquals(0, \core_competency\user_competency_plan::count_records()); 796 797 // Change status of the plan to complete. 798 api::complete_plan($plan); 799 800 // Check that user competencies are now in user_competency_plan objects and still in user_competency. 801 $this->assertEquals(2, \core_competency\user_competency::count_records()); 802 $this->assertEquals(3, \core_competency\user_competency_plan::count_records()); 803 804 $usercompetenciesplan = \core_competency\user_competency_plan::get_records(); 805 806 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid()); 807 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid()); 808 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency()); 809 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade()); 810 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid()); 811 812 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid()); 813 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid()); 814 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency()); 815 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade()); 816 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid()); 817 818 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid()); 819 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid()); 820 $this->assertNull($usercompetenciesplan[2]->get_proficiency()); 821 $this->assertNull($usercompetenciesplan[2]->get_grade()); 822 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid()); 823 824 // Check we can not add competency to completed plan. 825 try { 826 api::add_competency_to_plan($plan->get_id(), $c4->get_id()); 827 $this->fail('We can not add competency to completed plan.'); 828 } catch (coding_exception $e) { 829 // All good. 830 } 831 832 // Check we can not remove competency to completed plan. 833 try { 834 api::remove_competency_from_plan($plan->get_id(), $c3->get_id()); 835 $this->fail('We can not remove competency to completed plan.'); 836 } catch (coding_exception $e) { 837 // All good. 838 } 839 840 // Completing a plan that is completed throws an exception. 841 api::complete_plan($plan); 842 } 843 844 /** 845 * Set-up the workflow data (review, active, ...). 846 * 847 * @return array 848 */ 849 protected function setup_workflow_data() { 850 $this->resetAfterTest(); 851 852 $dg = $this->getDataGenerator(); 853 $user = $dg->create_user(); 854 $reviewer = $dg->create_user(); 855 $otheruser = $dg->create_user(); 856 857 $syscontext = context_system::instance(); 858 $userrole = $dg->create_role(); 859 $reviewerrole = $dg->create_role(); 860 $otheruserrole = $dg->create_role(); 861 862 assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $userrole, $syscontext->id); 863 assign_capability('moodle/competency:planmanage', CAP_ALLOW, $reviewerrole, $syscontext->id); 864 assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $reviewerrole, $syscontext->id); 865 $dg->role_assign($userrole, $user->id, $syscontext->id); 866 $dg->role_assign($reviewerrole, $reviewer->id, $syscontext->id); 867 accesslib_clear_all_caches_for_unit_testing(); 868 869 $lpg = $dg->get_plugin_generator('core_competency'); 870 $tpl = $lpg->create_template(); 871 $plan = $lpg->create_plan(array('userid' => $user->id)); 872 $tplplan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tpl->get_id())); 873 874 return array( 875 'dg' => $dg, 876 'lpg' => $lpg, 877 'user' => $user, 878 'reviewer' => $reviewer, 879 'otheruser' => $otheruser, 880 'plan' => $plan, 881 'tplplan' => $tplplan, 882 ); 883 } 884 885 /** 886 * Testing requesting the review of a plan. 887 */ 888 public function test_plan_request_review() { 889 $data = $this->setup_workflow_data(); 890 $dg = $data['dg']; 891 $lpg = $data['lpg']; 892 $user = $data['user']; 893 $reviewer = $data['reviewer']; 894 $otheruser = $data['otheruser']; 895 $plan = $data['plan']; 896 $tplplan = $data['tplplan']; 897 898 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 899 $this->assertEquals(plan::STATUS_DRAFT, $tplplan->get_status()); 900 901 // Foreign user cannot do anything. 902 $this->setUser($otheruser); 903 try { 904 api::plan_request_review($plan); 905 $this->fail('The user can not read the plan.'); 906 } catch (required_capability_exception $e) { 907 $this->assertEquals('nopermissions', $e->errorcode); 908 } 909 910 // Can not change a plan based on a template. 911 $this->setUser($user); 912 try { 913 api::plan_request_review($tplplan); 914 $this->fail('The plan is based on a template.'); 915 } catch (coding_exception $e) { 916 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage()); 917 } 918 919 // Can not send for review when not draft. 920 $this->setUser($user); 921 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 922 try { 923 api::plan_request_review($plan); 924 $this->fail('The plan cannot be sent for review at this stage.'); 925 } catch (coding_exception $e) { 926 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage()); 927 } 928 929 // Can not send for review when not draft. 930 $this->setUser($user); 931 $plan->set_status(plan::STATUS_ACTIVE); 932 try { 933 api::plan_request_review($plan); 934 $this->fail('The plan cannot be sent for review at this stage.'); 935 } catch (coding_exception $e) { 936 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage()); 937 } 938 939 // Can not send for review when not draft. 940 $this->setUser($user); 941 $plan->set_status(plan::STATUS_IN_REVIEW); 942 try { 943 api::plan_request_review($plan); 944 $this->fail('The plan cannot be sent for review at this stage.'); 945 } catch (coding_exception $e) { 946 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage()); 947 } 948 949 // Can not send for review when not draft. 950 $this->setUser($user); 951 $plan->set_status(plan::STATUS_COMPLETE); 952 try { 953 api::plan_request_review($plan); 954 $this->fail('The plan cannot be sent for review at this stage.'); 955 } catch (coding_exception $e) { 956 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage()); 957 } 958 959 // Sending for review as a reviewer. 960 $this->setUser($reviewer); 961 $plan->set_status(plan::STATUS_DRAFT); 962 try { 963 api::plan_request_review($plan); 964 $this->fail('The user can not request a review.'); 965 } catch (required_capability_exception $e) { 966 $this->assertEquals('nopermissions', $e->errorcode); 967 } 968 969 // Sending for review. 970 $this->setUser($user); 971 api::plan_request_review($plan); 972 $plan->read(); 973 $this->assertEquals(plan::STATUS_WAITING_FOR_REVIEW, $plan->get_status()); 974 975 // Sending for review by ID. 976 $plan->set_status(plan::STATUS_DRAFT); 977 $plan->update(); 978 api::plan_request_review($plan->get_id()); 979 $plan->read(); 980 $this->assertEquals(plan::STATUS_WAITING_FOR_REVIEW, $plan->get_status()); 981 } 982 983 /** 984 * Testing cancelling the review request. 985 */ 986 public function test_plan_cancel_review_request() { 987 $data = $this->setup_workflow_data(); 988 $dg = $data['dg']; 989 $lpg = $data['lpg']; 990 $user = $data['user']; 991 $reviewer = $data['reviewer']; 992 $otheruser = $data['otheruser']; 993 $plan = $data['plan']; 994 $tplplan = $data['tplplan']; 995 996 // Set waiting for review. 997 $tplplan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 998 $tplplan->update(); 999 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1000 $plan->update(); 1001 1002 // Foreign user cannot do anything. 1003 $this->setUser($otheruser); 1004 try { 1005 api::plan_cancel_review_request($plan); 1006 $this->fail('The user can not read the plan.'); 1007 } catch (required_capability_exception $e) { 1008 $this->assertEquals('nopermissions', $e->errorcode); 1009 } 1010 1011 // Can not change a plan based on a template. 1012 $this->setUser($user); 1013 try { 1014 api::plan_cancel_review_request($tplplan); 1015 $this->fail('The plan is based on a template.'); 1016 } catch (coding_exception $e) { 1017 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage()); 1018 } 1019 1020 // Can not cancel review request when not waiting for review. 1021 $this->setUser($user); 1022 $plan->set_status(plan::STATUS_DRAFT); 1023 try { 1024 api::plan_cancel_review_request($plan); 1025 $this->fail('The plan cannot be sent for review at this stage.'); 1026 } catch (coding_exception $e) { 1027 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage()); 1028 } 1029 1030 // Can not cancel review request when not waiting for review. 1031 $this->setUser($user); 1032 $plan->set_status(plan::STATUS_IN_REVIEW); 1033 try { 1034 api::plan_cancel_review_request($plan); 1035 $this->fail('The plan review cannot be cancelled at this stage.'); 1036 } catch (coding_exception $e) { 1037 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage()); 1038 } 1039 1040 // Can not cancel review request when not waiting for review. 1041 $this->setUser($user); 1042 $plan->set_status(plan::STATUS_ACTIVE); 1043 try { 1044 api::plan_cancel_review_request($plan); 1045 $this->fail('The plan review cannot be cancelled at this stage.'); 1046 } catch (coding_exception $e) { 1047 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage()); 1048 } 1049 1050 // Can not cancel review request when not waiting for review. 1051 $this->setUser($user); 1052 $plan->set_status(plan::STATUS_COMPLETE); 1053 try { 1054 api::plan_cancel_review_request($plan); 1055 $this->fail('The plan review cannot be cancelled at this stage.'); 1056 } catch (coding_exception $e) { 1057 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage()); 1058 } 1059 1060 // Cancelling as a reviewer. 1061 $this->setUser($reviewer); 1062 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1063 try { 1064 api::plan_cancel_review_request($plan); 1065 $this->fail('The user can not cancel a review request.'); 1066 } catch (required_capability_exception $e) { 1067 $this->assertEquals('nopermissions', $e->errorcode); 1068 } 1069 1070 // Cancelling review request. 1071 $this->setUser($user); 1072 api::plan_cancel_review_request($plan); 1073 $plan->read(); 1074 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1075 1076 // Cancelling review request by ID. 1077 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1078 $plan->update(); 1079 api::plan_cancel_review_request($plan->get_id()); 1080 $plan->read(); 1081 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1082 } 1083 1084 /** 1085 * Testing starting the review. 1086 */ 1087 public function test_plan_start_review() { 1088 $data = $this->setup_workflow_data(); 1089 $dg = $data['dg']; 1090 $lpg = $data['lpg']; 1091 $user = $data['user']; 1092 $reviewer = $data['reviewer']; 1093 $otheruser = $data['otheruser']; 1094 $plan = $data['plan']; 1095 $tplplan = $data['tplplan']; 1096 1097 // Set waiting for review. 1098 $tplplan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1099 $tplplan->update(); 1100 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1101 $plan->update(); 1102 1103 // Foreign user cannot do anything. 1104 $this->setUser($otheruser); 1105 try { 1106 api::plan_start_review($plan); 1107 $this->fail('The user can not read the plan.'); 1108 } catch (required_capability_exception $e) { 1109 $this->assertEquals('nopermissions', $e->errorcode); 1110 } 1111 1112 // Can not change a plan based on a template. 1113 $this->setUser($reviewer); 1114 try { 1115 api::plan_start_review($tplplan); 1116 $this->fail('The plan is based on a template.'); 1117 } catch (coding_exception $e) { 1118 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage()); 1119 } 1120 1121 // Can not start a review when not waiting for review. 1122 $this->setUser($reviewer); 1123 $plan->set_status(plan::STATUS_DRAFT); 1124 try { 1125 api::plan_start_review($plan); 1126 $this->fail('The plan review cannot be started at this stage.'); 1127 } catch (coding_exception $e) { 1128 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage()); 1129 } 1130 1131 // Can not start a review when not waiting for review. 1132 $this->setUser($reviewer); 1133 $plan->set_status(plan::STATUS_IN_REVIEW); 1134 try { 1135 api::plan_start_review($plan); 1136 $this->fail('The plan review cannot be started at this stage.'); 1137 } catch (coding_exception $e) { 1138 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage()); 1139 } 1140 1141 // Can not start a review when not waiting for review. 1142 $this->setUser($reviewer); 1143 $plan->set_status(plan::STATUS_ACTIVE); 1144 try { 1145 api::plan_start_review($plan); 1146 $this->fail('The plan review cannot be started at this stage.'); 1147 } catch (coding_exception $e) { 1148 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage()); 1149 } 1150 1151 // Can not start a review when not waiting for review. 1152 $this->setUser($reviewer); 1153 $plan->set_status(plan::STATUS_COMPLETE); 1154 try { 1155 api::plan_start_review($plan); 1156 $this->fail('The plan review cannot be started at this stage.'); 1157 } catch (coding_exception $e) { 1158 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage()); 1159 } 1160 1161 // Starting as the owner. 1162 $this->setUser($user); 1163 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1164 try { 1165 api::plan_start_review($plan); 1166 $this->fail('The user can not start a review.'); 1167 } catch (required_capability_exception $e) { 1168 $this->assertEquals('nopermissions', $e->errorcode); 1169 } 1170 1171 // Starting review. 1172 $this->setUser($reviewer); 1173 api::plan_start_review($plan); 1174 $plan->read(); 1175 $this->assertEquals(plan::STATUS_IN_REVIEW, $plan->get_status()); 1176 $this->assertEquals($reviewer->id, $plan->get_reviewerid()); 1177 1178 // Starting review by ID. 1179 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1180 $plan->set_reviewerid(null); 1181 $plan->update(); 1182 api::plan_start_review($plan->get_id()); 1183 $plan->read(); 1184 $this->assertEquals(plan::STATUS_IN_REVIEW, $plan->get_status()); 1185 $this->assertEquals($reviewer->id, $plan->get_reviewerid()); 1186 } 1187 1188 /** 1189 * Testing stopping the review. 1190 */ 1191 public function test_plan_stop_review() { 1192 $data = $this->setup_workflow_data(); 1193 $dg = $data['dg']; 1194 $lpg = $data['lpg']; 1195 $user = $data['user']; 1196 $reviewer = $data['reviewer']; 1197 $otheruser = $data['otheruser']; 1198 $plan = $data['plan']; 1199 $tplplan = $data['tplplan']; 1200 1201 // Set waiting for review. 1202 $tplplan->set_status(plan::STATUS_IN_REVIEW); 1203 $tplplan->update(); 1204 $plan->set_status(plan::STATUS_IN_REVIEW); 1205 $plan->update(); 1206 1207 // Foreign user cannot do anything. 1208 $this->setUser($otheruser); 1209 try { 1210 api::plan_stop_review($plan); 1211 $this->fail('The user can not read the plan.'); 1212 } catch (required_capability_exception $e) { 1213 $this->assertEquals('nopermissions', $e->errorcode); 1214 } 1215 1216 // Can not change a plan based on a template. 1217 $this->setUser($reviewer); 1218 try { 1219 api::plan_stop_review($tplplan); 1220 $this->fail('The plan is based on a template.'); 1221 } catch (coding_exception $e) { 1222 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage()); 1223 } 1224 1225 // Can not stop a review whe not in review. 1226 $this->setUser($reviewer); 1227 $plan->set_status(plan::STATUS_DRAFT); 1228 try { 1229 api::plan_stop_review($plan); 1230 $this->fail('The plan review cannot be stopped at this stage.'); 1231 } catch (coding_exception $e) { 1232 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage()); 1233 } 1234 1235 // Can not stop a review whe not in review. 1236 $this->setUser($reviewer); 1237 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1238 try { 1239 api::plan_stop_review($plan); 1240 $this->fail('The plan review cannot be stopped at this stage.'); 1241 } catch (coding_exception $e) { 1242 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage()); 1243 } 1244 1245 // Can not stop a review whe not in review. 1246 $this->setUser($reviewer); 1247 $plan->set_status(plan::STATUS_ACTIVE); 1248 try { 1249 api::plan_stop_review($plan); 1250 $this->fail('The plan review cannot be stopped at this stage.'); 1251 } catch (coding_exception $e) { 1252 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage()); 1253 } 1254 1255 // Can not stop a review whe not in review. 1256 $this->setUser($reviewer); 1257 $plan->set_status(plan::STATUS_COMPLETE); 1258 try { 1259 api::plan_stop_review($plan); 1260 $this->fail('The plan review cannot be stopped at this stage.'); 1261 } catch (coding_exception $e) { 1262 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage()); 1263 } 1264 1265 // Stopping as the owner. 1266 $this->setUser($user); 1267 $plan->set_status(plan::STATUS_IN_REVIEW); 1268 try { 1269 api::plan_stop_review($plan); 1270 $this->fail('The user can not stop a review.'); 1271 } catch (required_capability_exception $e) { 1272 $this->assertEquals('nopermissions', $e->errorcode); 1273 } 1274 1275 // Stopping review. 1276 $this->setUser($reviewer); 1277 api::plan_stop_review($plan); 1278 $plan->read(); 1279 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1280 1281 // Stopping review by ID. 1282 $plan->set_status(plan::STATUS_IN_REVIEW); 1283 $plan->update(); 1284 api::plan_stop_review($plan->get_id()); 1285 $plan->read(); 1286 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1287 } 1288 1289 /** 1290 * Testing approving the plan. 1291 */ 1292 public function test_approve_plan() { 1293 $data = $this->setup_workflow_data(); 1294 $dg = $data['dg']; 1295 $lpg = $data['lpg']; 1296 $user = $data['user']; 1297 $reviewer = $data['reviewer']; 1298 $otheruser = $data['otheruser']; 1299 $plan = $data['plan']; 1300 $tplplan = $data['tplplan']; 1301 1302 // Set waiting for review. 1303 $tplplan->set_status(plan::STATUS_IN_REVIEW); 1304 $tplplan->update(); 1305 $plan->set_status(plan::STATUS_IN_REVIEW); 1306 $plan->update(); 1307 1308 // Foreign user cannot do anything. 1309 $this->setUser($otheruser); 1310 try { 1311 api::approve_plan($plan); 1312 $this->fail('The user can not read the plan.'); 1313 } catch (required_capability_exception $e) { 1314 $this->assertEquals('nopermissions', $e->errorcode); 1315 } 1316 1317 // Can not change a plan based on a template. 1318 $this->setUser($reviewer); 1319 try { 1320 api::approve_plan($tplplan); 1321 $this->fail('The plan is based on a template.'); 1322 } catch (coding_exception $e) { 1323 $this->assertRegExp('/Template plans are already approved./', $e->getMessage()); 1324 } 1325 1326 // Can not approve a plan already approved. 1327 $this->setUser($reviewer); 1328 $plan->set_status(plan::STATUS_ACTIVE); 1329 try { 1330 api::approve_plan($plan); 1331 $this->fail('The plan cannot be approved at this stage.'); 1332 } catch (coding_exception $e) { 1333 $this->assertRegExp('/The plan cannot be approved at this stage./', $e->getMessage()); 1334 } 1335 1336 // Can not approve a plan already approved. 1337 $this->setUser($reviewer); 1338 $plan->set_status(plan::STATUS_COMPLETE); 1339 try { 1340 api::approve_plan($plan); 1341 $this->fail('The plan cannot be approved at this stage.'); 1342 } catch (coding_exception $e) { 1343 $this->assertRegExp('/The plan cannot be approved at this stage./', $e->getMessage()); 1344 } 1345 1346 // Approve as the owner. 1347 $this->setUser($user); 1348 $plan->set_status(plan::STATUS_IN_REVIEW); 1349 try { 1350 api::approve_plan($plan); 1351 $this->fail('The user can not approve the plan.'); 1352 } catch (required_capability_exception $e) { 1353 $this->assertEquals('nopermissions', $e->errorcode); 1354 } 1355 1356 // Approve plan from in review. 1357 $this->setUser($reviewer); 1358 api::approve_plan($plan); 1359 $plan->read(); 1360 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status()); 1361 1362 // Approve plan by ID. 1363 $plan->set_status(plan::STATUS_IN_REVIEW); 1364 $plan->update(); 1365 api::approve_plan($plan->get_id()); 1366 $plan->read(); 1367 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status()); 1368 1369 // Approve plan from draft. 1370 $plan->set_status(plan::STATUS_DRAFT); 1371 $plan->update(); 1372 api::approve_plan($plan); 1373 $plan->read(); 1374 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status()); 1375 1376 // Approve plan from waiting for review. 1377 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1378 $plan->update(); 1379 api::approve_plan($plan); 1380 $plan->read(); 1381 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status()); 1382 } 1383 1384 /** 1385 * Testing stopping the review. 1386 */ 1387 public function test_unapprove_plan() { 1388 $data = $this->setup_workflow_data(); 1389 $dg = $data['dg']; 1390 $lpg = $data['lpg']; 1391 $user = $data['user']; 1392 $reviewer = $data['reviewer']; 1393 $otheruser = $data['otheruser']; 1394 $plan = $data['plan']; 1395 $tplplan = $data['tplplan']; 1396 1397 // Set waiting for review. 1398 $tplplan->set_status(plan::STATUS_ACTIVE); 1399 $tplplan->update(); 1400 $plan->set_status(plan::STATUS_ACTIVE); 1401 $plan->update(); 1402 1403 // Foreign user cannot do anything. 1404 $this->setUser($otheruser); 1405 try { 1406 api::unapprove_plan($plan); 1407 $this->fail('The user can not read the plan.'); 1408 } catch (required_capability_exception $e) { 1409 $this->assertEquals('nopermissions', $e->errorcode); 1410 } 1411 1412 // Can not change a plan based on a template. 1413 $this->setUser($reviewer); 1414 try { 1415 api::unapprove_plan($tplplan); 1416 $this->fail('The plan is based on a template.'); 1417 } catch (coding_exception $e) { 1418 $this->assertRegExp('/Template plans are always approved./', $e->getMessage()); 1419 } 1420 1421 // Can not unapprove a non-draft plan. 1422 $this->setUser($reviewer); 1423 $plan->set_status(plan::STATUS_DRAFT); 1424 try { 1425 api::unapprove_plan($plan); 1426 $this->fail('The plan cannot be sent back to draft at this stage.'); 1427 } catch (coding_exception $e) { 1428 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage()); 1429 } 1430 1431 // Can not unapprove a non-draft plan. 1432 $this->setUser($reviewer); 1433 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW); 1434 try { 1435 api::unapprove_plan($plan); 1436 $this->fail('The plan cannot be sent back to draft at this stage.'); 1437 } catch (coding_exception $e) { 1438 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage()); 1439 } 1440 1441 // Can not unapprove a non-draft plan. 1442 $this->setUser($reviewer); 1443 $plan->set_status(plan::STATUS_IN_REVIEW); 1444 try { 1445 api::unapprove_plan($plan); 1446 $this->fail('The plan cannot be sent back to draft at this stage.'); 1447 } catch (coding_exception $e) { 1448 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage()); 1449 } 1450 1451 // Can not unapprove a non-draft plan. 1452 $this->setUser($reviewer); 1453 $plan->set_status(plan::STATUS_COMPLETE); 1454 try { 1455 api::unapprove_plan($plan); 1456 $this->fail('The plan cannot be sent back to draft at this stage.'); 1457 } catch (coding_exception $e) { 1458 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage()); 1459 } 1460 1461 // Unapprove as the owner. 1462 $this->setUser($user); 1463 $plan->set_status(plan::STATUS_ACTIVE); 1464 try { 1465 api::unapprove_plan($plan); 1466 $this->fail('The user can not unapprove the plan.'); 1467 } catch (required_capability_exception $e) { 1468 $this->assertEquals('nopermissions', $e->errorcode); 1469 } 1470 1471 // Unapprove plan. 1472 $this->setUser($reviewer); 1473 api::unapprove_plan($plan); 1474 $plan->read(); 1475 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1476 1477 // Unapprove plan by ID. 1478 $plan->set_status(plan::STATUS_ACTIVE); 1479 $plan->update(); 1480 api::unapprove_plan($plan->get_id()); 1481 $plan->read(); 1482 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status()); 1483 } 1484 1485 /** 1486 * Test update plan and the managing of archived user competencies. 1487 */ 1488 public function test_update_plan_manage_archived_competencies() { 1489 global $DB; 1490 1491 $this->resetAfterTest(true); 1492 $dg = $this->getDataGenerator(); 1493 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1494 1495 $syscontext = context_system::instance(); 1496 1497 // Create users and roles for the test. 1498 $user = $dg->create_user(); 1499 $manageownrole = $dg->create_role(array( 1500 'name' => 'User manage own', 1501 'shortname' => 'manageown' 1502 )); 1503 assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $manageownrole, $syscontext->id); 1504 assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $manageownrole, $syscontext->id); 1505 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id); 1506 assign_capability('moodle/competency:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id); 1507 $dg->role_assign($manageownrole, $user->id, $syscontext->id); 1508 $this->setUser($user); 1509 1510 // Create a framework and assign competencies. 1511 $framework = $lpg->create_framework(); 1512 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1513 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1514 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1515 1516 // Create two plans and assign competencies. 1517 $plan = $lpg->create_plan(array('userid' => $user->id)); 1518 $otherplan = $lpg->create_plan(array('userid' => $user->id)); 1519 1520 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id())); 1521 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id())); 1522 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id())); 1523 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id())); 1524 1525 $uclist = array( 1526 $lpg->create_user_competency(array( 1527 'userid' => $user->id, 1528 'competencyid' => $c1->get_id(), 1529 'proficiency' => true, 1530 'grade' => 1 1531 )), 1532 $lpg->create_user_competency(array( 1533 'userid' => $user->id, 1534 'competencyid' => $c2->get_id(), 1535 'proficiency' => false, 1536 'grade' => 2 1537 )) 1538 ); 1539 1540 // Change status of the plan to complete. 1541 $record = $plan->to_record(); 1542 $record->status = \core_competency\plan::STATUS_COMPLETE; 1543 1544 try { 1545 $plan = api::update_plan($record); 1546 $this->fail('We cannot complete a plan using api::update_plan().'); 1547 } catch (coding_exception $e) { 1548 // All good. 1549 } 1550 api::complete_plan($plan); 1551 1552 // Check that user compretencies are now in user_competency_plan objects and still in user_competency. 1553 $this->assertEquals(2, \core_competency\user_competency::count_records()); 1554 $this->assertEquals(3, \core_competency\user_competency_plan::count_records()); 1555 1556 $usercompetenciesplan = \core_competency\user_competency_plan::get_records(); 1557 1558 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid()); 1559 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid()); 1560 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency()); 1561 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade()); 1562 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid()); 1563 1564 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid()); 1565 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid()); 1566 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency()); 1567 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade()); 1568 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid()); 1569 1570 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid()); 1571 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid()); 1572 $this->assertNull($usercompetenciesplan[2]->get_proficiency()); 1573 $this->assertNull($usercompetenciesplan[2]->get_grade()); 1574 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid()); 1575 1576 // Change status of the plan to active. 1577 $record = $plan->to_record(); 1578 $record->status = \core_competency\plan::STATUS_ACTIVE; 1579 1580 try { 1581 api::update_plan($record); 1582 $this->fail('Completed plan can not be edited'); 1583 } catch (coding_exception $e) { 1584 // All good. 1585 } 1586 1587 api::reopen_plan($record->id); 1588 // Check that user_competency_plan objects are deleted if the plan status is changed to another status. 1589 $this->assertEquals(2, \core_competency\user_competency::count_records()); 1590 $this->assertEquals(0, \core_competency\user_competency_plan::count_records()); 1591 } 1592 1593 /** 1594 * Test completing plan does not change the order of competencies. 1595 */ 1596 public function test_complete_plan_doesnot_change_order() { 1597 global $DB; 1598 1599 $this->resetAfterTest(true); 1600 $this->setAdminUser(); 1601 $dg = $this->getDataGenerator(); 1602 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1603 1604 $syscontext = context_system::instance(); 1605 1606 // Create users and roles for the test. 1607 $user = $dg->create_user(); 1608 1609 // Create a framework and assign competencies. 1610 $framework = $lpg->create_framework(); 1611 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1612 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1613 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1614 1615 // Create two plans and assign competencies. 1616 $plan = $lpg->create_plan(array('userid' => $user->id)); 1617 1618 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id())); 1619 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id())); 1620 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id())); 1621 1622 // Changing competencies order in plan competency. 1623 api::reorder_plan_competency($plan->get_id(), $c1->get_id(), $c3->get_id()); 1624 1625 $competencies = api::list_plan_competencies($plan); 1626 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id()); 1627 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id()); 1628 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id()); 1629 1630 // Completing plan. 1631 api::complete_plan($plan); 1632 1633 $competencies = api::list_plan_competencies($plan); 1634 1635 // Completing plan does not change order. 1636 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id()); 1637 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id()); 1638 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id()); 1639 1640 // Testing plan based on template. 1641 $template = $lpg->create_template(); 1642 $framework = $lpg->create_framework(); 1643 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1644 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1645 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1646 1647 $lpg->create_template_competency(array( 1648 'templateid' => $template->get_id(), 1649 'competencyid' => $c1->get_id() 1650 )); 1651 $lpg->create_template_competency(array( 1652 'templateid' => $template->get_id(), 1653 'competencyid' => $c2->get_id() 1654 )); 1655 $lpg->create_template_competency(array( 1656 'templateid' => $template->get_id(), 1657 'competencyid' => $c3->get_id() 1658 )); 1659 // Reorder competencies in template. 1660 api::reorder_template_competency($template->get_id(), $c1->get_id(), $c3->get_id()); 1661 1662 // Create plan from template. 1663 $plan = api::create_plan_from_template($template->get_id(), $user->id); 1664 1665 $competencies = api::list_plan_competencies($plan); 1666 1667 // Completing plan does not change order. 1668 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id()); 1669 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id()); 1670 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id()); 1671 1672 // Completing plan. 1673 api::complete_plan($plan); 1674 1675 $competencies = api::list_plan_competencies($plan); 1676 1677 // Completing plan does not change order. 1678 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id()); 1679 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id()); 1680 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id()); 1681 } 1682 1683 /** 1684 * Test remove plan and the managing of archived user competencies. 1685 */ 1686 public function test_delete_plan_manage_archived_competencies() { 1687 $this->resetAfterTest(true); 1688 $dg = $this->getDataGenerator(); 1689 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1690 1691 $syscontext = context_system::instance(); 1692 1693 // Create user and role for the test. 1694 $user = $dg->create_user(); 1695 $managerole = $dg->create_role(array( 1696 'name' => 'User manage own', 1697 'shortname' => 'manageown' 1698 )); 1699 assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $managerole, $syscontext->id); 1700 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $managerole, $syscontext->id); 1701 $dg->role_assign($managerole, $user->id, $syscontext->id); 1702 $this->setUser($user); 1703 1704 // Create a framework and assign competencies. 1705 $framework = $lpg->create_framework(); 1706 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1707 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1708 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1709 1710 // Create completed plan with records in user_competency. 1711 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \core_competency\plan::STATUS_COMPLETE)); 1712 1713 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id())); 1714 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id())); 1715 1716 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id())); 1717 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id())); 1718 1719 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(), 1720 'planid' => $completedplan->get_id())); 1721 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(), 1722 'planid' => $completedplan->get_id())); 1723 1724 api::delete_plan($completedplan->get_id()); 1725 1726 // Check that achived user competencies are deleted. 1727 $this->assertEquals(0, \core_competency\plan::count_records()); 1728 $this->assertEquals(2, \core_competency\user_competency::count_records()); 1729 $this->assertEquals(0, \core_competency\user_competency_plan::count_records()); 1730 } 1731 1732 /** 1733 * Test listing of plan competencies. 1734 */ 1735 public function test_list_plan_competencies_manage_archived_competencies() { 1736 $this->resetAfterTest(true); 1737 $dg = $this->getDataGenerator(); 1738 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1739 1740 $syscontext = context_system::instance(); 1741 1742 // Create user and role for the test. 1743 $user = $dg->create_user(); 1744 $viewrole = $dg->create_role(array( 1745 'name' => 'User view', 1746 'shortname' => 'view' 1747 )); 1748 assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $viewrole, $syscontext->id); 1749 assign_capability('moodle/competency:planview', CAP_ALLOW, $viewrole, $syscontext->id); 1750 $dg->role_assign($viewrole, $user->id, $syscontext->id); 1751 $this->setUser($user); 1752 1753 // Create a framework and assign competencies. 1754 $framework = $lpg->create_framework(); 1755 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1756 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1757 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 1758 1759 // Create draft plan with records in user_competency. 1760 $draftplan = $lpg->create_plan(array('userid' => $user->id)); 1761 1762 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c1->get_id())); 1763 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c2->get_id())); 1764 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c3->get_id())); 1765 1766 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id())); 1767 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id())); 1768 1769 // Check that user_competency objects are returned when plan status is not complete. 1770 $plancompetencies = api::list_plan_competencies($draftplan); 1771 1772 $this->assertCount(3, $plancompetencies); 1773 $this->assertInstanceOf('\core_competency\user_competency', $plancompetencies[0]->usercompetency); 1774 $this->assertEquals($uc1->get_id(), $plancompetencies[0]->usercompetency->get_id()); 1775 $this->assertNull($plancompetencies[0]->usercompetencyplan); 1776 1777 $this->assertInstanceOf('\core_competency\user_competency', $plancompetencies[1]->usercompetency); 1778 $this->assertEquals($uc2->get_id(), $plancompetencies[1]->usercompetency->get_id()); 1779 $this->assertNull($plancompetencies[1]->usercompetencyplan); 1780 1781 $this->assertInstanceOf('\core_competency\user_competency', $plancompetencies[2]->usercompetency); 1782 $this->assertEquals(0, $plancompetencies[2]->usercompetency->get_id()); 1783 $this->assertNull($plancompetencies[2]->usercompetencyplan); 1784 1785 // Create completed plan with records in user_competency_plan. 1786 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \core_competency\plan::STATUS_COMPLETE)); 1787 1788 $pc1 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id())); 1789 $pc2 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id())); 1790 $pc3 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c3->get_id())); 1791 1792 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(), 1793 'planid' => $completedplan->get_id())); 1794 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(), 1795 'planid' => $completedplan->get_id())); 1796 $ucp3 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c3->get_id(), 1797 'planid' => $completedplan->get_id())); 1798 1799 // Check that user_competency_plan objects are returned when plan status is complete. 1800 $plancompetencies = api::list_plan_competencies($completedplan); 1801 1802 $this->assertCount(3, $plancompetencies); 1803 $this->assertInstanceOf('\core_competency\user_competency_plan', $plancompetencies[0]->usercompetencyplan); 1804 $this->assertEquals($ucp1->get_id(), $plancompetencies[0]->usercompetencyplan->get_id()); 1805 $this->assertNull($plancompetencies[0]->usercompetency); 1806 $this->assertInstanceOf('\core_competency\user_competency_plan', $plancompetencies[1]->usercompetencyplan); 1807 $this->assertEquals($ucp2->get_id(), $plancompetencies[1]->usercompetencyplan->get_id()); 1808 $this->assertNull($plancompetencies[1]->usercompetency); 1809 $this->assertInstanceOf('\core_competency\user_competency_plan', $plancompetencies[2]->usercompetencyplan); 1810 $this->assertEquals($ucp3->get_id(), $plancompetencies[2]->usercompetencyplan->get_id()); 1811 $this->assertNull($plancompetencies[2]->usercompetency); 1812 } 1813 1814 public function test_create_template_cohort() { 1815 $this->resetAfterTest(true); 1816 $this->setAdminUser(); 1817 1818 $dg = $this->getDataGenerator(); 1819 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1820 1821 $c1 = $dg->create_cohort(); 1822 $c2 = $dg->create_cohort(); 1823 $t1 = $lpg->create_template(); 1824 $t2 = $lpg->create_template(); 1825 1826 $this->assertEquals(0, \core_competency\template_cohort::count_records()); 1827 1828 // Create two relations with mixed parameters. 1829 $result = api::create_template_cohort($t1->get_id(), $c1->id); 1830 $result = api::create_template_cohort($t1, $c2); 1831 1832 $this->assertEquals(2, \core_competency\template_cohort::count_records()); 1833 $this->assertInstanceOf('core_competency\template_cohort', $result); 1834 $this->assertEquals($c2->id, $result->get_cohortid()); 1835 $this->assertEquals($t1->get_id(), $result->get_templateid()); 1836 $this->assertEquals(2, \core_competency\template_cohort::count_records_select('templateid = :id', 1837 array('id' => $t1->get_id()))); 1838 $this->assertEquals(0, \core_competency\template_cohort::count_records_select('templateid = :id', 1839 array('id' => $t2->get_id()))); 1840 } 1841 1842 public function test_create_template_cohort_permissions() { 1843 $this->resetAfterTest(true); 1844 1845 $dg = $this->getDataGenerator(); 1846 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1847 $cat = $dg->create_category(); 1848 $catcontext = context_coursecat::instance($cat->id); 1849 $syscontext = context_system::instance(); 1850 1851 $user = $dg->create_user(); 1852 $role = $dg->create_role(); 1853 assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $role, $syscontext->id, true); 1854 $dg->role_assign($role, $user->id, $syscontext->id); 1855 1856 $cohortrole = $dg->create_role(); 1857 assign_capability('moodle/cohort:view', CAP_ALLOW, $cohortrole, $syscontext->id, true); 1858 1859 accesslib_clear_all_caches_for_unit_testing(); 1860 1861 $c1 = $dg->create_cohort(); 1862 $c2 = $dg->create_cohort(array('visible' => 0, 'contextid' => $catcontext->id)); 1863 $t1 = $lpg->create_template(); 1864 1865 $this->assertEquals(0, \core_competency\template_cohort::count_records()); 1866 1867 $this->setUser($user); 1868 $result = api::create_template_cohort($t1, $c1); 1869 $this->assertInstanceOf('core_competency\\template_cohort', $result); 1870 1871 try { 1872 $result = api::create_template_cohort($t1, $c2); 1873 $this->fail('Permission required.'); 1874 } catch (required_capability_exception $e) { 1875 // That's what should happen. 1876 } 1877 1878 // Try again with the right permissions. 1879 $dg->role_assign($cohortrole, $user->id, $catcontext->id); 1880 accesslib_clear_all_caches_for_unit_testing(); 1881 1882 $result = api::create_template_cohort($t1, $c2); 1883 $this->assertInstanceOf('core_competency\\template_cohort', $result); 1884 } 1885 1886 public function test_delete_template() { 1887 $this->resetAfterTest(true); 1888 $this->setAdminUser(); 1889 1890 $dg = $this->getDataGenerator(); 1891 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1892 1893 $c1 = $dg->create_cohort(); 1894 $c2 = $dg->create_cohort(); 1895 $template = $lpg->create_template(); 1896 $id = $template->get_id(); 1897 1898 // Create 2 template cohorts. 1899 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c1->id)); 1900 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c2->id)); 1901 1902 // Check pre-test. 1903 $this->assertTrue(\core_competency\template::record_exists($id)); 1904 $this->assertEquals(2, \core_competency\template_cohort::count_records(array('templateid' => $id))); 1905 1906 $result = api::delete_template($template->get_id()); 1907 $this->assertTrue($result); 1908 1909 // Check that the template deos not exist anymore. 1910 $this->assertFalse(\core_competency\template::record_exists($id)); 1911 1912 // Test if associated cohorts are also deleted. 1913 $this->assertEquals(0, \core_competency\template_cohort::count_records(array('templateid' => $id))); 1914 } 1915 1916 public function test_delete_template_cohort() { 1917 $this->resetAfterTest(true); 1918 $this->setAdminUser(); 1919 1920 $dg = $this->getDataGenerator(); 1921 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 1922 1923 $c1 = $dg->create_cohort(); 1924 $c2 = $dg->create_cohort(); 1925 $t1 = $lpg->create_template(); 1926 $t2 = $lpg->create_template(); 1927 $tc1 = $lpg->create_template_cohort(array('templateid' => $t1->get_id(), 'cohortid' => $c1->id)); 1928 $tc1 = $lpg->create_template_cohort(array('templateid' => $t2->get_id(), 'cohortid' => $c2->id)); 1929 1930 $this->assertEquals(2, \core_competency\template_cohort::count_records()); 1931 $this->assertEquals(1, \core_competency\template_cohort::count_records_select('templateid = :id', 1932 array('id' => $t1->get_id()))); 1933 $this->assertEquals(1, \core_competency\template_cohort::count_records_select('templateid = :id', 1934 array('id' => $t2->get_id()))); 1935 1936 // Delete existing. 1937 $result = api::delete_template_cohort($t1->get_id(), $c1->id); 1938 $this->assertTrue($result); 1939 $this->assertEquals(1, \core_competency\template_cohort::count_records()); 1940 $this->assertEquals(0, \core_competency\template_cohort::count_records_select('templateid = :id', 1941 array('id' => $t1->get_id()))); 1942 $this->assertEquals(1, \core_competency\template_cohort::count_records_select('templateid = :id', 1943 array('id' => $t2->get_id()))); 1944 1945 // Delete non-existant. 1946 $result = api::delete_template_cohort($t1->get_id(), $c1->id); 1947 $this->assertTrue($result); 1948 $this->assertEquals(1, \core_competency\template_cohort::count_records()); 1949 $this->assertEquals(0, \core_competency\template_cohort::count_records_select('templateid = :id', 1950 array('id' => $t1->get_id()))); 1951 $this->assertEquals(1, \core_competency\template_cohort::count_records_select('templateid = :id', 1952 array('id' => $t2->get_id()))); 1953 } 1954 1955 public function test_add_evidence_log() { 1956 $this->resetAfterTest(true); 1957 $dg = $this->getDataGenerator(); 1958 $lpg = $dg->get_plugin_generator('core_competency'); 1959 1960 $u1 = $dg->create_user(); 1961 $u1ctx = context_user::instance($u1->id); 1962 $f1 = $lpg->create_framework(); 1963 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 1964 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 1965 1966 // Creating a standard evidence with minimal information. 1967 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 1968 'invaliddata', 'error'); 1969 $evidence->read(); 1970 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 1971 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 1972 $this->assertSame(null, $uc->get_grade()); 1973 $this->assertSame(null, $uc->get_proficiency()); 1974 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 1975 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 1976 $this->assertEquals(\core_competency\evidence::ACTION_LOG, $evidence->get_action()); 1977 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 1978 $this->assertEquals('error', $evidence->get_desccomponent()); 1979 $this->assertSame(null, $evidence->get_desca()); 1980 $this->assertSame(null, $evidence->get_url()); 1981 $this->assertSame(null, $evidence->get_grade()); 1982 $this->assertSame(null, $evidence->get_actionuserid()); 1983 1984 // Creating a standard evidence with more information. 1985 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 1986 'error', '$a', false, 'http://moodle.org', null, 2, 'The evidence of prior learning were reviewed.'); 1987 $evidence->read(); 1988 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 1989 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 1990 $this->assertSame(null, $uc->get_grade()); 1991 $this->assertSame(null, $uc->get_proficiency()); 1992 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 1993 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 1994 $this->assertEquals(\core_competency\evidence::ACTION_LOG, $evidence->get_action()); 1995 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 1996 $this->assertEquals('error', $evidence->get_desccomponent()); 1997 $this->assertEquals('$a', $evidence->get_desca()); 1998 $this->assertEquals('http://moodle.org', $evidence->get_url()); 1999 $this->assertSame(null, $evidence->get_grade()); 2000 $this->assertEquals(2, $evidence->get_actionuserid()); 2001 $this->assertSame('The evidence of prior learning were reviewed.', $evidence->get_note()); 2002 2003 // Creating a standard evidence and send for review. 2004 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 2005 'error', null, true); 2006 $evidence->read(); 2007 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); 2008 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status()); 2009 2010 // Trying to pass a grade should fail. 2011 try { 2012 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 2013 'error', null, false, null, 1); 2014 $this->fail('A grade can not be set'); 2015 } catch (coding_exception $e) { 2016 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage()); 2017 } 2018 } 2019 2020 public function test_add_evidence_complete() { 2021 $this->resetAfterTest(true); 2022 $dg = $this->getDataGenerator(); 2023 $lpg = $dg->get_plugin_generator('core_competency'); 2024 2025 $u1 = $dg->create_user(); 2026 $u1ctx = context_user::instance($u1->id); 2027 $scale = $dg->create_scale(array('scale' => 'A,B,C,D')); 2028 $scaleconfig = array(array('scaleid' => $scale->id)); 2029 $scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 1, 'proficient' => 0); 2030 $scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 1); 2031 $scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 0, 'proficient' => 1); 2032 $c2scaleconfig = array(array('scaleid' => $scale->id)); 2033 $c2scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 0, 'proficient' => 1); 2034 $c2scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 0); 2035 $c2scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 1, 'proficient' => 1); 2036 $f1 = $lpg->create_framework(array('scaleid' => $scale->id, 'scaleconfiguration' => $scaleconfig)); 2037 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2038 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'scaleid' => $scale->id, 2039 'scaleconfiguration' => $c2scaleconfig)); 2040 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2041 2042 // Creating an evidence with minimal information. 2043 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_COMPLETE, 'invaliddata', 2044 'error'); 2045 $evidence->read(); 2046 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2047 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2048 $this->assertEquals(2, $uc->get_grade()); // The grade has been set automatically to the framework default. 2049 $this->assertEquals(0, $uc->get_proficiency()); 2050 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2051 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2052 $this->assertEquals(\core_competency\evidence::ACTION_COMPLETE, $evidence->get_action()); 2053 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2054 $this->assertEquals('error', $evidence->get_desccomponent()); 2055 $this->assertSame(null, $evidence->get_desca()); 2056 $this->assertSame(null, $evidence->get_url()); 2057 $this->assertEquals(2, $evidence->get_grade()); 2058 $this->assertSame(null, $evidence->get_actionuserid()); 2059 2060 // Creating an evidence complete on competency with custom scale. 2061 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_COMPLETE, 'invaliddata', 2062 'error'); 2063 $evidence->read(); 2064 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); 2065 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2066 $this->assertEquals(4, $uc->get_grade()); // The grade has been set automatically to the competency default. 2067 $this->assertEquals(true, $uc->get_proficiency()); 2068 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2069 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2070 $this->assertEquals(\core_competency\evidence::ACTION_COMPLETE, $evidence->get_action()); 2071 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2072 $this->assertEquals('error', $evidence->get_desccomponent()); 2073 $this->assertSame(null, $evidence->get_desca()); 2074 $this->assertSame(null, $evidence->get_url()); 2075 $this->assertEquals(4, $evidence->get_grade()); 2076 $this->assertSame(null, $evidence->get_actionuserid()); 2077 2078 // Creating an evidence complete on a user competency with an existing grade. 2079 $uc = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get_id(), 'grade' => 1, 2080 'proficiency' => 0)); 2081 $this->assertEquals(1, $uc->get_grade()); 2082 $this->assertEquals(0, $uc->get_proficiency()); 2083 $evidence = api::add_evidence($u1->id, $c3->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_COMPLETE, 'invaliddata', 2084 'error'); 2085 $evidence->read(); 2086 $uc->read(); 2087 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2088 $this->assertEquals(1, $uc->get_grade()); // The grade has not been changed. 2089 $this->assertEquals(0, $uc->get_proficiency()); 2090 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2091 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2092 $this->assertEquals(\core_competency\evidence::ACTION_COMPLETE, $evidence->get_action()); 2093 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2094 $this->assertEquals('error', $evidence->get_desccomponent()); 2095 $this->assertSame(null, $evidence->get_desca()); 2096 $this->assertSame(null, $evidence->get_url()); 2097 $this->assertEquals(2, $evidence->get_grade()); // The complete grade has been set. 2098 $this->assertSame(null, $evidence->get_actionuserid()); 2099 2100 // Creating a standard evidence and send for review. 2101 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_COMPLETE, 'invaliddata', 2102 'error', null, true); 2103 $evidence->read(); 2104 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); 2105 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status()); 2106 2107 // Trying to pass a grade should throw an exception. 2108 try { 2109 api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_COMPLETE, 'invaliddata', 2110 'error', null, false, null, 1); 2111 } catch (coding_exception $e) { 2112 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage()); 2113 } 2114 } 2115 2116 public function test_add_evidence_override() { 2117 $this->resetAfterTest(true); 2118 $dg = $this->getDataGenerator(); 2119 $lpg = $dg->get_plugin_generator('core_competency'); 2120 2121 $u1 = $dg->create_user(); 2122 $u1ctx = context_user::instance($u1->id); 2123 $f1 = $lpg->create_framework(); 2124 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2125 2126 // Creating an evidence with minimal information. 2127 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_OVERRIDE, 'invaliddata', 2128 'error'); 2129 $evidence->read(); 2130 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2131 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2132 $this->assertSame(null, $uc->get_grade()); // We overrode with 'null'. 2133 $this->assertSame(null, $uc->get_proficiency()); 2134 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2135 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2136 $this->assertEquals(\core_competency\evidence::ACTION_OVERRIDE, $evidence->get_action()); 2137 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2138 $this->assertEquals('error', $evidence->get_desccomponent()); 2139 $this->assertSame(null, $evidence->get_desca()); 2140 $this->assertSame(null, $evidence->get_url()); 2141 $this->assertSame(null, $evidence->get_grade()); // We overrode with 'null'. 2142 $this->assertSame(null, $evidence->get_actionuserid()); 2143 2144 // Creating an evidence with a grade information. 2145 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_OVERRIDE, 'invaliddata', 2146 'error', null, false, null, 3); 2147 $evidence->read(); 2148 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2149 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2150 $this->assertEquals(3, $uc->get_grade()); 2151 $this->assertEquals(true, $uc->get_proficiency()); 2152 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2153 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2154 $this->assertEquals(\core_competency\evidence::ACTION_OVERRIDE, $evidence->get_action()); 2155 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2156 $this->assertEquals('error', $evidence->get_desccomponent()); 2157 $this->assertSame(null, $evidence->get_desca()); 2158 $this->assertSame(null, $evidence->get_url()); 2159 $this->assertEquals(3, $evidence->get_grade()); 2160 $this->assertSame(null, $evidence->get_actionuserid()); 2161 2162 // Creating an evidence with another grade information. 2163 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_OVERRIDE, 'invaliddata', 2164 'error', null, false, null, 1); 2165 $evidence->read(); 2166 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2167 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc->get_status()); 2168 $this->assertEquals(1, $uc->get_grade()); 2169 $this->assertEquals(0, $uc->get_proficiency()); 2170 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2171 $this->assertEquals($u1ctx->id, $evidence->get_contextid()); 2172 $this->assertEquals(\core_competency\evidence::ACTION_OVERRIDE, $evidence->get_action()); 2173 $this->assertEquals('invaliddata', $evidence->get_descidentifier()); 2174 $this->assertEquals('error', $evidence->get_desccomponent()); 2175 $this->assertSame(null, $evidence->get_desca()); 2176 $this->assertSame(null, $evidence->get_url()); 2177 $this->assertEquals(1, $evidence->get_grade()); 2178 $this->assertSame(null, $evidence->get_actionuserid()); 2179 2180 // Creating reverting the grade and send for review. 2181 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_OVERRIDE, 'invaliddata', 2182 'error', null, true); 2183 $evidence->read(); 2184 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2185 $this->assertSame(null, $uc->get_grade()); 2186 $this->assertSame(null, $uc->get_proficiency()); 2187 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status()); 2188 $this->assertSame(null, $evidence->get_grade()); 2189 } 2190 2191 public function test_add_evidence_and_send_for_review() { 2192 $this->resetAfterTest(true); 2193 $dg = $this->getDataGenerator(); 2194 $lpg = $dg->get_plugin_generator('core_competency'); 2195 2196 $u1 = $dg->create_user(); 2197 $u1ctx = context_user::instance($u1->id); 2198 $f1 = $lpg->create_framework(); 2199 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2200 2201 // Non-existing user competencies are created up for review. 2202 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 2203 'error', null, true); 2204 $uc = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2205 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status()); 2206 2207 // Existing user competencies sent for review don't change. 2208 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 2209 'error', null, true); 2210 $uc->read(); 2211 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status()); 2212 2213 // A user competency with a status non-idle won't change. 2214 $uc->set_status(\core_competency\user_competency::STATUS_IN_REVIEW); 2215 $uc->update(); 2216 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \core_competency\evidence::ACTION_LOG, 'invaliddata', 2217 'error', null, true); 2218 $uc->read(); 2219 $this->assertEquals(\core_competency\user_competency::STATUS_IN_REVIEW, $uc->get_status()); 2220 } 2221 2222 /** 2223 * Test add evidence for existing user_competency. 2224 */ 2225 public function test_add_evidence_existing_user_competency() { 2226 $this->resetAfterTest(true); 2227 $dg = $this->getDataGenerator(); 2228 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2229 2230 $syscontext = context_system::instance(); 2231 2232 // Create users. 2233 $user = $dg->create_user(); 2234 $this->setUser($user); 2235 2236 // Create a framework and assign competencies. 2237 $framework = $lpg->create_framework(); 2238 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2239 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2240 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2241 $uc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id())); 2242 $this->assertSame(null, $uc->get_grade()); 2243 $this->assertSame(null, $uc->get_proficiency()); 2244 2245 // Create an evidence and check it was created with the right usercomptencyid and information. 2246 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \core_competency\evidence::ACTION_OVERRIDE, 2247 'invalidevidencedesc', 'core_competency', array('a' => 'b'), false, 'http://moodle.org', 1, 2); 2248 $this->assertEquals(1, \core_competency\evidence::count_records()); 2249 2250 $evidence->read(); 2251 $uc->read(); 2252 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2253 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier()); 2254 $this->assertEquals('core_competency', $evidence->get_desccomponent()); 2255 $this->assertEquals((object) array('a' => 'b'), $evidence->get_desca()); 2256 $this->assertEquals('http://moodle.org', $evidence->get_url()); 2257 $this->assertEquals(\core_competency\evidence::ACTION_OVERRIDE, $evidence->get_action()); 2258 $this->assertEquals(2, $evidence->get_actionuserid()); 2259 $this->assertEquals(1, $evidence->get_grade()); 2260 $this->assertEquals(1, $uc->get_grade()); 2261 $this->assertEquals(0, $uc->get_proficiency()); 2262 } 2263 2264 /** 2265 * Test add evidence for non-existing user_competency. 2266 */ 2267 public function test_add_evidence_no_existing_user_competency() { 2268 $this->resetAfterTest(true); 2269 $dg = $this->getDataGenerator(); 2270 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2271 2272 $syscontext = context_system::instance(); 2273 2274 // Create users. 2275 $user = $dg->create_user(); 2276 $this->setUser($user); 2277 2278 // Create a framework and assign competencies. 2279 $framework = $lpg->create_framework(); 2280 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2281 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2282 $this->assertEquals(0, \core_competency\user_competency::count_records()); 2283 2284 // Create an evidence without a user competency record. 2285 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \core_competency\evidence::ACTION_OVERRIDE, 2286 'invalidevidencedesc', 'core_competency', 'Hello world!', false, 'http://moodle.org', 1, 2); 2287 $this->assertEquals(1, \core_competency\evidence::count_records()); 2288 $this->assertEquals(1, \core_competency\user_competency::count_records()); 2289 2290 $uc = \core_competency\user_competency::get_record(array('userid' => $user->id, 'competencyid' => $c1->get_id())); 2291 $evidence->read(); 2292 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 2293 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier()); 2294 $this->assertEquals('core_competency', $evidence->get_desccomponent()); 2295 $this->assertEquals('Hello world!', $evidence->get_desca()); 2296 $this->assertEquals('http://moodle.org', $evidence->get_url()); 2297 $this->assertEquals(\core_competency\evidence::ACTION_OVERRIDE, $evidence->get_action()); 2298 $this->assertEquals(2, $evidence->get_actionuserid()); 2299 $this->assertEquals(1, $evidence->get_grade()); 2300 $this->assertEquals(1, $uc->get_grade()); 2301 $this->assertEquals(0, $uc->get_proficiency()); 2302 } 2303 2304 public function test_add_evidence_applies_competency_rules() { 2305 $this->resetAfterTest(true); 2306 $dg = $this->getDataGenerator(); 2307 $lpg = $dg->get_plugin_generator('core_competency'); 2308 $syscontext = context_system::instance(); 2309 $ctxid = $syscontext->id; 2310 2311 $u1 = $dg->create_user(); 2312 2313 // Setting up the framework. 2314 $f1 = $lpg->create_framework(); 2315 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2316 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 2317 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 2318 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2319 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c2->get_id())); 2320 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2321 $c3a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c3->get_id())); 2322 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2323 $c4a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c4->get_id())); 2324 $c5 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2325 2326 // Setting up the rules. 2327 $c1->set_ruletype('core_competency\\competency_rule_all'); 2328 $c1->set_ruleoutcome(\core_competency\competency::OUTCOME_COMPLETE); 2329 $c1->update(); 2330 $c2->set_ruletype('core_competency\\competency_rule_all'); 2331 $c2->set_ruleoutcome(\core_competency\competency::OUTCOME_RECOMMEND); 2332 $c2->update(); 2333 $c3->set_ruletype('core_competency\\competency_rule_all'); 2334 $c3->set_ruleoutcome(\core_competency\competency::OUTCOME_EVIDENCE); 2335 $c3->update(); 2336 $c4->set_ruletype('core_competency\\competency_rule_all'); 2337 $c4->set_ruleoutcome(\core_competency\competency::OUTCOME_NONE); 2338 $c4->update(); 2339 2340 // Confirm the current data. 2341 $this->assertEquals(0, user_competency::count_records()); 2342 $this->assertEquals(0, evidence::count_records()); 2343 2344 // Let's do this! 2345 // First let's confirm that evidence not marking a completion have no impact. 2346 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_LOG, 'commentincontext', 'core'); 2347 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id())); 2348 $this->assertSame(null, $uc1a->get_proficiency()); 2349 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c1->get_id()))); 2350 2351 // Now let's try complete a competency but the rule won't match (not all children are complete). 2352 // The parent (the thing with the rule) will be created but won't have any evidence attached, and not 2353 // not be marked as completed. 2354 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2355 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id())); 2356 $this->assertEquals(true, $uc1a->get_proficiency()); 2357 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2358 $this->assertSame(null, $uc1->get_proficiency()); 2359 $this->assertEquals(0, evidence::count_records(array('usercompetencyid' => $uc1->get_id()))); 2360 2361 // Now we complete the other child. That will mark the parent as complete with an evidence. 2362 api::add_evidence($u1->id, $c1b, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2363 $uc1b = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1b->get_id())); 2364 $this->assertEquals(true, $uc1a->get_proficiency()); 2365 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); 2366 $this->assertEquals(true, $uc1->get_proficiency()); 2367 $this->assertEquals(user_competency::STATUS_IDLE, $uc1->get_status()); 2368 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc1->get_id()))); 2369 2370 // Check rule recommending. 2371 api::add_evidence($u1->id, $c2a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2372 $uc2a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2a->get_id())); 2373 $this->assertEquals(true, $uc1a->get_proficiency()); 2374 $uc2 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); 2375 $this->assertSame(null, $uc2->get_proficiency()); 2376 $this->assertEquals(user_competency::STATUS_WAITING_FOR_REVIEW, $uc2->get_status()); 2377 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc2->get_id()))); 2378 2379 // Check rule evidence. 2380 api::add_evidence($u1->id, $c3a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2381 $uc3a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3a->get_id())); 2382 $this->assertEquals(true, $uc1a->get_proficiency()); 2383 $uc3 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id())); 2384 $this->assertSame(null, $uc3->get_proficiency()); 2385 $this->assertEquals(user_competency::STATUS_IDLE, $uc3->get_status()); 2386 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc3->get_id()))); 2387 2388 // Check rule nothing. 2389 api::add_evidence($u1->id, $c4a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2390 $uc4a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4a->get_id())); 2391 $this->assertEquals(true, $uc1a->get_proficiency()); 2392 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c4->get_id()))); 2393 2394 // Check marking on something that has no parent. This just checks that nothing breaks. 2395 api::add_evidence($u1->id, $c5, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core'); 2396 } 2397 2398 /** 2399 * Tests for the user_competency_course data when api::add_evidence() is invoked when 2400 * grading a user competency in the system context. 2401 */ 2402 public function test_add_evidence_for_user_competency_course_grade_outside_course() { 2403 $this->resetAfterTest(true); 2404 $dg = $this->getDataGenerator(); 2405 $syscontext = context_system::instance(); 2406 2407 // Create a student. 2408 $student = $dg->create_user(); 2409 2410 // Create a competency for the course. 2411 $lpg = $dg->get_plugin_generator('core_competency'); 2412 $framework = $lpg->create_framework(); 2413 $comp = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2414 2415 // Add evidence. 2416 api::add_evidence($student->id, $comp, $syscontext, evidence::ACTION_OVERRIDE, 2417 'commentincontext', 'core', null, false, null, 1); 2418 2419 // Query for user_competency_course data. 2420 $filterparams = array( 2421 'userid' => $student->id, 2422 'competencyid' => $comp->get_id(), 2423 ); 2424 $usercompcourse = \core_competency\user_competency_course::get_record($filterparams); 2425 // There should be no user_competency_course object created when grading. 2426 $this->assertFalse($usercompcourse); 2427 } 2428 2429 /** 2430 * Tests for the user_competency_course data when api::add_evidence() is invoked when 2431 * grading a user competency in a course. 2432 */ 2433 public function test_add_evidence_user_competency_course_grade_in_course() { 2434 global $USER; 2435 2436 $this->resetAfterTest(true); 2437 $dg = $this->getDataGenerator(); 2438 2439 // Create a course. 2440 $course = $dg->create_course(); 2441 $record = array('courseid' => $course->id, 'pushratingstouserplans' => false); 2442 $settings = new course_competency_settings(0, (object) $record); 2443 $settings->create(); 2444 $coursecontext = context_course::instance($course->id); 2445 2446 // Create a student and enrol into the course. 2447 $student = $dg->create_user(); 2448 $studentarch = get_archetype_roles('student'); 2449 $studentrole = array_shift($studentarch); 2450 $dg->role_assign($studentrole->id, $student->id, $coursecontext->id); 2451 $dg->enrol_user($student->id, $course->id, $studentrole->id); 2452 2453 // Create a competency for the course. 2454 $lpg = $dg->get_plugin_generator('core_competency'); 2455 $framework = $lpg->create_framework(); 2456 // Do not push ratings from course to user plans. 2457 $comp = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2458 $lpg->create_course_competency(array('courseid' => $course->id, 'competencyid' => $comp->get_id())); 2459 2460 // Query for user_competency_course data. 2461 $filterparams = array( 2462 'userid' => $student->id, 2463 'competencyid' => $comp->get_id(), 2464 'courseid' => $course->id 2465 ); 2466 2467 // Add evidence that sets a grade to the course. 2468 $evidence = api::add_evidence($student->id, $comp, $coursecontext, evidence::ACTION_OVERRIDE, 2469 'commentincontext', 'core', null, false, null, 3, $USER->id); 2470 // Get user competency course record. 2471 $usercompcourse = \core_competency\user_competency_course::get_record($filterparams); 2472 // There should be a user_competency_course object when adding a grade. 2473 $this->assertNotEmpty($usercompcourse); 2474 $grade = $evidence->get_grade(); 2475 $this->assertEquals($grade, $usercompcourse->get_grade()); 2476 $this->assertEquals(3, $usercompcourse->get_grade()); 2477 $proficiency = $comp->get_proficiency_of_grade($grade); 2478 $this->assertEquals($proficiency, $usercompcourse->get_proficiency()); 2479 2480 // Confirm that the user competency's grade/proficiency has not been affected by the grade. 2481 $usercompetencyparams = [ 2482 'userid' => $student->id, 2483 'competencyid' => $comp->get_id(), 2484 ]; 2485 $usercompetency = \core_competency\user_competency::get_record($usercompetencyparams); 2486 $this->assertNotEmpty($usercompetency); 2487 $this->assertNotEquals($usercompcourse->get_grade(), $usercompetency->get_grade()); 2488 $this->assertNotEquals($usercompcourse->get_proficiency(), $usercompetency->get_proficiency()); 2489 } 2490 2491 public function test_observe_course_completed() { 2492 $this->resetAfterTest(true); 2493 $dg = $this->getDataGenerator(); 2494 $lpg = $dg->get_plugin_generator('core_competency'); 2495 2496 // Set-up users, framework, competencies and course competencies. 2497 $course = $dg->create_course(); 2498 $coursectx = context_course::instance($course->id); 2499 $u1 = $dg->create_user(); 2500 $f1 = $lpg->create_framework(); 2501 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2502 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2503 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2504 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2505 $cc1 = $lpg->create_course_competency(array('competencyid' => $c1->get_id(), 'courseid' => $course->id, 2506 'ruleoutcome' => \core_competency\course_competency::OUTCOME_NONE)); 2507 $cc2 = $lpg->create_course_competency(array('competencyid' => $c2->get_id(), 'courseid' => $course->id, 2508 'ruleoutcome' => \core_competency\course_competency::OUTCOME_EVIDENCE)); 2509 $cc3 = $lpg->create_course_competency(array('competencyid' => $c3->get_id(), 'courseid' => $course->id, 2510 'ruleoutcome' => \core_competency\course_competency::OUTCOME_RECOMMEND)); 2511 $cc4 = $lpg->create_course_competency(array('competencyid' => $c4->get_id(), 'courseid' => $course->id, 2512 'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE)); 2513 2514 $event = \core\event\course_completed::create(array( 2515 'objectid' => 1, 2516 'relateduserid' => $u1->id, 2517 'context' => $coursectx, 2518 'courseid' => $course->id, 2519 'other' => array('relateduserid' => $u1->id) 2520 )); 2521 $this->assertEquals(0, \core_competency\user_competency::count_records()); 2522 $this->assertEquals(0, \core_competency\evidence::count_records()); 2523 2524 // Let's go! 2525 api::observe_course_completed($event); 2526 $this->assertEquals(3, \core_competency\user_competency::count_records()); 2527 $this->assertEquals(3, \core_competency\evidence::count_records()); 2528 2529 // Outcome NONE did nothing. 2530 $this->assertFalse(\core_competency\user_competency::record_exists_select('userid = :uid AND competencyid = :cid', array( 2531 'uid' => $u1->id, 'cid' => $c1->get_id() 2532 ))); 2533 2534 // Outcome evidence. 2535 $uc2 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); 2536 $ev2 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc2->get_id())); 2537 2538 $this->assertEquals(null, $uc2->get_grade()); 2539 $this->assertEquals(null, $uc2->get_proficiency()); 2540 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc2->get_status()); 2541 2542 $this->assertEquals('evidence_coursecompleted', $ev2->get_descidentifier()); 2543 $this->assertEquals('core_competency', $ev2->get_desccomponent()); 2544 $this->assertEquals($course->shortname, $ev2->get_desca()); 2545 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev2->get_url()); 2546 $this->assertEquals(null, $ev2->get_grade()); 2547 $this->assertEquals($coursectx->id, $ev2->get_contextid()); 2548 $this->assertEquals(\core_competency\evidence::ACTION_LOG, $ev2->get_action()); 2549 $this->assertEquals(null, $ev2->get_actionuserid()); 2550 2551 // Outcome recommend. 2552 $uc3 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id())); 2553 $ev3 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc3->get_id())); 2554 2555 $this->assertEquals(null, $uc3->get_grade()); 2556 $this->assertEquals(null, $uc3->get_proficiency()); 2557 $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc3->get_status()); 2558 2559 $this->assertEquals('evidence_coursecompleted', $ev3->get_descidentifier()); 2560 $this->assertEquals('core_competency', $ev3->get_desccomponent()); 2561 $this->assertEquals($course->shortname, $ev3->get_desca()); 2562 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev3->get_url()); 2563 $this->assertEquals(null, $ev3->get_grade()); 2564 $this->assertEquals($coursectx->id, $ev3->get_contextid()); 2565 $this->assertEquals(\core_competency\evidence::ACTION_LOG, $ev3->get_action()); 2566 $this->assertEquals(null, $ev3->get_actionuserid()); 2567 2568 // Outcome complete. 2569 $uc4 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4->get_id())); 2570 $ev4 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc4->get_id())); 2571 2572 $this->assertEquals(3, $uc4->get_grade()); 2573 $this->assertEquals(1, $uc4->get_proficiency()); 2574 $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc4->get_status()); 2575 2576 $this->assertEquals('evidence_coursecompleted', $ev4->get_descidentifier()); 2577 $this->assertEquals('core_competency', $ev4->get_desccomponent()); 2578 $this->assertEquals($course->shortname, $ev4->get_desca()); 2579 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev4->get_url()); 2580 $this->assertEquals(3, $ev4->get_grade()); 2581 $this->assertEquals($coursectx->id, $ev4->get_contextid()); 2582 $this->assertEquals(\core_competency\evidence::ACTION_COMPLETE, $ev4->get_action()); 2583 $this->assertEquals(null, $ev4->get_actionuserid()); 2584 } 2585 2586 public function test_list_evidence_in_course() { 2587 global $SITE; 2588 2589 $this->resetAfterTest(true); 2590 $dg = $this->getDataGenerator(); 2591 $lpg = $dg->get_plugin_generator('core_competency'); 2592 $u1 = $dg->create_user(); 2593 $course = $dg->create_course(); 2594 $coursecontext = context_course::instance($course->id); 2595 2596 $this->setAdminUser(); 2597 $f = $lpg->create_framework(); 2598 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 2599 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 2600 $cc = api::add_competency_to_course($course->id, $c->get_id()); 2601 $cc2 = api::add_competency_to_course($course->id, $c2->get_id()); 2602 2603 $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page'); 2604 $page = $pagegenerator->create_instance(array('course' => $course->id)); 2605 2606 $cm = get_coursemodule_from_instance('page', $page->id); 2607 $cmcontext = context_module::instance($cm->id); 2608 // Add the competency to the course module. 2609 $ccm = api::add_competency_to_course_module($cm, $c->get_id()); 2610 2611 // Now add the evidence to the course. 2612 $evidence1 = api::add_evidence($u1->id, $c->get_id(), $coursecontext->id, \core_competency\evidence::ACTION_LOG, 2613 'invaliddata', 'error'); 2614 2615 $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id()); 2616 $this->assertEquals($result[0]->get_id(), $evidence1->get_id()); 2617 2618 // Now add the evidence to the course module. 2619 $evidence2 = api::add_evidence($u1->id, $c->get_id(), $cmcontext->id, \core_competency\evidence::ACTION_LOG, 2620 'invaliddata', 'error'); 2621 2622 $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id(), 'timecreated', 'ASC'); 2623 $this->assertEquals($evidence1->get_id(), $result[0]->get_id()); 2624 $this->assertEquals($evidence2->get_id(), $result[1]->get_id()); 2625 } 2626 2627 public function test_list_course_modules_using_competency() { 2628 global $SITE; 2629 2630 $this->resetAfterTest(true); 2631 $dg = $this->getDataGenerator(); 2632 $lpg = $dg->get_plugin_generator('core_competency'); 2633 $u1 = $dg->create_user(); 2634 $u2 = $dg->create_user(); 2635 $course = $dg->create_course(); 2636 $course2 = $dg->create_course(); 2637 2638 $this->setAdminUser(); 2639 $f = $lpg->create_framework(); 2640 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 2641 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 2642 $cc = api::add_competency_to_course($course->id, $c->get_id()); 2643 $cc2 = api::add_competency_to_course($course->id, $c2->get_id()); 2644 2645 // First check we get an empty list when there are no links. 2646 $expected = array(); 2647 $result = api::list_course_modules_using_competency($c->get_id(), $course->id); 2648 $this->assertEquals($expected, $result); 2649 2650 $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page'); 2651 $page = $pagegenerator->create_instance(array('course' => $course->id)); 2652 2653 $cm = get_coursemodule_from_instance('page', $page->id); 2654 // Add a link and list again. 2655 $ccm = api::add_competency_to_course_module($cm, $c->get_id()); 2656 $expected = array($cm->id); 2657 $result = api::list_course_modules_using_competency($c->get_id(), $course->id); 2658 $this->assertEquals($expected, $result); 2659 2660 // Check a different course. 2661 $expected = array(); 2662 $result = api::list_course_modules_using_competency($c->get_id(), $course2->id); 2663 $this->assertEquals($expected, $result); 2664 2665 // Remove the link and check again. 2666 $result = api::remove_competency_from_course_module($cm, $c->get_id()); 2667 $expected = true; 2668 $this->assertEquals($expected, $result); 2669 $expected = array(); 2670 $result = api::list_course_modules_using_competency($c->get_id(), $course->id); 2671 $this->assertEquals($expected, $result); 2672 2673 // Now add 2 links. 2674 api::add_competency_to_course_module($cm, $c->get_id()); 2675 api::add_competency_to_course_module($cm, $c2->get_id()); 2676 $result = api::list_course_module_competencies_in_course_module($cm->id); 2677 $this->assertEquals($result[0]->get_competencyid(), $c->get_id()); 2678 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id()); 2679 2680 // Now re-order. 2681 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id()); 2682 $result = api::list_course_module_competencies_in_course_module($cm->id); 2683 $this->assertEquals($result[0]->get_competencyid(), $c2->get_id()); 2684 $this->assertEquals($result[1]->get_competencyid(), $c->get_id()); 2685 2686 // And re-order again. 2687 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id()); 2688 $result = api::list_course_module_competencies_in_course_module($cm->id); 2689 $this->assertEquals($result[0]->get_competencyid(), $c->get_id()); 2690 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id()); 2691 } 2692 2693 /** 2694 * Test update ruleoutcome for course_competency. 2695 */ 2696 public function test_set_ruleoutcome_course_competency() { 2697 $this->resetAfterTest(true); 2698 $dg = $this->getDataGenerator(); 2699 $lpg = $dg->get_plugin_generator('core_competency'); 2700 $u1 = $dg->create_user(); 2701 $u2 = $dg->create_user(); 2702 $course = $dg->create_course(); 2703 2704 $this->setAdminUser(); 2705 $f = $lpg->create_framework(); 2706 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 2707 $cc = api::add_competency_to_course($course->id, $c->get_id()); 2708 2709 // Check record was created with default rule value Evidence. 2710 $this->assertEquals(1, \core_competency\course_competency::count_records()); 2711 $recordscc = api::list_course_competencies($course->id); 2712 $this->assertEquals(\core_competency\course_competency::OUTCOME_EVIDENCE, 2713 $recordscc[0]['coursecompetency']->get_ruleoutcome()); 2714 2715 // Check ruleoutcome value is updated to None. 2716 $this->assertTrue(api::set_course_competency_ruleoutcome($recordscc[0]['coursecompetency']->get_id(), 2717 \core_competency\course_competency::OUTCOME_NONE)); 2718 $recordscc = api::list_course_competencies($course->id); 2719 $this->assertEquals(\core_competency\course_competency::OUTCOME_NONE, $recordscc[0]['coursecompetency']->get_ruleoutcome()); 2720 } 2721 2722 /** 2723 * Test validation on grade on user_competency. 2724 */ 2725 public function test_validate_grade_in_user_competency() { 2726 global $DB; 2727 2728 $this->resetAfterTest(true); 2729 $this->setAdminUser(); 2730 $dg = $this->getDataGenerator(); 2731 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2732 $user = $dg->create_user(); 2733 2734 $s1 = $dg->create_scale(array("scale" => "value1, value2")); 2735 $s2 = $dg->create_scale(array("scale" => "value3, value4, value5, value6")); 2736 2737 $scaleconfiguration1 = '[{"scaleid":"'.$s1->id.'"},{"name":"value1","id":1,"scaledefault":1,"proficient":0},' . 2738 '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]'; 2739 $scaleconfiguration2 = '[{"scaleid":"'.$s2->id.'"},{"name":"value3","id":1,"scaledefault":1,"proficient":0},' 2740 . '{"name":"value4","id":2,"scaledefault":0,"proficient":1}]'; 2741 2742 // Create a framework with scale configuration1. 2743 $frm = array( 2744 'scaleid' => $s1->id, 2745 'scaleconfiguration' => $scaleconfiguration1 2746 ); 2747 $framework = $lpg->create_framework($frm); 2748 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2749 2750 // Create competency with its own scale configuration. 2751 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 2752 'scaleid' => $s2->id, 2753 'scaleconfiguration' => $scaleconfiguration2 2754 )); 2755 2756 // Detecte invalid grade in competency using its framework competency scale. 2757 try { 2758 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(), 2759 'proficiency' => true, 'grade' => 3 )); 2760 $usercompetency->create(); 2761 $this->fail('Invalid grade not detected in framework scale'); 2762 } catch (\core_competency\invalid_persistent_exception $e) { 2763 $this->assertTrue(true); 2764 } 2765 2766 // Detecte invalid grade in competency using its own scale. 2767 try { 2768 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(), 2769 'proficiency' => true, 'grade' => 5 )); 2770 $usercompetency->create(); 2771 $this->fail('Invalid grade not detected in competency scale'); 2772 } catch (\core_competency\invalid_persistent_exception $e) { 2773 $this->assertTrue(true); 2774 } 2775 2776 // Accept valid grade in competency using its framework competency scale. 2777 try { 2778 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(), 2779 'proficiency' => true, 'grade' => 1 )); 2780 $usercompetency->create(); 2781 $this->assertTrue(true); 2782 } catch (\core_competency\invalid_persistent_exception $e) { 2783 $this->fail('Valide grade rejected in framework scale'); 2784 } 2785 2786 // Accept valid grade in competency using its framework competency scale. 2787 try { 2788 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(), 2789 'proficiency' => true, 'grade' => 4 )); 2790 $usercompetency->create(); 2791 $this->assertTrue(true); 2792 } catch (\core_competency\invalid_persistent_exception $e) { 2793 $this->fail('Valide grade rejected in competency scale'); 2794 } 2795 } 2796 2797 /** 2798 * Test when adding competency that belong to hidden framework to plan/template/course. 2799 */ 2800 public function test_hidden_framework() { 2801 $this->resetAfterTest(true); 2802 $this->setAdminUser(); 2803 $dg = $this->getDataGenerator(); 2804 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2805 $user = $dg->create_user(); 2806 2807 // Create a course. 2808 $cat1 = $dg->create_category(); 2809 $course = $dg->create_course(array('category' => $cat1->id)); 2810 // Create a template. 2811 $template = $lpg->create_template(); 2812 // Create a plan. 2813 $plan = $lpg->create_plan(array('userid' => $user->id)); 2814 2815 // Create a hidden framework. 2816 $frm = array( 2817 'visible' => false 2818 ); 2819 $framework = $lpg->create_framework($frm); 2820 $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2821 2822 // Linking competency that belong to hidden framework to course. 2823 try { 2824 api::add_competency_to_course($course->id, $competency->get_id()); 2825 $this->fail('A competency belonging to hidden framework can not be linked to course'); 2826 } catch (coding_exception $e) { 2827 $this->assertTrue(true); 2828 } 2829 2830 // Adding competency that belong to hidden framework to template. 2831 try { 2832 api::add_competency_to_template($template->get_id(), $competency->get_id()); 2833 $this->fail('A competency belonging to hidden framework can not be added to template'); 2834 } catch (coding_exception $e) { 2835 $this->assertTrue(true); 2836 } 2837 2838 // Adding competency that belong to hidden framework to plan. 2839 try { 2840 api::add_competency_to_plan($plan->get_id(), $competency->get_id()); 2841 $this->fail('A competency belonging to hidden framework can not be added to plan'); 2842 } catch (coding_exception $e) { 2843 $this->assertTrue(true); 2844 } 2845 } 2846 2847 /** 2848 * Test when using hidden template in plan/cohort. 2849 */ 2850 public function test_hidden_template() { 2851 $this->resetAfterTest(true); 2852 $this->setAdminUser(); 2853 $dg = $this->getDataGenerator(); 2854 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2855 $user = $dg->create_user(); 2856 2857 // Create a cohort. 2858 $cohort = $dg->create_cohort(); 2859 // Create a hidden template. 2860 $template = $lpg->create_template(array('visible' => false)); 2861 2862 // Can not link hidden template to plan. 2863 try { 2864 api::create_plan_from_template($template->get_id(), $user->id); 2865 $this->fail('Can not link a hidden template to plan'); 2866 } catch (coding_exception $e) { 2867 $this->assertTrue(true); 2868 } 2869 2870 // Can associate hidden template to cohort. 2871 $templatecohort = api::create_template_cohort($template->get_id(), $cohort->id); 2872 $this->assertInstanceOf('\core_competency\template_cohort', $templatecohort); 2873 } 2874 2875 /** 2876 * Test that completed plan created form a template does not change when template is modified. 2877 */ 2878 public function test_completed_plan_doesnot_change() { 2879 global $DB; 2880 2881 $this->resetAfterTest(true); 2882 $this->setAdminUser(); 2883 $dg = $this->getDataGenerator(); 2884 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 2885 $user = $dg->create_user(); 2886 2887 // Create a framework and assign competencies. 2888 $framework = $lpg->create_framework(); 2889 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2890 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2891 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2892 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 2893 2894 // Create template and assign competencies. 2895 $tp = $lpg->create_template(); 2896 $tpc1 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c1->get_id())); 2897 $tpc2 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c2->get_id())); 2898 $tpc3 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c3->get_id())); 2899 2900 // Create a plan form template and change it status to complete. 2901 $plan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tp->get_id())); 2902 api::complete_plan($plan); 2903 2904 // Check user competency plan created correctly. 2905 $this->assertEquals(3, \core_competency\user_competency_plan::count_records()); 2906 $ucp = \core_competency\user_competency_plan::get_records(); 2907 $this->assertEquals($ucp[0]->get_competencyid(), $c1->get_id()); 2908 $this->assertEquals($ucp[1]->get_competencyid(), $c2->get_id()); 2909 $this->assertEquals($ucp[2]->get_competencyid(), $c3->get_id()); 2910 2911 // Add and remove a competency from the template. 2912 api::add_competency_to_template($tp->get_id(), $c4->get_id()); 2913 api::remove_competency_from_template($tp->get_id(), $c1->get_id()); 2914 2915 // Check that user competency plan did not change. 2916 $competencies = $plan->get_competencies(); 2917 $this->assertEquals(3, count($competencies)); 2918 $ucp1 = array($c1->get_id(), $c2->get_id(), $c3->get_id()); 2919 $ucp2 = array(); 2920 foreach ($competencies as $id => $cmp) { 2921 $ucp2[] = $id; 2922 } 2923 $this->assertEquals(0, count(array_diff($ucp1, $ucp2))); 2924 } 2925 2926 protected function setup_framework_for_reset_rules_tests() { 2927 $this->resetAfterTest(true); 2928 $dg = $this->getDataGenerator(); 2929 $lpg = $dg->get_plugin_generator('core_competency'); 2930 2931 $this->setAdminUser(); 2932 $f1 = $lpg->create_framework(); 2933 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2934 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 2935 $c1a1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 2936 $c1a1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a1->get_id())); 2937 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2938 $c1b1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 2939 $c1b1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b1->get_id())); 2940 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2941 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 2942 2943 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 2944 $c1->set_ruletype('core_competency\\competency_rule_all'); 2945 $c1->update(); 2946 $c1a->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 2947 $c1a->set_ruletype('core_competency\\competency_rule_all'); 2948 $c1a->update(); 2949 $c1a1->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 2950 $c1a1->set_ruletype('core_competency\\competency_rule_all'); 2951 $c1a1->update(); 2952 $c1b->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 2953 $c1b->set_ruletype('core_competency\\competency_rule_all'); 2954 $c1b->update(); 2955 $c2->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 2956 $c2->set_ruletype('core_competency\\competency_rule_all'); 2957 $c2->update(); 2958 2959 return array( 2960 'f1' => $f1, 2961 'c1' => $c1, 2962 'c1a' => $c1a, 2963 'c1a1' => $c1a1, 2964 'c1a1a' => $c1a1a, 2965 'c1b' => $c1b, 2966 'c1b1' => $c1b1, 2967 'c1b1a' => $c1b1a, 2968 'c2' => $c2, 2969 'c2a' => $c2a, 2970 ); 2971 } 2972 2973 public function test_moving_competency_reset_rules_updown() { 2974 $data = $this->setup_framework_for_reset_rules_tests(); 2975 $f1 = $data['f1']; 2976 $c1 = $data['c1']; 2977 $c1a = $data['c1a']; 2978 $c1a1 = $data['c1a1']; 2979 $c1a1a = $data['c1a1a']; 2980 $c1b = $data['c1b']; 2981 $c1b1 = $data['c1b1']; 2982 $c1b1a = $data['c1b1a']; 2983 $c2 = $data['c2']; 2984 $c2a = $data['c2a']; 2985 2986 // Moving up and down doesn't change anything. 2987 api::move_down_competency($c1a->get_id()); 2988 $c1->read(); 2989 $c1a->read(); 2990 $c1a1->read(); 2991 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome()); 2992 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome()); 2993 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome()); 2994 api::move_up_competency($c1a->get_id()); 2995 $c1->read(); 2996 $c1a->read(); 2997 $c1a1->read(); 2998 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome()); 2999 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome()); 3000 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome()); 3001 } 3002 3003 public function test_moving_competency_reset_rules_parent() { 3004 $data = $this->setup_framework_for_reset_rules_tests(); 3005 $f1 = $data['f1']; 3006 $c1 = $data['c1']; 3007 $c1a = $data['c1a']; 3008 $c1a1 = $data['c1a1']; 3009 $c1a1a = $data['c1a1a']; 3010 $c1b = $data['c1b']; 3011 $c1b1 = $data['c1b1']; 3012 $c1b1a = $data['c1b1a']; 3013 $c2 = $data['c2']; 3014 $c2a = $data['c2a']; 3015 3016 // Moving out of parent will reset the parent, and the destination. 3017 api::set_parent_competency($c1a->get_id(), $c1b->get_id()); 3018 $c1->read(); 3019 $c1a->read(); 3020 $c1a1->read(); 3021 $c1b->read(); 3022 $c2->read(); 3023 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome()); 3024 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome()); 3025 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome()); 3026 $this->assertEquals(competency::OUTCOME_NONE, $c1b->get_ruleoutcome()); 3027 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3028 } 3029 3030 public function test_moving_competency_reset_rules_totoplevel() { 3031 $data = $this->setup_framework_for_reset_rules_tests(); 3032 $f1 = $data['f1']; 3033 $c1 = $data['c1']; 3034 $c1a = $data['c1a']; 3035 $c1a1 = $data['c1a1']; 3036 $c1a1a = $data['c1a1a']; 3037 $c1b = $data['c1b']; 3038 $c1b1 = $data['c1b1']; 3039 $c1b1a = $data['c1b1a']; 3040 $c2 = $data['c2']; 3041 $c2a = $data['c2a']; 3042 3043 // Moving to top level only affects the initial parent. 3044 api::set_parent_competency($c1a1->get_id(), 0); 3045 $c1->read(); 3046 $c1a->read(); 3047 $c1a1->read(); 3048 $c1b->read(); 3049 $c2->read(); 3050 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome()); 3051 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome()); 3052 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome()); 3053 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome()); 3054 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3055 } 3056 3057 public function test_moving_competency_reset_rules_fromtoplevel() { 3058 $data = $this->setup_framework_for_reset_rules_tests(); 3059 $f1 = $data['f1']; 3060 $c1 = $data['c1']; 3061 $c1a = $data['c1a']; 3062 $c1a1 = $data['c1a1']; 3063 $c1a1a = $data['c1a1a']; 3064 $c1b = $data['c1b']; 3065 $c1b1 = $data['c1b1']; 3066 $c1b1a = $data['c1b1a']; 3067 $c2 = $data['c2']; 3068 $c2a = $data['c2a']; 3069 3070 // Moving from top level only affects the destination parent. 3071 api::set_parent_competency($c2->get_id(), $c1a1->get_id()); 3072 $c1->read(); 3073 $c1a->read(); 3074 $c1a1->read(); 3075 $c1b->read(); 3076 $c2->read(); 3077 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome()); 3078 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome()); 3079 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome()); 3080 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome()); 3081 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3082 } 3083 3084 public function test_moving_competency_reset_rules_child() { 3085 $data = $this->setup_framework_for_reset_rules_tests(); 3086 $f1 = $data['f1']; 3087 $c1 = $data['c1']; 3088 $c1a = $data['c1a']; 3089 $c1a1 = $data['c1a1']; 3090 $c1a1a = $data['c1a1a']; 3091 $c1b = $data['c1b']; 3092 $c1b1 = $data['c1b1']; 3093 $c1b1a = $data['c1b1a']; 3094 $c2 = $data['c2']; 3095 $c2a = $data['c2a']; 3096 3097 // Moving to a child of self resets self, parent and destination. 3098 api::set_parent_competency($c1a->get_id(), $c1a1->get_id()); 3099 $c1->read(); 3100 $c1a->read(); 3101 $c1a1->read(); 3102 $c1b->read(); 3103 $c2->read(); 3104 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome()); 3105 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome()); 3106 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome()); 3107 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome()); 3108 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3109 } 3110 3111 public function test_create_competency_reset_rules() { 3112 $data = $this->setup_framework_for_reset_rules_tests(); 3113 $f1 = $data['f1']; 3114 $c1 = $data['c1']; 3115 $c1a = $data['c1a']; 3116 $c1a1 = $data['c1a1']; 3117 $c1a1a = $data['c1a1a']; 3118 $c1b = $data['c1b']; 3119 $c1b1 = $data['c1b1']; 3120 $c1b1a = $data['c1b1a']; 3121 $c2 = $data['c2']; 3122 $c2a = $data['c2a']; 3123 3124 // Adding a new competency resets the rule of its parent. 3125 api::create_competency((object) array('shortname' => 'A', 'parentid' => $c1->get_id(), 'idnumber' => 'A', 3126 'competencyframeworkid' => $f1->get_id())); 3127 $c1->read(); 3128 $c1a->read(); 3129 $c1a1->read(); 3130 $c1b->read(); 3131 $c2->read(); 3132 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome()); 3133 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome()); 3134 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome()); 3135 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome()); 3136 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3137 } 3138 3139 public function test_delete_competency_reset_rules() { 3140 $data = $this->setup_framework_for_reset_rules_tests(); 3141 $f1 = $data['f1']; 3142 $c1 = $data['c1']; 3143 $c1a = $data['c1a']; 3144 $c1a1 = $data['c1a1']; 3145 $c1a1a = $data['c1a1a']; 3146 $c1b = $data['c1b']; 3147 $c1b1 = $data['c1b1']; 3148 $c1b1a = $data['c1b1a']; 3149 $c2 = $data['c2']; 3150 $c2a = $data['c2a']; 3151 3152 // Deleting a competency resets the rule of its parent. 3153 api::delete_competency($c1a->get_id()); 3154 $c1->read(); 3155 $c1b->read(); 3156 $c2->read(); 3157 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome()); 3158 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome()); 3159 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome()); 3160 } 3161 3162 public function test_template_has_related_data() { 3163 $this->resetAfterTest(true); 3164 $this->setAdminUser(); 3165 3166 $dg = $this->getDataGenerator(); 3167 $user = $dg->create_user(); 3168 $lpg = $dg->get_plugin_generator('core_competency'); 3169 $tpl1 = $lpg->create_template(); 3170 $tpl2 = $lpg->create_template(); 3171 3172 // Create plans for first template. 3173 $time = time(); 3174 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $user->id, 3175 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN)); 3176 3177 $this->assertTrue(api::template_has_related_data($tpl1->get_id())); 3178 $this->assertFalse(api::template_has_related_data($tpl2->get_id())); 3179 3180 } 3181 3182 public function test_delete_template_delete_plans() { 3183 $this->resetAfterTest(true); 3184 $this->setAdminUser(); 3185 3186 $dg = $this->getDataGenerator(); 3187 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 3188 3189 $u1 = $dg->create_user(); 3190 $f = $lpg->create_framework(); 3191 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 3192 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 3193 3194 $tpl = $lpg->create_template(); 3195 3196 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(), 3197 'sortorder' => 1)); 3198 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(), 3199 'sortorder' => 2)); 3200 3201 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id)); 3202 3203 // Check pre-test. 3204 $this->assertTrue(\core_competency\template::record_exists($tpl->get_id())); 3205 $this->assertEquals(2, \core_competency\template_competency::count_competencies($tpl->get_id())); 3206 $this->assertEquals(1, count(\core_competency\plan::get_records(array('templateid' => $tpl->get_id())))); 3207 3208 $result = api::delete_template($tpl->get_id(), true); 3209 $this->assertTrue($result); 3210 3211 // Check that the template does not exist anymore. 3212 $this->assertFalse(\core_competency\template::record_exists($tpl->get_id())); 3213 3214 // Check that associated competencies are also deleted. 3215 $this->assertEquals(0, \core_competency\template_competency::count_competencies($tpl->get_id())); 3216 3217 // Check that associated plan are also deleted. 3218 $this->assertEquals(0, count(\core_competency\plan::get_records(array('templateid' => $tpl->get_id())))); 3219 } 3220 3221 public function test_delete_template_unlink_plans() { 3222 $this->resetAfterTest(true); 3223 $this->setAdminUser(); 3224 3225 $dg = $this->getDataGenerator(); 3226 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 3227 3228 $u1 = $dg->create_user(); 3229 $f = $lpg->create_framework(); 3230 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 3231 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id())); 3232 3233 $tpl = $lpg->create_template(); 3234 3235 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(), 3236 'sortorder' => 1)); 3237 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(), 3238 'sortorder' => 2)); 3239 3240 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id)); 3241 3242 // Check pre-test. 3243 $this->assertTrue(\core_competency\template::record_exists($tpl->get_id())); 3244 $this->assertEquals(2, \core_competency\template_competency::count_competencies($tpl->get_id())); 3245 $this->assertEquals(1, count(\core_competency\plan::get_records(array('templateid' => $tpl->get_id())))); 3246 3247 $result = api::delete_template($tpl->get_id(), false); 3248 $this->assertTrue($result); 3249 3250 // Check that the template does not exist anymore. 3251 $this->assertFalse(\core_competency\template::record_exists($tpl->get_id())); 3252 3253 // Check that associated competencies are also deleted. 3254 $this->assertEquals(0, \core_competency\template_competency::count_competencies($tpl->get_id())); 3255 3256 // Check that associated plan still exist but unlink from template. 3257 $plans = \core_competency\plan::get_records(array('id' => $p1->get_id())); 3258 $this->assertEquals(1, count($plans)); 3259 $this->assertEquals($plans[0]->get_origtemplateid(), $tpl->get_id()); 3260 $this->assertNull($plans[0]->get_templateid()); 3261 } 3262 3263 public function test_delete_competency() { 3264 $this->resetAfterTest(true); 3265 $dg = $this->getDataGenerator(); 3266 $lpg = $dg->get_plugin_generator('core_competency'); 3267 $this->setAdminUser(); 3268 3269 $u1 = $dg->create_user(); 3270 3271 $f1 = $lpg->create_framework(); 3272 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3273 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3274 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3275 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3276 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3277 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3278 3279 // Set rules on parent competency. 3280 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE); 3281 $c1->set_ruletype('core_competency\\competency_rule_all'); 3282 $c1->update(); 3283 3284 // If we delete competeny, the related competencies relations and evidences should be deleted. 3285 // Create related competencies using one of c1a competency descendants. 3286 $rc = $lpg->create_related_competency(array( 3287 'competencyid' => $c2->get_id(), 3288 'relatedcompetencyid' => $c11b->get_id() 3289 )); 3290 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3291 3292 // Creating a standard evidence with minimal information. 3293 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3294 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id())); 3295 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid()); 3296 $uc2->delete(); 3297 3298 $this->assertTrue(api::delete_competency($c1a->get_id())); 3299 $this->assertFalse(competency::record_exists($c1a->get_id())); 3300 3301 // Check that on delete, we reset the rule on parent competency. 3302 $c1->read(); 3303 $this->assertNull($c1->get_ruletype()); 3304 $this->assertNull($c1->get_ruletype()); 3305 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome()); 3306 3307 // Check that descendants were also deleted. 3308 $this->assertFalse(competency::record_exists($c1b->get_id())); 3309 $this->assertFalse(competency::record_exists($c11b->get_id())); 3310 $this->assertFalse(competency::record_exists($c12b->get_id())); 3311 3312 // Check if evidence are also deleted. 3313 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3314 3315 // Check if related conpetency relation is deleted. 3316 $this->assertEquals(0, count(api::list_related_competencies($c2->get_id()))); 3317 3318 // Delete a simple competency. 3319 $this->assertTrue(api::delete_competency($c2->get_id())); 3320 $this->assertFalse(competency::record_exists($c2->get_id())); 3321 } 3322 3323 public function test_delete_competency_used_in_plan() { 3324 $this->resetAfterTest(true); 3325 $dg = $this->getDataGenerator(); 3326 $lpg = $dg->get_plugin_generator('core_competency'); 3327 $this->setAdminUser(); 3328 3329 $u1 = $dg->create_user(); 3330 3331 $plan = $lpg->create_plan((object) array('userid' => $u1->id)); 3332 3333 $f1 = $lpg->create_framework(); 3334 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3335 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3336 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3337 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3338 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3339 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3340 3341 // Add competency to plan. 3342 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id())); 3343 // We can not delete a competency , if competency or competency children is associated to plan. 3344 $this->assertFalse(api::delete_competency($c1a->get_id())); 3345 3346 // We can delete the competency if we remove the competency from the plan. 3347 $pc->delete(); 3348 3349 $this->assertTrue(api::delete_competency($c1a->get_id())); 3350 $this->assertFalse(competency::record_exists($c1a->get_id())); 3351 $this->assertFalse(competency::record_exists($c1b->get_id())); 3352 $this->assertFalse(competency::record_exists($c11b->get_id())); 3353 $this->assertFalse(competency::record_exists($c12b->get_id())); 3354 } 3355 3356 public function test_delete_competency_used_in_usercompetency() { 3357 $this->resetAfterTest(true); 3358 $dg = $this->getDataGenerator(); 3359 $lpg = $dg->get_plugin_generator('core_competency'); 3360 $this->setAdminUser(); 3361 3362 $u1 = $dg->create_user(); 3363 3364 $f1 = $lpg->create_framework(); 3365 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3366 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3367 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3368 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3369 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3370 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3371 3372 // Create user competency. 3373 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3374 3375 // We can not delete a competency , if competency or competency children exist in user competency. 3376 $this->assertFalse(api::delete_competency($c1a->get_id())); 3377 3378 // We can delete the competency if we remove the competency from user competency. 3379 $uc1->delete(); 3380 3381 $this->assertTrue(api::delete_competency($c1a->get_id())); 3382 $this->assertFalse(competency::record_exists($c1a->get_id())); 3383 $this->assertFalse(competency::record_exists($c1b->get_id())); 3384 $this->assertFalse(competency::record_exists($c11b->get_id())); 3385 $this->assertFalse(competency::record_exists($c12b->get_id())); 3386 } 3387 3388 public function test_delete_competency_used_in_usercompetencyplan() { 3389 $this->resetAfterTest(true); 3390 $dg = $this->getDataGenerator(); 3391 $lpg = $dg->get_plugin_generator('core_competency'); 3392 $this->setAdminUser(); 3393 3394 $u1 = $dg->create_user(); 3395 3396 $plan = $lpg->create_plan((object) array('userid' => $u1->id)); 3397 3398 $f1 = $lpg->create_framework(); 3399 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3400 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3401 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3402 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3403 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3404 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3405 3406 // Create user competency plan. 3407 $uc2 = $lpg->create_user_competency_plan(array( 3408 'userid' => $u1->id, 3409 'competencyid' => $c11b->get_id(), 3410 'planid' => $plan->get_id() 3411 )); 3412 3413 // We can not delete a competency , if competency or competency children exist in user competency plan. 3414 $this->assertFalse(api::delete_competency($c1a->get_id())); 3415 3416 // We can delete the competency if we remove the competency from user competency plan. 3417 $uc2->delete(); 3418 3419 $this->assertTrue(api::delete_competency($c1a->get_id())); 3420 $this->assertFalse(competency::record_exists($c1a->get_id())); 3421 $this->assertFalse(competency::record_exists($c1b->get_id())); 3422 $this->assertFalse(competency::record_exists($c11b->get_id())); 3423 $this->assertFalse(competency::record_exists($c12b->get_id())); 3424 } 3425 3426 public function test_delete_competency_used_in_template() { 3427 $this->resetAfterTest(true); 3428 $dg = $this->getDataGenerator(); 3429 $lpg = $dg->get_plugin_generator('core_competency'); 3430 $this->setAdminUser(); 3431 3432 $template = $lpg->create_template(); 3433 3434 $f1 = $lpg->create_framework(); 3435 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3436 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3437 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3438 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3439 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3440 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3441 3442 // Add competency to a template. 3443 $tc = $lpg->create_template_competency(array( 3444 'templateid' => $template->get_id(), 3445 'competencyid' => $c11b->get_id() 3446 )); 3447 // We can not delete a competency , if competency or competency children is linked to template. 3448 $this->assertFalse(api::delete_competency($c1a->get_id())); 3449 3450 // We can delete the competency if we remove the competency from template. 3451 $tc->delete(); 3452 3453 $this->assertTrue(api::delete_competency($c1a->get_id())); 3454 $this->assertFalse(competency::record_exists($c1a->get_id())); 3455 $this->assertFalse(competency::record_exists($c1b->get_id())); 3456 $this->assertFalse(competency::record_exists($c11b->get_id())); 3457 $this->assertFalse(competency::record_exists($c12b->get_id())); 3458 } 3459 3460 public function test_delete_competency_used_in_course() { 3461 $this->resetAfterTest(true); 3462 $dg = $this->getDataGenerator(); 3463 $lpg = $dg->get_plugin_generator('core_competency'); 3464 $this->setAdminUser(); 3465 3466 $cat1 = $dg->create_category(); 3467 3468 $course = $dg->create_course(array('category' => $cat1->id)); 3469 3470 $f1 = $lpg->create_framework(); 3471 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3472 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3473 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3474 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3475 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3476 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3477 3478 // Add competency to course. 3479 $cc = $lpg->create_course_competency(array( 3480 'courseid' => $course->id, 3481 'competencyid' => $c11b->get_id() 3482 )); 3483 3484 // We can not delete a competency if the competency or competencies children is linked to a course. 3485 $this->assertFalse(api::delete_competency($c1a->get_id())); 3486 3487 // We can delete the competency if we remove the competency from course. 3488 $cc->delete(); 3489 3490 $this->assertTrue(api::delete_competency($c1a->get_id())); 3491 $this->assertFalse(competency::record_exists($c1a->get_id())); 3492 $this->assertFalse(competency::record_exists($c1b->get_id())); 3493 $this->assertFalse(competency::record_exists($c11b->get_id())); 3494 $this->assertFalse(competency::record_exists($c12b->get_id())); 3495 } 3496 3497 public function test_delete_framework() { 3498 $this->resetAfterTest(true); 3499 $dg = $this->getDataGenerator(); 3500 $lpg = $dg->get_plugin_generator('core_competency'); 3501 $this->setAdminUser(); 3502 3503 $u1 = $dg->create_user(); 3504 3505 $f1 = $lpg->create_framework(); 3506 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3507 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3508 $c2id = $c2->get_id(); 3509 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3510 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3511 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3512 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3513 3514 // If we delete framework, the related competencies relations and evidences should be deleted. 3515 // Create related competencies using one of c1a competency descendants. 3516 $rc = $lpg->create_related_competency(array( 3517 'competencyid' => $c2->get_id(), 3518 'relatedcompetencyid' => $c11b->get_id() 3519 )); 3520 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3521 3522 // Creating a standard evidence with minimal information. 3523 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3524 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id())); 3525 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid()); 3526 $uc2->delete(); 3527 3528 $this->assertTrue(api::delete_framework($f1->get_id())); 3529 $this->assertFalse(competency_framework::record_exists($f1->get_id())); 3530 3531 // Check that all competencies were also deleted. 3532 $this->assertFalse(competency::record_exists($c1->get_id())); 3533 $this->assertFalse(competency::record_exists($c2->get_id())); 3534 $this->assertFalse(competency::record_exists($c1a->get_id())); 3535 $this->assertFalse(competency::record_exists($c1b->get_id())); 3536 $this->assertFalse(competency::record_exists($c11b->get_id())); 3537 $this->assertFalse(competency::record_exists($c12b->get_id())); 3538 3539 // Check if evidence are also deleted. 3540 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3541 3542 // Check if related conpetency relation is deleted. 3543 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3544 3545 // Delete a simple framework. 3546 $f2 = $lpg->create_framework(); 3547 $this->assertTrue(api::delete_framework($f2->get_id())); 3548 $this->assertFalse(competency_framework::record_exists($f2->get_id())); 3549 } 3550 3551 public function test_delete_framework_competency_used_in_plan() { 3552 $this->resetAfterTest(true); 3553 $dg = $this->getDataGenerator(); 3554 $lpg = $dg->get_plugin_generator('core_competency'); 3555 $this->setAdminUser(); 3556 3557 $u1 = $dg->create_user(); 3558 3559 $plan = $lpg->create_plan((object) array('userid' => $u1->id)); 3560 3561 $f1 = $lpg->create_framework(); 3562 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3563 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3564 $c2id = $c2->get_id(); 3565 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3566 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3567 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3568 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3569 3570 // Create related competencies. 3571 $rc = $lpg->create_related_competency(array( 3572 'competencyid' => $c2->get_id(), 3573 'relatedcompetencyid' => $c11b->get_id() 3574 )); 3575 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3576 3577 // Creating a standard evidence with minimal information. 3578 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3579 $usercompetencyid = $uc2->get_id(); 3580 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); 3581 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid()); 3582 $uc2->delete(); 3583 3584 // Add competency to plan. 3585 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id())); 3586 // We can not delete a framework , if competency or competency children is associated to plan. 3587 $this->assertFalse(api::delete_framework($f1->get_id())); 3588 // Check that none of associated data are deleted. 3589 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); 3590 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); 3591 3592 // We can delete the competency if we remove the competency from the plan. 3593 $pc->delete(); 3594 3595 $this->assertTrue(api::delete_framework($f1->get_id())); 3596 $this->assertFalse(competency::record_exists($c1->get_id())); 3597 $this->assertFalse(competency::record_exists($c2->get_id())); 3598 $this->assertFalse(competency::record_exists($c1a->get_id())); 3599 $this->assertFalse(competency::record_exists($c1b->get_id())); 3600 $this->assertFalse(competency::record_exists($c11b->get_id())); 3601 $this->assertFalse(competency::record_exists($c12b->get_id())); 3602 // Check if evidence are also deleted. 3603 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3604 3605 // Check if related conpetency relation is deleted. 3606 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3607 } 3608 3609 public function test_delete_framework_competency_used_in_usercompetency() { 3610 $this->resetAfterTest(true); 3611 $dg = $this->getDataGenerator(); 3612 $lpg = $dg->get_plugin_generator('core_competency'); 3613 $this->setAdminUser(); 3614 3615 $u1 = $dg->create_user(); 3616 3617 $f1 = $lpg->create_framework(); 3618 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3619 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3620 $c2id = $c2->get_id(); 3621 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3622 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3623 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3624 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3625 3626 // Create related competencies. 3627 $rc = $lpg->create_related_competency(array( 3628 'competencyid' => $c2->get_id(), 3629 'relatedcompetencyid' => $c11b->get_id() 3630 )); 3631 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3632 3633 // Creating a standard evidence with minimal information. 3634 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3635 $usercompetencyid = $uc1->get_id(); 3636 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); 3637 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid()); 3638 $uc1->delete(); 3639 3640 // Create user competency. 3641 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3642 3643 // We can not delete a framework , if competency or competency children exist in user competency. 3644 $this->assertFalse(api::delete_framework($f1->get_id())); 3645 // Check that none of associated data are deleted. 3646 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); 3647 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); 3648 3649 // We can delete the framework if we remove the competency from user competency. 3650 $uc2->delete(); 3651 3652 $this->assertTrue(api::delete_framework($f1->get_id())); 3653 $this->assertFalse(competency::record_exists($c1->get_id())); 3654 $this->assertFalse(competency::record_exists($c2->get_id())); 3655 $this->assertFalse(competency::record_exists($c1a->get_id())); 3656 $this->assertFalse(competency::record_exists($c1b->get_id())); 3657 $this->assertFalse(competency::record_exists($c11b->get_id())); 3658 $this->assertFalse(competency::record_exists($c12b->get_id())); 3659 // Check if evidence are also deleted. 3660 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3661 3662 // Check if related conpetency relation is deleted. 3663 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3664 } 3665 3666 public function test_delete_framework_competency_used_in_usercompetencyplan() { 3667 $this->resetAfterTest(true); 3668 $dg = $this->getDataGenerator(); 3669 $lpg = $dg->get_plugin_generator('core_competency'); 3670 $this->setAdminUser(); 3671 3672 $u1 = $dg->create_user(); 3673 3674 $plan = $lpg->create_plan((object) array('userid' => $u1->id)); 3675 3676 $f1 = $lpg->create_framework(); 3677 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3678 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3679 $c2id = $c2->get_id(); 3680 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3681 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3682 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3683 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3684 3685 // Create related competencies. 3686 $rc = $lpg->create_related_competency(array( 3687 'competencyid' => $c2->get_id(), 3688 'relatedcompetencyid' => $c11b->get_id() 3689 )); 3690 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3691 3692 // Creating a standard evidence with minimal information. 3693 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3694 $usercompetencyid = $uc1->get_id(); 3695 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); 3696 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid()); 3697 $uc1->delete(); 3698 3699 // Create user competency plan. 3700 $uc2 = $lpg->create_user_competency_plan(array( 3701 'userid' => $u1->id, 3702 'competencyid' => $c11b->get_id(), 3703 'planid' => $plan->get_id() 3704 )); 3705 3706 // We can not delete a framework , if competency or competency children exist in user competency plan. 3707 $this->assertFalse(api::delete_framework($f1->get_id())); 3708 // Check that none of associated data are deleted. 3709 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); 3710 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); 3711 3712 // We can delete the framework if we remove the competency from user competency plan. 3713 $uc2->delete(); 3714 3715 $this->assertTrue(api::delete_framework($f1->get_id())); 3716 $this->assertFalse(competency::record_exists($c1->get_id())); 3717 $this->assertFalse(competency::record_exists($c2->get_id())); 3718 $this->assertFalse(competency::record_exists($c1a->get_id())); 3719 $this->assertFalse(competency::record_exists($c1b->get_id())); 3720 $this->assertFalse(competency::record_exists($c11b->get_id())); 3721 $this->assertFalse(competency::record_exists($c12b->get_id())); 3722 // Check if evidence are also deleted. 3723 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3724 3725 // Check if related conpetency relation is deleted. 3726 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3727 } 3728 3729 public function test_delete_framework_competency_used_in_template() { 3730 $this->resetAfterTest(true); 3731 $dg = $this->getDataGenerator(); 3732 $lpg = $dg->get_plugin_generator('core_competency'); 3733 $this->setAdminUser(); 3734 3735 $u1 = $dg->create_user(); 3736 $template = $lpg->create_template(); 3737 3738 $f1 = $lpg->create_framework(); 3739 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3740 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3741 $c2id = $c2->get_id(); 3742 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3743 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3744 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3745 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3746 3747 // Create related competencies. 3748 $rc = $lpg->create_related_competency(array( 3749 'competencyid' => $c2->get_id(), 3750 'relatedcompetencyid' => $c11b->get_id() 3751 )); 3752 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3753 3754 // Creating a standard evidence with minimal information. 3755 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3756 $usercompetencyid = $uc1->get_id(); 3757 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); 3758 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid()); 3759 $uc1->delete(); 3760 3761 // Add competency to a template. 3762 $tc = $lpg->create_template_competency(array( 3763 'templateid' => $template->get_id(), 3764 'competencyid' => $c11b->get_id() 3765 )); 3766 // We can not delete a framework , if competency or competency children is linked to template. 3767 $this->assertFalse(api::delete_framework($f1->get_id())); 3768 // Check that none of associated data are deleted. 3769 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); 3770 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); 3771 3772 // We can delete the framework if we remove the competency from template. 3773 $tc->delete(); 3774 3775 $this->assertTrue(api::delete_framework($f1->get_id())); 3776 $this->assertFalse(competency::record_exists($c1->get_id())); 3777 $this->assertFalse(competency::record_exists($c2->get_id())); 3778 $this->assertFalse(competency::record_exists($c1a->get_id())); 3779 $this->assertFalse(competency::record_exists($c1b->get_id())); 3780 $this->assertFalse(competency::record_exists($c11b->get_id())); 3781 $this->assertFalse(competency::record_exists($c12b->get_id())); 3782 // Check if evidence are also deleted. 3783 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3784 3785 // Check if related conpetency relation is deleted. 3786 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3787 } 3788 3789 public function test_delete_framework_competency_used_in_course() { 3790 $this->resetAfterTest(true); 3791 $dg = $this->getDataGenerator(); 3792 $lpg = $dg->get_plugin_generator('core_competency'); 3793 $this->setAdminUser(); 3794 3795 $cat1 = $dg->create_category(); 3796 $u1 = $dg->create_user(); 3797 $course = $dg->create_course(array('category' => $cat1->id)); 3798 3799 $f1 = $lpg->create_framework(); 3800 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3801 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); 3802 $c2id = $c2->get_id(); 3803 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); 3804 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); 3805 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3806 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); 3807 3808 // Create related competencies. 3809 $rc = $lpg->create_related_competency(array( 3810 'competencyid' => $c2->get_id(), 3811 'relatedcompetencyid' => $c11b->get_id() 3812 )); 3813 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); 3814 3815 // Creating a standard evidence with minimal information. 3816 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); 3817 $usercompetencyid = $uc1->get_id(); 3818 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); 3819 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid()); 3820 $uc1->delete(); 3821 3822 // Add competency to course. 3823 $cc = $lpg->create_course_competency(array( 3824 'courseid' => $course->id, 3825 'competencyid' => $c11b->get_id() 3826 )); 3827 3828 // We can not delete a framework if the competency or competencies children is linked to a course. 3829 $this->assertFalse(api::delete_framework($f1->get_id())); 3830 // Check that none of associated data are deleted. 3831 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); 3832 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); 3833 3834 // We can delete the framework if we remove the competency from course. 3835 $cc->delete(); 3836 3837 $this->assertTrue(api::delete_framework($f1->get_id())); 3838 $this->assertFalse(competency::record_exists($c1->get_id())); 3839 $this->assertFalse(competency::record_exists($c2->get_id())); 3840 $this->assertFalse(competency::record_exists($c1a->get_id())); 3841 $this->assertFalse(competency::record_exists($c1b->get_id())); 3842 $this->assertFalse(competency::record_exists($c11b->get_id())); 3843 $this->assertFalse(competency::record_exists($c12b->get_id())); 3844 // Check if evidence are also deleted. 3845 $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); 3846 3847 // Check if related conpetency relation is deleted. 3848 $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); 3849 } 3850 3851 public function test_grade_competency_in_course_permissions() { 3852 $this->resetAfterTest(); 3853 $dg = $this->getDataGenerator(); 3854 3855 $c1 = $dg->create_course(); 3856 $c2 = $dg->create_course(); 3857 $sysctx = context_system::instance(); 3858 $c1ctx = context_course::instance($c1->id); 3859 $c2ctx = context_course::instance($c2->id); 3860 3861 $teacher1 = $dg->create_user(); 3862 $noneditingteacher = $dg->create_user(); 3863 $student1 = $dg->create_user(); 3864 $student2 = $dg->create_user(); 3865 $notstudent1 = $dg->create_user(); 3866 3867 $lpg = $dg->get_plugin_generator('core_competency'); 3868 $framework = $lpg->create_framework(); 3869 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 3870 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 3871 $lpg->create_course_competency(array('courseid' => $c1->id, 'competencyid' => $comp1->get_id())); 3872 3873 $studentarch = get_archetype_roles('student'); 3874 $studentrole = array_shift($studentarch); 3875 3876 $gradablerole = $dg->create_role(); 3877 assign_capability('moodle/competency:coursecompetencygradable', CAP_ALLOW, $gradablerole, $sysctx->id); 3878 3879 $notgradablerole = $dg->create_role(); 3880 assign_capability('moodle/competency:coursecompetencygradable', CAP_PROHIBIT, $notgradablerole, $sysctx->id); 3881 3882 $canviewucrole = $dg->create_role(); 3883 assign_capability('moodle/competency:usercompetencyview', CAP_ALLOW, $canviewucrole, $sysctx->id); 3884 3885 $cannotviewcomp = $dg->create_role(); 3886 assign_capability('moodle/competency:competencyview', CAP_PROHIBIT, $cannotviewcomp, $sysctx->id); 3887 3888 $canmanagecomp = $dg->create_role(); 3889 assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $canmanagecomp, $sysctx->id); 3890 3891 $cangraderole = $dg->create_role(); 3892 assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $cangraderole, $sysctx->id); 3893 3894 // Enrol s1 and s2 as students in course 1. 3895 $dg->enrol_user($student1->id, $c1->id, $studentrole->id); 3896 $dg->enrol_user($student2->id, $c1->id, $studentrole->id); 3897 3898 // Mark the s2 as not being 'gradable'. 3899 $dg->role_assign($notgradablerole, $student2->id, $c1ctx->id); 3900 3901 // Mark the 'non a student' as 'gradable' throughout the site. 3902 $dg->role_assign($gradablerole, $notstudent1->id, $sysctx->id); 3903 3904 // From now we'll iterate over each permission. 3905 accesslib_clear_all_caches_for_unit_testing(); 3906 $this->setUser($teacher1); 3907 3908 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View a user competency', 3909 $c1->id, $student1->id, $comp1->get_id()); 3910 3911 // Give permission to view competencies. 3912 $dg->role_assign($canviewucrole, $teacher1->id, $c1ctx->id); 3913 accesslib_clear_all_caches_for_unit_testing(); 3914 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'Set competency rating', 3915 $c1->id, $student1->id, $comp1->get_id()); 3916 3917 // Give permission to rate. 3918 $dg->role_assign($cangraderole, $teacher1->id, $c1ctx->id); 3919 accesslib_clear_all_caches_for_unit_testing(); 3920 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id()); 3921 3922 // Remove permssion to read competencies, this leads to error. 3923 $dg->role_assign($cannotviewcomp, $teacher1->id, $sysctx->id); 3924 accesslib_clear_all_caches_for_unit_testing(); 3925 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View competency frameworks', 3926 $c1->id, $student1->id, $comp1->get_id()); 3927 3928 // Give permssion to manage course competencies, this leads to success. 3929 $dg->role_assign($canmanagecomp, $teacher1->id, $sysctx->id); 3930 accesslib_clear_all_caches_for_unit_testing(); 3931 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id()); 3932 3933 // Try to grade a user that is not gradable, lead to errors. 3934 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency may not be rated at this time.', 3935 $c1->id, $student2->id, $comp1->get_id()); 3936 3937 // Try to grade a competency not in the course. 3938 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency does not belong to this course', 3939 $c1->id, $student1->id, $comp2->get_id()); 3940 3941 // Try to grade a user that is not enrolled, even though they are 'gradable'. 3942 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency may not be rated at this time.', 3943 $c1->id, $notstudent1->id, $comp1->get_id()); 3944 3945 // Give permission for non-editing teacher to grade. 3946 $dg->role_assign($canviewucrole, $noneditingteacher->id, $c1ctx->id); 3947 $dg->role_assign($cangraderole, $noneditingteacher->id, $c1ctx->id); 3948 $this->setUser($noneditingteacher); 3949 3950 accesslib_clear_all_caches_for_unit_testing(); 3951 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id()); 3952 } 3953 3954 /** 3955 * Assert that a competency was graded in a course. 3956 * 3957 * @param int $courseid The course ID. 3958 * @param int $userid The user ID. 3959 * @param int $compid The competency ID. 3960 * @param int $grade The grade. 3961 */ 3962 protected function assertSuccessWithGradeCompetencyInCourse($courseid, $userid, $compid, $grade = 1) { 3963 $beforecount = evidence::count_records(); 3964 api::grade_competency_in_course($courseid, $userid, $compid, $grade); 3965 $this->assertEquals($beforecount + 1, evidence::count_records()); 3966 $uc = user_competency::get_record(array('userid' => $userid, 'competencyid' => $compid)); 3967 $records = evidence::get_records(array(), 'id', 'DESC', 0, 1); 3968 $evidence = array_pop($records); 3969 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid()); 3970 } 3971 3972 /** 3973 * Assert that grading a competency in course throws an exception. 3974 * 3975 * @param string $exceptiontype The exception type. 3976 * @param string $exceptiontest The exceptiont text. 3977 * @param int $courseid The course ID. 3978 * @param int $userid The user ID. 3979 * @param int $compid The competency ID. 3980 * @param int $grade The grade. 3981 */ 3982 protected function assertExceptionWithGradeCompetencyInCourse($exceptiontype, $exceptiontext, $courseid, $userid, $compid, 3983 $grade = 1) { 3984 3985 $raised = false; 3986 try { 3987 api::grade_competency_in_course($courseid, $userid, $compid, $grade); 3988 } catch (moodle_exception $e) { 3989 $raised = true; 3990 $this->assertInstanceOf($exceptiontype, $e); 3991 $this->assertRegExp('@' . $exceptiontext . '@', $e->getMessage()); 3992 } 3993 3994 if (!$raised) { 3995 $this->fail('Grading should not be allowed.'); 3996 } 3997 } 3998 3999 /** 4000 * Test list of evidences for plan completed and not completed. 4001 */ 4002 public function test_list_evidence() { 4003 global $DB; 4004 4005 $this->resetAfterTest(true); 4006 $dg = $this->getDataGenerator(); 4007 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); 4008 4009 $syscontext = context_system::instance(); 4010 4011 // Create users. 4012 $user = $dg->create_user(); 4013 $this->setUser($user); 4014 4015 // Create a framework and assign competencies. 4016 $framework = $lpg->create_framework(); 4017 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4018 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4019 4020 // Create 2 user plans and add competency to each plan. 4021 $p1 = $lpg->create_plan(array('userid' => $user->id)); 4022 $p2 = $lpg->create_plan(array('userid' => $user->id)); 4023 $pc1 = $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c1->get_id())); 4024 $pc2 = $lpg->create_plan_competency(array('planid' => $p2->get_id(), 'competencyid' => $c1->get_id())); 4025 4026 // Create user competency and add an evidence. 4027 $uc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id())); 4028 $e1 = $lpg->create_evidence(array('usercompetencyid' => $uc->get_id())); 4029 4030 // Check both plans as one evidence. 4031 $this->assertEquals(1, count(api::list_evidence($user->id, $c1->get_id(), $p1->get_id()))); 4032 $this->assertEquals(1, count(api::list_evidence($user->id, $c1->get_id(), $p2->get_id()))); 4033 4034 // Complete second plan. 4035 $p2->set_status(plan::STATUS_COMPLETE); 4036 $p2->update(); 4037 4038 // Add another evidence for the same competency, but in the future (time + 1). 4039 $e2 = $lpg->create_evidence(array('usercompetencyid' => $uc->get_id())); 4040 $evidencesql = "UPDATE {" . evidence::TABLE . "} SET timecreated = :currenttime WHERE id = :evidenceid"; 4041 $DB->execute($evidencesql, array('currenttime' => time() + 1, 'evidenceid' => $e2->get_id())); 4042 4043 // Check that the first plan, which is not completed, has all the evidence. 4044 $this->assertEquals(2, count(api::list_evidence($user->id, $c1->get_id(), $p1->get_id()))); 4045 4046 // Check that the second plan, completed before the new evidence, only has the first piece of evidence. 4047 $listevidences = api::list_evidence($user->id, $c1->get_id(), $p2->get_id()); 4048 $this->assertEquals(1, count($listevidences)); 4049 $this->assertEquals($e1->get_id(), $listevidences[$e1->get_id()]->get_id()); 4050 } 4051 4052 /** 4053 * Get a user competency in a course. 4054 */ 4055 public function test_get_user_competency_in_course() { 4056 $this->resetAfterTest(true); 4057 $dg = $this->getDataGenerator(); 4058 $lpg = $dg->get_plugin_generator('core_competency'); 4059 $this->setAdminUser(); 4060 4061 $user = $dg->create_user(); 4062 $c1 = $dg->create_course(); 4063 4064 // Enrol the user so they can be rated in the course. 4065 $studentarch = get_archetype_roles('student'); 4066 $studentrole = array_shift($studentarch); 4067 $coursecontext = context_course::instance($c1->id); 4068 $dg->role_assign($studentrole->id, $user->id, $coursecontext->id); 4069 $dg->enrol_user($user->id, $c1->id, $studentrole->id); 4070 4071 $framework = $lpg->create_framework(); 4072 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4073 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4074 $lpg->create_course_competency(array('competencyid' => $comp1->get_id(), 'courseid' => $c1->id)); 4075 $lpg->create_course_competency(array('competencyid' => $comp2->get_id(), 'courseid' => $c1->id)); 4076 4077 // Create a user competency for comp1. 4078 api::grade_competency_in_course($c1, $user->id, $comp1->get_id(), 3, 'Unit test'); 4079 4080 // Test for competency already exist in user_competency. 4081 $uc = api::get_user_competency_in_course($c1->id, $user->id, $comp1->get_id()); 4082 $this->assertEquals($comp1->get_id(), $uc->get_competencyid()); 4083 $this->assertEquals($user->id, $uc->get_userid()); 4084 $this->assertEquals(3, $uc->get_grade()); 4085 $this->assertEquals(true, $uc->get_proficiency()); 4086 4087 // Test for competency does not exist in user_competency. 4088 $uc2 = api::get_user_competency_in_course($c1->id, $user->id, $comp2->get_id()); 4089 $this->assertEquals($comp2->get_id(), $uc2->get_competencyid()); 4090 $this->assertEquals($user->id, $uc2->get_userid()); 4091 $this->assertEquals(null, $uc2->get_grade()); 4092 $this->assertEquals(null, $uc2->get_proficiency()); 4093 } 4094 4095 /** 4096 * Test course statistics api functions. 4097 */ 4098 public function test_course_statistics() { 4099 $this->resetAfterTest(true); 4100 $dg = $this->getDataGenerator(); 4101 $lpg = $dg->get_plugin_generator('core_competency'); 4102 $this->setAdminUser(); 4103 4104 $u1 = $dg->create_user(); 4105 $u2 = $dg->create_user(); 4106 $u3 = $dg->create_user(); 4107 $u4 = $dg->create_user(); 4108 $c1 = $dg->create_course(); 4109 $framework = $lpg->create_framework(); 4110 // Enrol students in the course. 4111 $studentarch = get_archetype_roles('student'); 4112 $studentrole = array_shift($studentarch); 4113 $coursecontext = context_course::instance($c1->id); 4114 $dg->role_assign($studentrole->id, $u1->id, $coursecontext->id); 4115 $dg->enrol_user($u1->id, $c1->id, $studentrole->id); 4116 $dg->role_assign($studentrole->id, $u2->id, $coursecontext->id); 4117 $dg->enrol_user($u2->id, $c1->id, $studentrole->id); 4118 $dg->role_assign($studentrole->id, $u3->id, $coursecontext->id); 4119 $dg->enrol_user($u3->id, $c1->id, $studentrole->id); 4120 $dg->role_assign($studentrole->id, $u4->id, $coursecontext->id); 4121 $dg->enrol_user($u4->id, $c1->id, $studentrole->id); 4122 4123 // Create 6 competencies. 4124 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4125 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4126 $comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4127 $comp4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4128 $comp5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4129 $comp6 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4130 4131 // Link 6 out of 6 to a course. 4132 $lpg->create_course_competency(array('competencyid' => $comp1->get_id(), 'courseid' => $c1->id)); 4133 $lpg->create_course_competency(array('competencyid' => $comp2->get_id(), 'courseid' => $c1->id)); 4134 $lpg->create_course_competency(array('competencyid' => $comp3->get_id(), 'courseid' => $c1->id)); 4135 $lpg->create_course_competency(array('competencyid' => $comp4->get_id(), 'courseid' => $c1->id)); 4136 $lpg->create_course_competency(array('competencyid' => $comp5->get_id(), 'courseid' => $c1->id)); 4137 $lpg->create_course_competency(array('competencyid' => $comp6->get_id(), 'courseid' => $c1->id)); 4138 4139 // Rate some competencies. 4140 // User 1. 4141 api::grade_competency_in_course($c1, $u1->id, $comp1->get_id(), 4, 'Unit test'); 4142 api::grade_competency_in_course($c1, $u1->id, $comp2->get_id(), 4, 'Unit test'); 4143 api::grade_competency_in_course($c1, $u1->id, $comp3->get_id(), 4, 'Unit test'); 4144 api::grade_competency_in_course($c1, $u1->id, $comp4->get_id(), 4, 'Unit test'); 4145 // User 2. 4146 api::grade_competency_in_course($c1, $u2->id, $comp1->get_id(), 1, 'Unit test'); 4147 api::grade_competency_in_course($c1, $u2->id, $comp2->get_id(), 1, 'Unit test'); 4148 api::grade_competency_in_course($c1, $u2->id, $comp3->get_id(), 1, 'Unit test'); 4149 api::grade_competency_in_course($c1, $u2->id, $comp4->get_id(), 1, 'Unit test'); 4150 // User 3. 4151 api::grade_competency_in_course($c1, $u3->id, $comp1->get_id(), 3, 'Unit test'); 4152 api::grade_competency_in_course($c1, $u3->id, $comp2->get_id(), 3, 'Unit test'); 4153 // User 4. 4154 api::grade_competency_in_course($c1, $u4->id, $comp1->get_id(), 2, 'Unit test'); 4155 api::grade_competency_in_course($c1, $u4->id, $comp2->get_id(), 2, 'Unit test'); 4156 4157 // OK we have enough data - lets call some API functions and check for expected results. 4158 4159 $result = api::count_proficient_competencies_in_course_for_user($c1->id, $u1->id); 4160 $this->assertEquals(4, $result); 4161 $result = api::count_proficient_competencies_in_course_for_user($c1->id, $u2->id); 4162 $this->assertEquals(0, $result); 4163 $result = api::count_proficient_competencies_in_course_for_user($c1->id, $u3->id); 4164 $this->assertEquals(2, $result); 4165 $result = api::count_proficient_competencies_in_course_for_user($c1->id, $u4->id); 4166 $this->assertEquals(0, $result); 4167 4168 $result = api::get_least_proficient_competencies_for_course($c1->id, 0, 2); 4169 // We should get 5 and 6 in repeatable order. 4170 $valid = false; 4171 if (($comp5->get_id() == $result[0]->get_id()) || ($comp6->get_id() == $result[0]->get_id())) { 4172 $valid = true; 4173 } 4174 $this->assertTrue($valid); 4175 $valid = false; 4176 if (($comp5->get_id() == $result[1]->get_id()) || ($comp6->get_id() == $result[1]->get_id())) { 4177 $valid = true; 4178 } 4179 $this->assertTrue($valid); 4180 $expected = $result[1]->get_id(); 4181 $result = api::get_least_proficient_competencies_for_course($c1->id, 1, 1); 4182 $this->assertEquals($result[0]->get_id(), $expected); 4183 } 4184 4185 /** 4186 * Test template statistics api functions. 4187 */ 4188 public function test_template_statistics() { 4189 $this->resetAfterTest(true); 4190 $dg = $this->getDataGenerator(); 4191 $lpg = $dg->get_plugin_generator('core_competency'); 4192 $this->setAdminUser(); 4193 4194 $u1 = $dg->create_user(); 4195 $u2 = $dg->create_user(); 4196 $u3 = $dg->create_user(); 4197 $u4 = $dg->create_user(); 4198 $c1 = $dg->create_course(); 4199 $framework = $lpg->create_framework(); 4200 4201 // Create 6 competencies. 4202 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4203 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4204 $comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4205 $comp4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4206 $comp5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4207 $comp6 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); 4208 4209 // Link 5 out of 6 to a course. 4210 $lpg->create_course_competency(array('competencyid' => $comp1->get_id(), 'courseid' => $c1->id)); 4211 $lpg->create_course_competency(array('competencyid' => $comp2->get_id(), 'courseid' => $c1->id)); 4212 $lpg->create_course_competency(array('competencyid' => $comp3->get_id(), 'courseid' => $c1->id)); 4213 $lpg->create_course_competency(array('competencyid' => $comp4->get_id(), 'courseid' => $c1->id)); 4214 $lpg->create_course_competency(array('competencyid' => $comp5->get_id(), 'courseid' => $c1->id)); 4215 4216 // Put all 6 in a template. 4217 $tpl = $this->getDataGenerator()->get_plugin_generator('core_competency')->create_template(); 4218 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp1->get_id())); 4219 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp2->get_id())); 4220 $tplc3 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp3->get_id())); 4221 $tplc4 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp4->get_id())); 4222 $tplc5 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp5->get_id())); 4223 $tplc6 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp6->get_id())); 4224 4225 // Create some plans from the template. 4226 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id)); 4227 $p2 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u2->id)); 4228 $p3 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u3->id)); 4229 $p4 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u4->id)); 4230 4231 // Rate some competencies. 4232 // User 1. 4233 $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp1->get_id(), 4234 'proficiency' => true, 'grade' => 1 )); 4235 $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp2->get_id(), 4236 'proficiency' => true, 'grade' => 1 )); 4237 $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp3->get_id(), 4238 'proficiency' => true, 'grade' => 1 )); 4239 // User 2. 4240 $lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp1->get_id(), 4241 'proficiency' => false, 'grade' => 1 )); 4242 $lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp2->get_id(), 4243 'proficiency' => false, 'grade' => 1 )); 4244 $lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp3->get_id(), 4245 'proficiency' => false, 'grade' => 1 )); 4246 // User 3. 4247 $lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp2->get_id(), 4248 'proficiency' => false, 'grade' => 1 )); 4249 $lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp3->get_id(), 4250 'proficiency' => true, 'grade' => 1 )); 4251 $lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp4->get_id(), 4252 'proficiency' => false, 'grade' => 1 )); 4253 $lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp5->get_id(), 4254 'proficiency' => true, 'grade' => 1 )); 4255 // User 4. 4256 $lpg->create_user_competency(array('userid' => $u4->id, 'competencyid' => $comp3->get_id(), 4257 'proficiency' => true, 'grade' => 1 )); 4258 $lpg->create_user_competency(array('userid' => $u4->id, 'competencyid' => $comp5->get_id(), 4259 'proficiency' => true, 'grade' => 1 )); 4260 4261 // Complete 3 out of 4 plans. 4262 api::complete_plan($p1->get_id()); 4263 api::complete_plan($p2->get_id()); 4264 api::complete_plan($p3->get_id()); 4265 4266 // OK we have enough data - lets call some API functions and check for expected results. 4267 4268 $result = api::count_competencies_in_template_with_no_courses($tpl->get_id()); 4269 $this->assertEquals(1, $result); 4270 4271 $result = api::count_plans_for_template($tpl->get_id()); 4272 $this->assertEquals(4, $result); 4273 4274 $result = api::count_plans_for_template($tpl->get_id(), plan::STATUS_COMPLETE); 4275 $this->assertEquals(3, $result); 4276 4277 // This counts the records of competencies in completed plans for all users with a plan from this template. 4278 $result = api::count_user_competency_plans_for_template($tpl->get_id()); 4279 // There should be 3 plans * 6 competencies. 4280 $this->assertEquals(18, $result); 4281 4282 // This counts the records of proficient competencies in completed plans for all users with a plan from this template. 4283 $result = api::count_user_competency_plans_for_template($tpl->get_id(), true); 4284 // There should be 5. 4285 $this->assertEquals(5, $result); 4286 4287 // This counts the records of not proficient competencies in completed plans for all users with a plan from this template. 4288 $result = api::count_user_competency_plans_for_template($tpl->get_id(), false); 4289 // There should be 13. 4290 $this->assertEquals(13, $result); 4291 4292 // This lists the plans based on this template, optionally filtered by status. 4293 $result = api::list_plans_for_template($tpl->get_id()); 4294 4295 $this->assertEquals(4, count($result)); 4296 foreach ($result as $one) { 4297 $this->assertInstanceOf('\core_competency\plan', $one); 4298 } 4299 // This lists the plans based on this template, optionally filtered by status. 4300 $result = api::list_plans_for_template($tpl->get_id(), plan::STATUS_COMPLETE); 4301 4302 $this->assertEquals(3, count($result)); 4303 foreach ($result as $one) { 4304 $this->assertInstanceOf('\core_competency\plan', $one); 4305 $this->assertEquals(plan::STATUS_COMPLETE, $one->get_status()); 4306 } 4307 4308 $result = api::get_least_proficient_competencies_for_template($tpl->get_id(), 0, 2); 4309 4310 // Our times completed counts should look like this: 4311 // - comp1 - 1 4312 // - comp2 - 1 4313 // - comp3 - 2 4314 // - comp4 - 0 4315 // - comp5 - 1 4316 // - comp6 - 0 4317 // 4318 // And this is a fullstop to make CiBoT happy. 4319 $this->assertEquals(2, count($result)); 4320 $leastarray = array($comp4->get_id(), $comp6->get_id()); 4321 foreach ($result as $one) { 4322 $this->assertInstanceOf('\core_competency\competency', $one); 4323 $this->assertContains($one->get_id(), $leastarray); 4324 } 4325 } 4326 4327 public function test_is_scale_used_anywhere() { 4328 $this->resetAfterTest(); 4329 $dg = $this->getDataGenerator(); 4330 $lpg = $dg->get_plugin_generator('core_competency'); 4331 4332 $scale1 = $dg->create_scale(); 4333 $scale2 = $dg->create_scale(); 4334 $scale3 = $dg->create_scale(); 4335 $scale4 = $dg->create_scale(); 4336 4337 $this->assertFalse(api::is_scale_used_anywhere($scale1->id)); 4338 $this->assertFalse(api::is_scale_used_anywhere($scale2->id)); 4339 $this->assertFalse(api::is_scale_used_anywhere($scale3->id)); 4340 $this->assertFalse(api::is_scale_used_anywhere($scale4->id)); 4341 4342 // Using scale 1 in a framework. 4343 $f1 = $lpg->create_framework([ 4344 'scaleid' => $scale1->id, 4345 'scaleconfiguration' => json_encode([ 4346 ['scaleid' => $scale1->id], 4347 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4348 ]) 4349 ]); 4350 $this->assertTrue(api::is_scale_used_anywhere($scale1->id)); 4351 $this->assertFalse(api::is_scale_used_anywhere($scale2->id)); 4352 $this->assertFalse(api::is_scale_used_anywhere($scale3->id)); 4353 $this->assertFalse(api::is_scale_used_anywhere($scale4->id)); 4354 4355 // Using scale 2 in a competency. 4356 $f2 = $lpg->create_framework(); 4357 $c2 = $lpg->create_competency([ 4358 'competencyframeworkid' => $f2->get_id(), 4359 'scaleid' => $scale2->id, 4360 'scaleconfiguration' => json_encode([ 4361 ['scaleid' => $scale2->id], 4362 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4363 ]) 4364 ]); 4365 4366 $this->assertTrue(api::is_scale_used_anywhere($scale1->id)); 4367 $this->assertTrue(api::is_scale_used_anywhere($scale2->id)); 4368 $this->assertFalse(api::is_scale_used_anywhere($scale3->id)); 4369 $this->assertFalse(api::is_scale_used_anywhere($scale4->id)); 4370 4371 // Using scale 3 in a framework, and scale 4 in a competency of that framework. 4372 $f3 = $lpg->create_framework([ 4373 'scaleid' => $scale3->id, 4374 'scaleconfiguration' => json_encode([ 4375 ['scaleid' => $scale3->id], 4376 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4377 ]) 4378 ]); 4379 $c3 = $lpg->create_competency([ 4380 'competencyframeworkid' => $f3->get_id(), 4381 'scaleid' => $scale4->id, 4382 'scaleconfiguration' => json_encode([ 4383 ['scaleid' => $scale4->id], 4384 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4385 ]) 4386 ]); 4387 4388 $this->assertTrue(api::is_scale_used_anywhere($scale1->id)); 4389 $this->assertTrue(api::is_scale_used_anywhere($scale2->id)); 4390 $this->assertTrue(api::is_scale_used_anywhere($scale3->id)); 4391 $this->assertTrue(api::is_scale_used_anywhere($scale4->id)); 4392 4393 // Multiple occurrences of the same scale (3, and 4). 4394 $f4 = $lpg->create_framework([ 4395 'scaleid' => $scale3->id, 4396 'scaleconfiguration' => json_encode([ 4397 ['scaleid' => $scale3->id], 4398 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4399 ]) 4400 ]); 4401 $c4 = $lpg->create_competency([ 4402 'competencyframeworkid' => $f3->get_id(), 4403 'scaleid' => $scale4->id, 4404 'scaleconfiguration' => json_encode([ 4405 ['scaleid' => $scale4->id], 4406 ['id' => 1, 'scaledefault' => 1, 'proficient' => 1] 4407 ]) 4408 ]); 4409 $this->assertTrue(api::is_scale_used_anywhere($scale1->id)); 4410 $this->assertTrue(api::is_scale_used_anywhere($scale2->id)); 4411 $this->assertTrue(api::is_scale_used_anywhere($scale3->id)); 4412 $this->assertTrue(api::is_scale_used_anywhere($scale4->id)); 4413 } 4414 4415 public function test_delete_evidence() { 4416 $this->resetAfterTest(); 4417 $dg = $this->getDataGenerator(); 4418 $ccg = $dg->get_plugin_generator('core_competency'); 4419 4420 $u1 = $dg->create_user(); 4421 $f1 = $ccg->create_framework(); 4422 $comp1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4423 $uc1 = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $comp1->get_id()]); 4424 4425 $ev1 = $ccg->create_evidence(['usercompetencyid' => $uc1->get_id()]); 4426 $ev2 = $ccg->create_evidence(['usercompetencyid' => $uc1->get_id()]); 4427 4428 $this->setAdminUser($u1); 4429 4430 $this->assertEquals(2, evidence::count_records()); 4431 api::delete_evidence($ev1); 4432 $this->assertEquals(1, evidence::count_records()); 4433 $this->assertFalse(evidence::record_exists($ev1->get_id())); 4434 $this->assertTrue(evidence::record_exists($ev2->get_id())); 4435 } 4436 4437 /** 4438 * @expectedException required_capability_exception 4439 */ 4440 public function test_delete_evidence_without_permissions() { 4441 $this->resetAfterTest(); 4442 $dg = $this->getDataGenerator(); 4443 $ccg = $dg->get_plugin_generator('core_competency'); 4444 4445 $u1 = $dg->create_user(); 4446 $f1 = $ccg->create_framework(); 4447 $comp1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4448 $uc1 = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $comp1->get_id()]); 4449 $ev1 = $ccg->create_evidence(['usercompetencyid' => $uc1->get_id()]); 4450 4451 $this->setUser($u1); 4452 4453 api::delete_evidence($ev1); 4454 } 4455 4456 public function test_list_plans_to_review() { 4457 $dg = $this->getDataGenerator(); 4458 $this->resetAfterTest(); 4459 $ccg = $dg->get_plugin_generator('core_competency'); 4460 $sysctx = context_system::instance(); 4461 $this->setAdminUser(); 4462 4463 $reviewer = $dg->create_user(); 4464 $roleallow = $dg->create_role(); 4465 $roleprohibit = $dg->create_role(); 4466 assign_capability('moodle/competency:planreview', CAP_ALLOW, $roleallow, $sysctx->id); 4467 assign_capability('moodle/competency:planreview', CAP_PROHIBIT, $roleprohibit, $sysctx->id); 4468 role_assign($roleallow, $reviewer->id, $sysctx->id); 4469 accesslib_clear_all_caches_for_unit_testing(); 4470 4471 $u1 = $dg->create_user(); 4472 $u2 = $dg->create_user(); 4473 $f1 = $ccg->create_framework(); 4474 $comp1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4475 $p1a = $ccg->create_plan(['userid' => $u1->id, 'status' => plan::STATUS_WAITING_FOR_REVIEW]); 4476 $p1b = $ccg->create_plan(['userid' => $u1->id, 'status' => plan::STATUS_IN_REVIEW, 'reviewerid' => $reviewer->id]); 4477 $p1c = $ccg->create_plan(['userid' => $u1->id, 'status' => plan::STATUS_DRAFT]); 4478 $p2a = $ccg->create_plan(['userid' => $u2->id, 'status' => plan::STATUS_WAITING_FOR_REVIEW]); 4479 $p2b = $ccg->create_plan(['userid' => $u2->id, 'status' => plan::STATUS_IN_REVIEW]); 4480 $p2c = $ccg->create_plan(['userid' => $u2->id, 'status' => plan::STATUS_ACTIVE]); 4481 $p2d = $ccg->create_plan(['userid' => $u2->id, 'status' => plan::STATUS_ACTIVE]); 4482 api::complete_plan($p2d); 4483 4484 // The reviewer can review all plans waiting for review, or in review where they are the reviewer. 4485 $this->setUser($reviewer); 4486 $result = api::list_plans_to_review(); 4487 $this->assertEquals(3, $result['count']); 4488 $this->assertEquals($p1a->get_id(), $result['plans'][0]->plan->get_id()); 4489 $this->assertEquals($p1b->get_id(), $result['plans'][1]->plan->get_id()); 4490 $this->assertEquals($p2a->get_id(), $result['plans'][2]->plan->get_id()); 4491 4492 // The reviewer cannot view the plans when they do not have the permission in the user's context. 4493 role_assign($roleprohibit, $reviewer->id, context_user::instance($u2->id)->id); 4494 accesslib_clear_all_caches_for_unit_testing(); 4495 $result = api::list_plans_to_review(); 4496 $this->assertEquals(2, $result['count']); 4497 $this->assertEquals($p1a->get_id(), $result['plans'][0]->plan->get_id()); 4498 $this->assertEquals($p1b->get_id(), $result['plans'][1]->plan->get_id()); 4499 } 4500 4501 public function test_list_user_competencies_to_review() { 4502 $dg = $this->getDataGenerator(); 4503 $this->resetAfterTest(); 4504 $ccg = $dg->get_plugin_generator('core_competency'); 4505 $sysctx = context_system::instance(); 4506 $this->setAdminUser(); 4507 4508 $reviewer = $dg->create_user(); 4509 $roleallow = $dg->create_role(); 4510 $roleprohibit = $dg->create_role(); 4511 assign_capability('moodle/competency:usercompetencyreview', CAP_ALLOW, $roleallow, $sysctx->id); 4512 assign_capability('moodle/competency:usercompetencyreview', CAP_PROHIBIT, $roleprohibit, $sysctx->id); 4513 role_assign($roleallow, $reviewer->id, $sysctx->id); 4514 accesslib_clear_all_caches_for_unit_testing(); 4515 4516 $u1 = $dg->create_user(); 4517 $u2 = $dg->create_user(); 4518 $f1 = $ccg->create_framework(); 4519 $c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4520 $c2 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4521 $c3 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); 4522 $uc1a = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c1->get_id(), 4523 'status' => user_competency::STATUS_IDLE]); 4524 $uc1b = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c2->get_id(), 4525 'status' => user_competency::STATUS_WAITING_FOR_REVIEW]); 4526 $uc1c = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c3->get_id(), 4527 'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $reviewer->id]); 4528 $uc2a = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c1->get_id(), 4529 'status' => user_competency::STATUS_WAITING_FOR_REVIEW]); 4530 $uc2b = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c2->get_id(), 4531 'status' => user_competency::STATUS_IDLE]); 4532 $uc2c = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c3->get_id(), 4533 'status' => user_competency::STATUS_IN_REVIEW]); 4534 4535 // The reviewer can review all plans waiting for review, or in review where they are the reviewer. 4536 $this->setUser($reviewer); 4537 $result = api::list_user_competencies_to_review(); 4538 $this->assertEquals(3, $result['count']); 4539 $this->assertEquals($uc2a->get_id(), $result['competencies'][0]->usercompetency->get_id()); 4540 $this->assertEquals($uc1b->get_id(), $result['competencies'][1]->usercompetency->get_id()); 4541 $this->assertEquals($uc1c->get_id(), $result['competencies'][2]->usercompetency->get_id()); 4542 4543 // The reviewer cannot view the plans when they do not have the permission in the user's context. 4544 role_assign($roleprohibit, $reviewer->id, context_user::instance($u2->id)->id); 4545 accesslib_clear_all_caches_for_unit_testing(); 4546 $result = api::list_user_competencies_to_review(); 4547 $this->assertEquals(2, $result['count']); 4548 $this->assertEquals($uc1b->get_id(), $result['competencies'][0]->usercompetency->get_id()); 4549 $this->assertEquals($uc1c->get_id(), $result['competencies'][1]->usercompetency->get_id()); 4550 } 4551 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |