See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace tool_lp; 18 19 use core_competency\api; 20 use core_competency\invalid_persistent_exception; 21 use core_competency\plan; 22 use core_competency\related_competency; 23 use core_competency\user_competency; 24 use core_competency\user_competency_plan; 25 use core_competency\plan_competency; 26 use core_competency\template; 27 use core_competency\template_competency; 28 use core_competency\course_competency_settings; 29 use externallib_advanced_testcase; 30 31 defined('MOODLE_INTERNAL') || die(); 32 33 global $CFG; 34 35 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 36 37 /** 38 * External learning plans webservice API tests. 39 * 40 * @package tool_lp 41 * @copyright 2015 Damyon Wiese 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class externallib_test extends externallib_advanced_testcase { 45 46 /** @var \stdClass $creator User with enough permissions to create insystem context. */ 47 protected $creator = null; 48 49 /** @var \stdClass $catcreator User with enough permissions to create incategory context. */ 50 protected $catcreator = null; 51 52 /** @var \stdClass $category Category */ 53 protected $category = null; 54 55 /** @var \stdClass $category Category */ 56 protected $othercategory = null; 57 58 /** @var \stdClass $user User with enough permissions to view insystem context */ 59 protected $user = null; 60 61 /** @var \stdClass $catuser User with enough permissions to view incategory context */ 62 protected $catuser = null; 63 64 /** @var int Creator role id */ 65 protected $creatorrole = null; 66 67 /** @var int User role id */ 68 protected $userrole = null; 69 70 /** 71 * Setup function- we will create a course and add an assign instance to it. 72 */ 73 protected function setUp(): void { 74 global $DB, $CFG; 75 76 $this->resetAfterTest(true); 77 78 // Create some users. 79 $creator = $this->getDataGenerator()->create_user(); 80 $user = $this->getDataGenerator()->create_user(); 81 $catuser = $this->getDataGenerator()->create_user(); 82 $catcreator = $this->getDataGenerator()->create_user(); 83 $category = $this->getDataGenerator()->create_category(); 84 $othercategory = $this->getDataGenerator()->create_category(); 85 $syscontext = \context_system::instance(); 86 $catcontext = \context_coursecat::instance($category->id); 87 88 // Fetching default authenticated user role. 89 $authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid)); 90 91 // Reset all default authenticated users permissions. 92 unassign_capability('moodle/competency:competencygrade', $authrole->id); 93 unassign_capability('moodle/competency:competencymanage', $authrole->id); 94 unassign_capability('moodle/competency:competencyview', $authrole->id); 95 unassign_capability('moodle/competency:planmanage', $authrole->id); 96 unassign_capability('moodle/competency:planmanagedraft', $authrole->id); 97 unassign_capability('moodle/competency:planmanageown', $authrole->id); 98 unassign_capability('moodle/competency:planview', $authrole->id); 99 unassign_capability('moodle/competency:planviewdraft', $authrole->id); 100 unassign_capability('moodle/competency:planviewown', $authrole->id); 101 unassign_capability('moodle/competency:planviewowndraft', $authrole->id); 102 unassign_capability('moodle/competency:templatemanage', $authrole->id); 103 unassign_capability('moodle/competency:templateview', $authrole->id); 104 unassign_capability('moodle/cohort:manage', $authrole->id); 105 unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id); 106 107 // Creating specific roles. 108 $this->creatorrole = create_role('Creator role', 'lpcreatorrole', 'learning plan creator role description'); 109 $this->userrole = create_role('User role', 'lpuserrole', 'learning plan user role description'); 110 111 assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); 112 assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id); 113 assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); 114 assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id); 115 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id); 116 assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id); 117 assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id); 118 assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id); 119 assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id); 120 assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id); 121 122 assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id); 123 assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id); 124 assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id); 125 assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id); 126 127 role_assign($this->creatorrole, $creator->id, $syscontext->id); 128 role_assign($this->creatorrole, $catcreator->id, $catcontext->id); 129 role_assign($this->userrole, $user->id, $syscontext->id); 130 role_assign($this->userrole, $catuser->id, $catcontext->id); 131 132 $this->creator = $creator; 133 $this->catcreator = $catcreator; 134 $this->user = $user; 135 $this->catuser = $catuser; 136 $this->category = $category; 137 $this->othercategory = $othercategory; 138 139 accesslib_clear_all_caches_for_unit_testing(); 140 } 141 142 public function test_search_users_by_capability() { 143 global $CFG; 144 $this->resetAfterTest(true); 145 146 $dg = $this->getDataGenerator(); 147 $ux = $dg->create_user(); 148 $u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan', 149 'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing', 150 'institution' => 'HQ')); 151 152 // First we search with no capability assigned. 153 $this->setUser($ux); 154 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 155 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 156 $this->assertCount(0, $result['users']); 157 $this->assertEquals(0, $result['count']); 158 159 // Now we assign a different capability. 160 $usercontext = \context_user::instance($u1->id); 161 $systemcontext = \context_system::instance(); 162 $customrole = $this->assignUserCapability('moodle/competency:planview', $usercontext->id); 163 164 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 165 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 166 $this->assertCount(0, $result['users']); 167 $this->assertEquals(0, $result['count']); 168 169 // Now we assign a matching capability in the same role. 170 $usercontext = \context_user::instance($u1->id); 171 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $customrole); 172 173 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 174 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 175 $this->assertCount(1, $result['users']); 176 $this->assertEquals(1, $result['count']); 177 178 // Now assign another role with the same capability (test duplicates). 179 role_assign($this->creatorrole, $ux->id, $usercontext->id); 180 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 181 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 182 $this->assertCount(1, $result['users']); 183 $this->assertEquals(1, $result['count']); 184 185 // Now lets try a different user with only the role at system level. 186 $ux2 = $dg->create_user(); 187 role_assign($this->creatorrole, $ux2->id, $systemcontext->id); 188 $this->setUser($ux2); 189 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 190 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 191 $this->assertCount(1, $result['users']); 192 $this->assertEquals(1, $result['count']); 193 194 // Now lets try a different user with only the role at user level. 195 $ux3 = $dg->create_user(); 196 role_assign($this->creatorrole, $ux3->id, $usercontext->id); 197 $this->setUser($ux3); 198 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 199 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 200 $this->assertCount(1, $result['users']); 201 $this->assertEquals(1, $result['count']); 202 203 // Switch back. 204 $this->setUser($ux); 205 206 // Now add a prevent override (will change nothing because we still have an ALLOW). 207 assign_capability('moodle/competency:planmanage', CAP_PREVENT, $customrole, $usercontext->id); 208 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 209 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 210 $this->assertCount(1, $result['users']); 211 $this->assertEquals(1, $result['count']); 212 213 // Now change to a prohibit override (should prevent access). 214 assign_capability('moodle/competency:planmanage', CAP_PROHIBIT, $customrole, $usercontext->id); 215 $result = external::search_users('yyylan', 'moodle/competency:planmanage'); 216 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 217 $this->assertCount(1, $result['users']); 218 $this->assertEquals(1, $result['count']); 219 220 } 221 222 /** 223 * Ensures that overrides, as well as system permissions, are respected. 224 */ 225 public function test_search_users_by_capability_the_comeback() { 226 $this->resetAfterTest(); 227 $dg = $this->getDataGenerator(); 228 229 $master = $dg->create_user(); 230 $manager = $dg->create_user(); 231 $slave1 = $dg->create_user(array('lastname' => 'MOODLER')); 232 $slave2 = $dg->create_user(array('lastname' => 'MOODLER')); 233 $slave3 = $dg->create_user(array('lastname' => 'MOODLER')); 234 235 $syscontext = \context_system::instance(); 236 $slave1context = \context_user::instance($slave1->id); 237 $slave2context = \context_user::instance($slave2->id); 238 $slave3context = \context_user::instance($slave3->id); 239 240 // Creating a role giving the site config. 241 $roleid = $dg->create_role(); 242 assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext->id, true); 243 244 // Create a role override for slave 2. 245 assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $slave2context->id, true); 246 247 // Assigning the role. 248 // Master -> System context. 249 // Manager -> User context. 250 role_assign($roleid, $master->id, $syscontext); 251 role_assign($roleid, $manager->id, $slave1context); 252 253 // Flush accesslib. 254 accesslib_clear_all_caches_for_unit_testing(); 255 256 // Confirm. 257 // Master has system permissions. 258 $this->setUser($master); 259 $this->assertTrue(has_capability('moodle/site:config', $syscontext)); 260 $this->assertTrue(has_capability('moodle/site:config', $slave1context)); 261 $this->assertFalse(has_capability('moodle/site:config', $slave2context)); 262 $this->assertTrue(has_capability('moodle/site:config', $slave3context)); 263 264 // Manager only has permissions in slave 1. 265 $this->setUser($manager); 266 $this->assertFalse(has_capability('moodle/site:config', $syscontext)); 267 $this->assertTrue(has_capability('moodle/site:config', $slave1context)); 268 $this->assertFalse(has_capability('moodle/site:config', $slave2context)); 269 $this->assertFalse(has_capability('moodle/site:config', $slave3context)); 270 271 // Now do the test. 272 $this->setUser($master); 273 $result = external::search_users('MOODLER', 'moodle/site:config'); 274 $this->assertCount(2, $result['users']); 275 $this->assertEquals(2, $result['count']); 276 $this->assertArrayHasKey($slave1->id, $result['users']); 277 $this->assertArrayHasKey($slave3->id, $result['users']); 278 279 $this->setUser($manager); 280 $result = external::search_users('MOODLER', 'moodle/site:config'); 281 $this->assertCount(1, $result['users']); 282 $this->assertEquals(1, $result['count']); 283 $this->assertArrayHasKey($slave1->id, $result['users']); 284 } 285 286 public function test_search_users() { 287 global $CFG; 288 $this->resetAfterTest(true); 289 290 $dg = $this->getDataGenerator(); 291 $ux = $dg->create_user(); 292 $u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan', 293 'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing', 294 'institution' => 'HQ')); 295 $u2 = $dg->create_user(array('idnumber' => 'Dogs', 'firstname' => 'Alice', 'lastname' => 'Dyyylan', 296 'email' => 'alyyyson@dyyylan.com', 'phone1' => '33333', 'phone2' => '77777', 'department' => 'Development', 297 'institution' => 'O2')); 298 $u3 = $dg->create_user(array('idnumber' => 'Fish', 'firstname' => 'Thomas', 'lastname' => 'Xow', 299 'email' => 'fishyyy@moodle.com', 'phone1' => '77777', 'phone2' => '33333', 'department' => 'Research', 300 'institution' => 'Bob')); 301 302 // We need to give the user the capability we are searching for on each of the test users. 303 $this->setAdminUser(); 304 $usercontext = \context_user::instance($u1->id); 305 $dummyrole = $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id); 306 $usercontext = \context_user::instance($u2->id); 307 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole); 308 $usercontext = \context_user::instance($u3->id); 309 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole); 310 311 $this->setUser($ux); 312 $usercontext = \context_user::instance($u1->id); 313 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole); 314 $usercontext = \context_user::instance($u2->id); 315 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole); 316 $usercontext = \context_user::instance($u3->id); 317 $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole); 318 319 $this->setAdminUser(); 320 321 // No identity fields. 322 $CFG->showuseridentity = ''; 323 $result = external::search_users('cats', 'moodle/competency:planmanage'); 324 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 325 $this->assertCount(0, $result['users']); 326 $this->assertEquals(0, $result['count']); 327 328 // Filter by name. 329 $CFG->showuseridentity = ''; 330 $result = external::search_users('dyyylan', 'moodle/competency:planmanage'); 331 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 332 $this->assertCount(2, $result['users']); 333 $this->assertEquals(2, $result['count']); 334 $this->assertEquals($u2->id, $result['users'][0]['id']); 335 $this->assertEquals($u1->id, $result['users'][1]['id']); 336 337 // Filter by institution and name. 338 $CFG->showuseridentity = 'institution'; 339 $result = external::search_users('bob', 'moodle/competency:planmanage'); 340 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 341 $this->assertCount(2, $result['users']); 342 $this->assertEquals(2, $result['count']); 343 $this->assertEquals($u1->id, $result['users'][0]['id']); 344 $this->assertEquals($u3->id, $result['users'][1]['id']); 345 346 // Filter by id number. 347 $CFG->showuseridentity = 'idnumber'; 348 $result = external::search_users('cats', 'moodle/competency:planmanage'); 349 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 350 $this->assertCount(1, $result['users']); 351 $this->assertEquals(1, $result['count']); 352 $this->assertEquals($u1->id, $result['users'][0]['id']); 353 $this->assertEquals($u1->idnumber, $result['users'][0]['idnumber']); 354 $this->assertEmpty($result['users'][0]['email']); 355 $this->assertEmpty($result['users'][0]['phone1']); 356 $this->assertEmpty($result['users'][0]['phone2']); 357 $this->assertEmpty($result['users'][0]['department']); 358 $this->assertEmpty($result['users'][0]['institution']); 359 360 // Filter by email. 361 $CFG->showuseridentity = 'email'; 362 $result = external::search_users('yyy', 'moodle/competency:planmanage'); 363 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 364 $this->assertCount(3, $result['users']); 365 $this->assertEquals(3, $result['count']); 366 $this->assertEquals($u2->id, $result['users'][0]['id']); 367 $this->assertEquals($u2->email, $result['users'][0]['email']); 368 $this->assertEquals($u1->id, $result['users'][1]['id']); 369 $this->assertEquals($u1->email, $result['users'][1]['email']); 370 $this->assertEquals($u3->id, $result['users'][2]['id']); 371 $this->assertEquals($u3->email, $result['users'][2]['email']); 372 373 // Filter by any. 374 $CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution'; 375 $result = external::search_users('yyy', 'moodle/competency:planmanage'); 376 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 377 $this->assertCount(3, $result['users']); 378 $this->assertEquals(3, $result['count']); 379 $this->assertArrayHasKey('idnumber', $result['users'][0]); 380 $this->assertArrayHasKey('email', $result['users'][0]); 381 $this->assertArrayHasKey('phone1', $result['users'][0]); 382 $this->assertArrayHasKey('phone2', $result['users'][0]); 383 $this->assertArrayHasKey('department', $result['users'][0]); 384 $this->assertArrayHasKey('institution', $result['users'][0]); 385 386 // Switch to a user that cannot view identity fields. 387 $this->setUser($ux); 388 $CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution'; 389 390 // Only names are included. 391 $result = external::search_users('fish'); 392 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 393 $this->assertCount(0, $result['users']); 394 $this->assertEquals(0, $result['count']); 395 396 $result = external::search_users('bob', 'moodle/competency:planmanage'); 397 $result = \external_api::clean_returnvalue(external::search_users_returns(), $result); 398 $this->assertCount(1, $result['users']); 399 $this->assertEquals(1, $result['count']); 400 $this->assertEquals($u1->id, $result['users'][0]['id']); 401 $this->assertEmpty($result['users'][0]['idnumber']); 402 $this->assertEmpty($result['users'][0]['email']); 403 $this->assertEmpty($result['users'][0]['phone1']); 404 $this->assertEmpty($result['users'][0]['phone2']); 405 $this->assertEmpty($result['users'][0]['department']); 406 $this->assertEmpty($result['users'][0]['institution']); 407 } 408 409 public function test_data_for_user_competency_summary_in_plan() { 410 global $CFG; 411 412 $this->setUser($this->creator); 413 414 $dg = $this->getDataGenerator(); 415 $lpg = $dg->get_plugin_generator('core_competency'); 416 417 $f1 = $lpg->create_framework(); 418 419 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); 420 421 $tpl = $lpg->create_template(); 422 $lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1->get('id'))); 423 424 $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'), 'name' => 'Evil')); 425 426 $uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get('id'))); 427 428 $evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1, true); 429 $evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 2, true); 430 431 $summary = external::data_for_user_competency_summary_in_plan($c1->get('id'), $plan->get('id')); 432 $this->assertTrue($summary->usercompetencysummary->cangrade); 433 $this->assertEquals('Evil', $summary->plan->name); 434 $this->assertEquals('B', $summary->usercompetencysummary->usercompetency->gradename); 435 $this->assertEquals('B', $summary->usercompetencysummary->evidence[0]->gradename); 436 $this->assertEquals('A', $summary->usercompetencysummary->evidence[1]->gradename); 437 } 438 439 public function test_data_for_user_competency_summary() { 440 $this->setUser($this->creator); 441 442 $dg = $this->getDataGenerator(); 443 $lpg = $dg->get_plugin_generator('core_competency'); 444 $f1 = $lpg->create_framework(); 445 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); 446 447 $evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true); 448 $evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true); 449 450 $summary = external::data_for_user_competency_summary($this->user->id, $c1->get('id')); 451 $this->assertTrue($summary->cangrade); 452 $this->assertEquals('B', $summary->usercompetency->gradename); 453 $this->assertEquals('B', $summary->evidence[0]->gradename); 454 $this->assertEquals('A', $summary->evidence[1]->gradename); 455 } 456 457 public function test_data_for_course_competency_page() { 458 $this->setAdminUser(); 459 460 $dg = $this->getDataGenerator(); 461 $lpg = $dg->get_plugin_generator('core_competency'); 462 $f1 = $lpg->create_framework(); 463 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'))); 464 $course1 = $dg->create_course(array('category' => $this->category->id)); 465 $cc = api::add_competency_to_course($course1->id, $c1->get('id')); 466 467 $evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true); 468 $evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true); 469 470 $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page'); 471 $page = $pagegenerator->create_instance(array('course' => $course1->id)); 472 $page2 = $pagegenerator->create_instance(array('course' => $course1->id)); 473 474 $cm = get_coursemodule_from_instance('page', $page->id); 475 $cm2 = get_coursemodule_from_instance('page', $page2->id); 476 // Add the competency to the course module. 477 $ccm = api::add_competency_to_course_module($cm, $c1->get('id')); 478 $summary = external::data_for_course_competencies_page($course1->id, 0); 479 $summary2 = external::data_for_course_competencies_page($course1->id, $cm->id); 480 $summary3 = external::data_for_course_competencies_page($course1->id, $cm2->id); 481 482 $this->assertEquals(count($summary->competencies), 1); 483 $this->assertEquals(count($summary->competencies), count($summary2->competencies)); 484 $this->assertEquals(count($summary3->competencies), 0); 485 } 486 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body