c10fc54389204c771188663567b03baa58a0d6e8
[moodle.git] / admin / tool / lp / tests / externallib_test.php
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  * External learning plans webservice API tests.
18  *
19  * @package tool_lp
20  * @copyright 2015 Damyon Wiese
21  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
24 defined('MOODLE_INTERNAL') || die();
26 global $CFG;
28 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
30 use tool_lp\api;
31 use tool_lp\external;
32 use tool_lp\plan;
33 use tool_lp\related_competency;
34 use tool_lp\user_competency;
35 use tool_lp\user_competency_plan;
36 use tool_lp\plan_competency;
37 use tool_lp\template_competency;
38 use tool_lp\course_competency_settings;
40 /**
41  * External learning plans webservice API tests.
42  *
43  * @package tool_lp
44  * @copyright 2015 Damyon Wiese
45  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46  */
47 class tool_lp_external_testcase extends externallib_advanced_testcase {
49     /** @var stdClass $creator User with enough permissions to create insystem context. */
50     protected $creator = null;
52     /** @var stdClass $learningplancreator User with enough permissions to create incategory context. */
53     protected $catcreator = null;
55     /** @var stdClass $category Category */
56     protected $category = null;
58     /** @var stdClass $user User with enough permissions to view insystem context */
59     protected $user = null;
61     /** @var stdClass $catuser User with enough permissions to view incategory context */
62     protected $catuser = null;
64     /** @var int Creator role id */
65     protected $creatorrole = null;
67     /** @var int User role id */
68     protected $userrole = null;
70     /** @var string scaleconfiguration */
71     protected $scaleconfiguration1 = null;
73     /** @var string scaleconfiguration */
74     protected $scaleconfiguration2 = null;
76     /** @var string catscaleconfiguration */
77     protected $scaleconfiguration3 = null;
79     /** @var string catscaleconfiguration */
80     protected $catscaleconfiguration4 = null;
82     /**
83      * Setup function- we will create a course and add an assign instance to it.
84      */
85     protected function setUp() {
86         global $DB;
88         $this->resetAfterTest(true);
90         // Create some users.
91         $creator = $this->getDataGenerator()->create_user();
92         $user = $this->getDataGenerator()->create_user();
93         $catuser = $this->getDataGenerator()->create_user();
94         $category = $this->getDataGenerator()->create_category();
95         $othercategory = $this->getDataGenerator()->create_category();
96         $catcreator = $this->getDataGenerator()->create_user();
98         $syscontext = context_system::instance();
99         $catcontext = context_coursecat::instance($category->id);
100         $othercatcontext = context_coursecat::instance($othercategory->id);
102         // Fetching default authenticated user role.
103         $userroles = get_archetype_roles('user');
104         $this->assertCount(1, $userroles);
105         $authrole = array_pop($userroles);
107         // Reset all default authenticated users permissions.
108         unassign_capability('tool/lp:competencygrade', $authrole->id);
109         unassign_capability('tool/lp:competencymanage', $authrole->id);
110         unassign_capability('tool/lp:competencyview', $authrole->id);
111         unassign_capability('tool/lp:planmanage', $authrole->id);
112         unassign_capability('tool/lp:planmanagedraft', $authrole->id);
113         unassign_capability('tool/lp:planmanageown', $authrole->id);
114         unassign_capability('tool/lp:planview', $authrole->id);
115         unassign_capability('tool/lp:planviewdraft', $authrole->id);
116         unassign_capability('tool/lp:planviewown', $authrole->id);
117         unassign_capability('tool/lp:planviewowndraft', $authrole->id);
118         unassign_capability('tool/lp:templatemanage', $authrole->id);
119         unassign_capability('tool/lp:templateview', $authrole->id);
120         unassign_capability('moodle/cohort:manage', $authrole->id);
121         unassign_capability('tool/lp:coursecompetencyconfigure', $authrole->id);
123         // Creating specific roles.
124         $this->creatorrole = create_role('Creator role', 'creatorrole', 'learning plan creator role description');
125         $this->userrole = create_role('User role', 'userrole', 'learning plan user role description');
127         assign_capability('tool/lp:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
128         assign_capability('tool/lp:competencycompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id);
129         assign_capability('tool/lp:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id);
130         assign_capability('tool/lp:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
131         assign_capability('tool/lp:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
132         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id);
133         assign_capability('tool/lp:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id);
134         assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
135         assign_capability('tool/lp:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
136         assign_capability('tool/lp:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id);
137         assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
138         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $syscontext->id);
139         assign_capability('tool/lp:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id);
140         assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
142         role_assign($this->creatorrole, $creator->id, $syscontext->id);
143         role_assign($this->creatorrole, $catcreator->id, $catcontext->id);
144         role_assign($this->userrole, $user->id, $syscontext->id);
145         role_assign($this->userrole, $catuser->id, $catcontext->id);
147         $this->creator = $creator;
148         $this->catcreator = $catcreator;
149         $this->user = $user;
150         $this->catuser = $catuser;
151         $this->category = $category;
152         $this->othercategory = $othercategory;
154         $this->getDataGenerator()->create_scale(array("id" => "1", "scale" => "value1, value2"));
155         $this->getDataGenerator()->create_scale(array("id" => "2", "scale" => "value3, value4"));
156         $this->getDataGenerator()->create_scale(array("id" => "3", "scale" => "value5, value6"));
157         $this->getDataGenerator()->create_scale(array("id" => "4", "scale" => "value7, value8"));
159         $this->scaleconfiguration1 = '[{"scaleid":"1"},{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .
160                 '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';
161         $this->scaleconfiguration2 = '[{"scaleid":"2"},{"name":"value3","id":1,"scaledefault":1,"proficient":0},' .
162                 '{"name":"value4","id":2,"scaledefault":0,"proficient":1}]';
163         $this->scaleconfiguration3 = '[{"scaleid":"3"},{"name":"value5","id":1,"scaledefault":1,"proficient":0},' .
164                 '{"name":"value6","id":2,"scaledefault":0,"proficient":1}]';
165         $this->scaleconfiguration4 = '[{"scaleid":"4"},{"name":"value8","id":1,"scaledefault":1,"proficient":0},' .
166                 '{"name":"value8","id":2,"scaledefault":0,"proficient":1}]';
167         accesslib_clear_all_caches_for_unit_testing();
168     }
170     protected function create_competency_framework($number = 1, $system = true) {
171         $scalepropname = 'scaleconfiguration' . $number;
172         $framework = array(
173             'shortname' => 'shortname' . $number,
174             'idnumber' => 'idnumber' . $number,
175             'description' => 'description' . $number,
176             'descriptionformat' => FORMAT_HTML,
177             'scaleid' => $number,
178             'scaleconfiguration' => $this->$scalepropname,
179             'visible' => true,
180             'contextid' => $system ? context_system::instance()->id : context_coursecat::instance($this->category->id)->id
181         );
182         $result = external::create_competency_framework($framework);
183         return (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
184     }
186     protected function create_plan($number, $userid, $templateid, $status, $duedate) {
187         $plan = array(
188             'name' => 'name' . $number,
189             'description' => 'description' . $number,
190             'descriptionformat' => FORMAT_HTML,
191             'userid' => $userid,
192             'templateid' => empty($templateid) ? null : $templateid,
193             'status' => $status,
194             'duedate' => $duedate
195         );
196         $result = external::create_plan($plan);
197         return (object) external_api::clean_returnvalue(external::create_plan_returns(), $result);
198     }
200     protected function create_template($number, $system) {
201         $template = array(
202             'shortname' => 'shortname' . $number,
203             'description' => 'description' . $number,
204             'descriptionformat' => FORMAT_HTML,
205             'duedate' => 0,
206             'visible' => true,
207             'contextid' => $system ? context_system::instance()->id : context_coursecat::instance($this->category->id)->id
208         );
209         $result = external::create_template($template);
210         return (object) external_api::clean_returnvalue(external::create_template_returns(), $result);
211     }
213     protected function update_template($templateid, $number) {
214         $template = array(
215             'id' => $templateid,
216             'shortname' => 'shortname' . $number,
217             'description' => 'description' . $number,
218             'descriptionformat' => FORMAT_HTML,
219             'visible' => true
220         );
221         $result = external::update_template($template);
222         return external_api::clean_returnvalue(external::update_template_returns(), $result);
223     }
225     protected function update_plan($planid, $number, $userid, $templateid, $status, $duedate) {
226         $plan = array(
227             'id' => $planid,
228             'name' => 'name' . $number,
229             'description' => 'description' . $number,
230             'descriptionformat' => FORMAT_HTML,
231             'userid' => $userid,
232             'templateid' => $templateid,
233             'status' => $status,
234             'duedate' => $duedate
235         );
236         $result = external::update_plan($plan);
237         return external_api::clean_returnvalue(external::update_plan_returns(), $result);
238     }
240     protected function update_competency_framework($id, $number = 1, $system = true) {
241         $scalepropname = 'scaleconfiguration' . $number;
242         $framework = array(
243             'id' => $id,
244             'shortname' => 'shortname' . $number,
245             'idnumber' => 'idnumber' . $number,
246             'description' => 'description' . $number,
247             'descriptionformat' => FORMAT_HTML,
248             'scaleid' => $number,
249             'scaleconfiguration' => $this->$scalepropname,
250             'visible' => true,
251             'contextid' => $system ? context_system::instance()->id : context_coursecat::instance($this->category->id)->id
252         );
253         $result = external::update_competency_framework($framework);
254         return external_api::clean_returnvalue(external::update_competency_framework_returns(), $result);
255     }
257     protected function create_competency($number, $frameworkid) {
258         $competency = array(
259             'shortname' => 'shortname' . $number,
260             'idnumber' => 'idnumber' . $number,
261             'description' => 'description' . $number,
262             'descriptionformat' => FORMAT_HTML,
263             'competencyframeworkid' => $frameworkid,
264             'sortorder' => 0
265         );
266         $result = external::create_competency($competency);
267         return (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
268     }
270     protected function update_competency($id, $number) {
271         $competency = array(
272             'id' => $id,
273             'shortname' => 'shortname' . $number,
274             'idnumber' => 'idnumber' . $number,
275             'description' => 'description' . $number,
276             'descriptionformat' => FORMAT_HTML,
277             'sortorder' => 0
278         );
279         $result = external::update_competency($competency);
280         return external_api::clean_returnvalue(external::update_competency_returns(), $result);
281     }
283     /**
284      * Test we can't create a competency framework with only read permissions.
285      */
286     public function test_create_competency_frameworks_with_read_permissions() {
287         $this->setExpectedException('required_capability_exception');
288         $this->setUser($this->user);
290         $result = $this->create_competency_framework(1, true);
291     }
293     /**
294      * Test we can't create a competency framework with only read permissions.
295      */
296     public function test_create_competency_frameworks_with_read_permissions_in_category() {
297         $this->setExpectedException('required_capability_exception');
298         $this->setUser($this->catuser);
299         $result = $this->create_competency_framework(1, false);
300     }
302     /**
303      * Test we can create a competency framework with manage permissions.
304      */
305     public function test_create_competency_frameworks_with_manage_permissions() {
306         $this->setUser($this->creator);
307         $result = $this->create_competency_framework(1, true);
309         $this->assertGreaterThan(0, $result->timecreated);
310         $this->assertGreaterThan(0, $result->timemodified);
311         $this->assertEquals($this->creator->id, $result->usermodified);
312         $this->assertEquals('shortname1', $result->shortname);
313         $this->assertEquals('idnumber1', $result->idnumber);
314         $this->assertEquals('description1', $result->description);
315         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
316         $this->assertEquals(1, $result->scaleid);
317         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
318         $this->assertEquals(true, $result->visible);
319     }
321     /**
322      * Test we can create a competency framework with manage permissions.
323      */
324     public function test_create_competency_frameworks_with_manage_permissions_in_category() {
325         $this->setUser($this->catcreator);
326         $result = $this->create_competency_framework(1, false);
328         $this->assertGreaterThan(0, $result->timecreated);
329         $this->assertGreaterThan(0, $result->timemodified);
330         $this->assertEquals($this->catcreator->id, $result->usermodified);
331         $this->assertEquals('shortname1', $result->shortname);
332         $this->assertEquals('idnumber1', $result->idnumber);
333         $this->assertEquals('description1', $result->description);
334         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
335         $this->assertEquals(1, $result->scaleid);
336         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
337         $this->assertEquals(true, $result->visible);
339         try {
340             $result = $this->create_competency_framework(1, true);
341             $this->fail('User cannot create a framework at system level.');
342         } catch (required_capability_exception $e) {
343             // All good.
344         }
345     }
347     /**
348      * Test we cannot create a competency framework with nasty data.
349      */
350     public function test_create_competency_frameworks_with_nasty_data() {
351         $this->setUser($this->creator);
352         $this->setExpectedException('invalid_parameter_exception');
353         $framework = array(
354             'shortname' => 'short<a href="">',
355             'idnumber' => 'id;"number',
356             'description' => 'de<>\\..scription',
357             'descriptionformat' => FORMAT_HTML,
358             'scaleid' => 1,
359             'scaleconfiguration' => $this->scaleconfiguration1,
360             'visible' => true,
361             'contextid' => context_system::instance()->id
362         );
363         $result = external::create_competency_framework($framework);
364     }
366     /**
367      * Test we can read a competency framework with manage permissions.
368      */
369     public function test_read_competency_frameworks_with_manage_permissions() {
370         $this->setUser($this->creator);
371         $result = $this->create_competency_framework(1, true);
373         $id = $result->id;
374         $result = external::read_competency_framework($id);
375         $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
377         $this->assertGreaterThan(0, $result->timecreated);
378         $this->assertGreaterThan(0, $result->timemodified);
379         $this->assertEquals($this->creator->id, $result->usermodified);
380         $this->assertEquals('shortname1', $result->shortname);
381         $this->assertEquals('idnumber1', $result->idnumber);
382         $this->assertEquals('description1', $result->description);
383         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
384         $this->assertEquals(1, $result->scaleid);
385         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
386         $this->assertEquals(true, $result->visible);
387     }
389     /**
390      * Test we can read a competency framework with manage permissions.
391      */
392     public function test_read_competency_frameworks_with_manage_permissions_in_category() {
393         $this->setUser($this->creator);
395         $insystem = $this->create_competency_framework(1, true);
396         $incat = $this->create_competency_framework(2, false);
398         $this->setUser($this->catcreator);
399         $id = $incat->id;
400         $result = external::read_competency_framework($id);
401         $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
403         $this->assertGreaterThan(0, $result->timecreated);
404         $this->assertGreaterThan(0, $result->timemodified);
405         $this->assertEquals($this->creator->id, $result->usermodified);
406         $this->assertEquals('shortname2', $result->shortname);
407         $this->assertEquals('idnumber2', $result->idnumber);
408         $this->assertEquals('description2', $result->description);
409         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
410         $this->assertEquals(2, $result->scaleid);
411         $this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);
412         $this->assertEquals(true, $result->visible);
414         try {
415             $id = $insystem->id;
416             $result = external::read_competency_framework($id);
417             $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
418             $this->fail('User cannot read a framework at system level.');
419         } catch (required_capability_exception $e) {
420             // All good.
421         }
422     }
424     /**
425      * Test we can read a competency framework with read permissions.
426      */
427     public function test_read_competency_frameworks_with_read_permissions() {
428         $this->setUser($this->creator);
429         $result = $this->create_competency_framework(1, true);
431         // Switch users to someone with less permissions.
432         $this->setUser($this->user);
433         $id = $result->id;
434         $result = external::read_competency_framework($id);
435         $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
437         $this->assertGreaterThan(0, $result->timecreated);
438         $this->assertGreaterThan(0, $result->timemodified);
439         $this->assertEquals($this->creator->id, $result->usermodified);
440         $this->assertEquals('shortname1', $result->shortname);
441         $this->assertEquals('idnumber1', $result->idnumber);
442         $this->assertEquals('description1', $result->description);
443         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
444         $this->assertEquals(1, $result->scaleid);
445         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
446         $this->assertEquals(true, $result->visible);
447     }
448     /**
449      * Test we can read a competency framework with read permissions.
450      */
451     public function test_read_competency_frameworks_with_read_permissions_in_category() {
452         $this->setUser($this->creator);
454         $insystem = $this->create_competency_framework(1, true);
455         $incat = $this->create_competency_framework(2, false);
457         // Switch users to someone with less permissions.
458         $this->setUser($this->catuser);
459         $id = $incat->id;
460         $result = external::read_competency_framework($id);
461         $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
463         $this->assertGreaterThan(0, $result->timecreated);
464         $this->assertGreaterThan(0, $result->timemodified);
465         $this->assertEquals($this->creator->id, $result->usermodified);
466         $this->assertEquals('shortname2', $result->shortname);
467         $this->assertEquals('idnumber2', $result->idnumber);
468         $this->assertEquals('description2', $result->description);
469         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
470         $this->assertEquals(2, $result->scaleid);
471         $this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);
472         $this->assertEquals(true, $result->visible);
474         // Switching to user with no permissions.
475         try {
476             $result = external::read_competency_framework($insystem->id);
477             $this->fail('Current user cannot should not be able to read the framework.');
478         } catch (required_capability_exception $e) {
479             // All good.
480         }
481     }
483     /**
484      * Test we can delete a competency framework with manage permissions.
485      */
486     public function test_delete_competency_frameworks_with_manage_permissions() {
487         $this->setUser($this->creator);
488         $result = $this->create_competency_framework(1, true);
490         $id = $result->id;
491         $result = external::delete_competency_framework($id);
492         $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
494         $this->assertTrue($result);
495     }
497     /**
498      * Test we can delete a competency framework with manage permissions.
499      */
500     public function test_delete_competency_frameworks_with_manage_permissions_in_category() {
501         $this->setUser($this->creator);
503         $insystem = $this->create_competency_framework(1, true);
504         $incat = $this->create_competency_framework(2, false);
506         $this->setUser($this->catcreator);
507         $id = $incat->id;
508         $result = external::delete_competency_framework($id);
509         $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
511         $this->assertTrue($result);
513         try {
514             $id = $insystem->id;
515             $result = external::delete_competency_framework($id);
516             $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
517             $this->fail('Current user cannot should not be able to delete the framework.');
518         } catch (required_capability_exception $e) {
519             // All good.
520         }
521     }
523     /**
524      * Test we can delete a competency framework with read permissions.
525      */
526     public function test_delete_competency_frameworks_with_read_permissions() {
527         $this->setExpectedException('required_capability_exception');
528         $this->setUser($this->creator);
529         $result = $this->create_competency_framework(1, true);
531         $id = $result->id;
532         // Switch users to someone with less permissions.
533         $this->setUser($this->user);
534         $result = external::delete_competency_framework($id);
535     }
537     /**
538      * Test we can update a competency framework with manage permissions.
539      */
540     public function test_update_competency_frameworks_with_manage_permissions() {
541         $this->setUser($this->creator);
542         $result = $this->create_competency_framework(1, true);
544         $result = $this->update_competency_framework($result->id, 2, true);
546         $this->assertTrue($result);
547     }
549     /**
550      * Test we can update a competency framework with manage permissions.
551      */
552     public function test_update_competency_frameworks_with_manage_permissions_in_category() {
553         $this->setUser($this->creator);
555         $insystem = $this->create_competency_framework(1, true);
556         $incat = $this->create_competency_framework(2, false);
558         $this->setUser($this->catcreator);
559         $id = $incat->id;
561         $result = $this->update_competency_framework($incat->id, 3, false);
563         $this->assertTrue($result);
565         try {
566             $result = $this->update_competency_framework($insystem->id, 4, true);
567             $this->fail('Current user should not be able to update the framework.');
568         } catch (required_capability_exception $e) {
569             // All good.
570         }
571     }
573     public function test_update_framework_scale() {
574         $this->setUser($this->creator);
575         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
577         $s1 = $this->getDataGenerator()->create_scale();
579         $f1 = $lpg->create_framework(array('scaleid' => 1));
580         $f2 = $lpg->create_framework(array('scaleid' => 1));
581         $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
582         $c2 = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
584         $this->assertEquals(1, $f1->get_scaleid());
586         // Make the scale of f2 being used.
587         $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2->get_id()));
589         // Changing the framework where the scale is not used.
590         $result = $this->update_competency_framework($f1->get_id(), 3, true);
592         $f1 = new \tool_lp\competency_framework($f1->get_id());
593         $this->assertEquals(3, $f1->get_scaleid());
595         // Changing the framework where the scale is used.
596         try {
597             $result = $this->update_competency_framework($f2->get_id(), 4, true);
598             $this->fail('The scale cannot be changed once used.');
599         } catch (\tool_lp\invalid_persistent_exception $e) {
600             $this->assertRegexp('/scaleid/', $e->getMessage());
601         }
602     }
604     /**
605      * Test we can update a competency framework with read permissions.
606      */
607     public function test_update_competency_frameworks_with_read_permissions() {
608         $this->setExpectedException('required_capability_exception');
609         $this->setUser($this->creator);
610         $result = $this->create_competency_framework(1, true);
612         $this->setUser($this->user);
613         $result = $this->update_competency_framework($result->id, 2, true);
614     }
616     /**
617      * Test we can list and count competency frameworks with manage permissions.
618      */
619     public function test_list_and_count_competency_frameworks_with_manage_permissions() {
620         $this->setUser($this->creator);
621         $result = $this->create_competency_framework(1, true);
622         $result = $this->create_competency_framework(2, true);
623         $result = $this->create_competency_framework(3, true);
624         $result = $this->create_competency_framework(4, false);
626         $result = external::count_competency_frameworks(array('contextid' => context_system::instance()->id), 'self');
627         $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
629         $this->assertEquals($result, 3);
631         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
632             array('contextid' => context_system::instance()->id), 'self', false);
633         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
635         $this->assertEquals(count($result), 3);
636         $result = (object) $result[0];
638         $this->assertGreaterThan(0, $result->timecreated);
639         $this->assertGreaterThan(0, $result->timemodified);
640         $this->assertEquals($this->creator->id, $result->usermodified);
641         $this->assertEquals('shortname1', $result->shortname);
642         $this->assertEquals('idnumber1', $result->idnumber);
643         $this->assertEquals('description1', $result->description);
644         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
645         $this->assertEquals(1, $result->scaleid);
646         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
647         $this->assertEquals(true, $result->visible);
648     }
650     public function list_competency_frameworks_with_query() {
651         $this->setUser($this->creator);
652         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
653         $framework1 = $lpg->create_framework(array(
654             'shortname' => 'shortname_beetroot',
655             'idnumber' => 'idnumber_cinnamon',
656             'description' => 'description',
657             'descriptionformat' => FORMAT_HTML,
658             'visible' => true,
659             'contextid' => context_system::instance()->id
660         ));
661         $framework2 = $lpg->create_framework(array(
662             'shortname' => 'shortname_citrus',
663             'idnumber' => 'idnumber_beer',
664             'description' => 'description',
665             'descriptionformat' => FORMAT_HTML,
666             'visible' => true,
667             'contextid' => context_system::instance()->id
668         ));
670         // Search on both ID number and shortname.
671         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
672             array('contextid' => context_system::instance()->id), 'self', false, 'bee');
673         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
674         $this->assertCount(2, $result);
675         $f = (object) array_shift($result);
676         $this->assertEquals($framework1->get_id(), $f->get_id());
677         $f = (object) array_shift($result);
678         $this->assertEquals($framework2->get_id(), $f->get_id());
680         // Search on ID number.
681         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
682             array('contextid' => context_system::instance()->id), 'self', false, 'beer');
683         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
684         $this->assertCount(1, $result);
685         $f = (object) array_shift($result);
686         $this->assertEquals($framework2->get_id(), $f->get_id());
688         // Search on shortname.
689         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
690             array('contextid' => context_system::instance()->id), 'self', false, 'cinnamon');
691         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
692         $this->assertCount(1, $result);
693         $f = (object) array_shift($result);
694         $this->assertEquals($framework1->get_id(), $f->get_id());
696         // No match.
697         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
698             array('contextid' => context_system::instance()->id), 'self', false, 'pwnd!');
699         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
700         $this->assertCount(0, $result);
701     }
703     /**
704      * Test we can list and count competency frameworks with read permissions.
705      */
706     public function test_list_and_count_competency_frameworks_with_read_permissions() {
707         $this->setUser($this->creator);
708         $result = $this->create_competency_framework(1, true);
709         $result = $this->create_competency_framework(2, true);
710         $result = $this->create_competency_framework(3, true);
711         $result = $this->create_competency_framework(4, false);
713         $this->setUser($this->user);
714         $result = external::count_competency_frameworks(array('contextid' => context_system::instance()->id), 'self');
715         $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
716         $this->assertEquals($result, 3);
718         $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
719             array('contextid' => context_system::instance()->id), 'self', false);
720         $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
722         $this->assertEquals(count($result), 3);
723         $result = (object) $result[0];
725         $this->assertGreaterThan(0, $result->timecreated);
726         $this->assertGreaterThan(0, $result->timemodified);
727         $this->assertEquals($this->creator->id, $result->usermodified);
728         $this->assertEquals('shortname1', $result->shortname);
729         $this->assertEquals('idnumber1', $result->idnumber);
730         $this->assertEquals('description1', $result->description);
731         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
732         $this->assertEquals(1, $result->scaleid);
733         $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
734         $this->assertEquals(true, $result->visible);
735     }
737     /**
738      * Test we can't create a competency with only read permissions.
739      */
740     public function test_create_competency_with_read_permissions() {
741         $this->setExpectedException('required_capability_exception');
742         $framework = $this->create_competency_framework(1, true);
743         $this->setUser($this->user);
744         $competency = $this->create_competency(1, $framework->id);
745     }
747     /**
748      * Test we can create a competency with manage permissions.
749      */
750     public function test_create_competency_with_manage_permissions() {
751         $this->setUser($this->creator);
752         $framework = $this->create_competency_framework(1, true);
753         $competency = $this->create_competency(1, $framework->id);
755         $this->assertGreaterThan(0, $competency->timecreated);
756         $this->assertGreaterThan(0, $competency->timemodified);
757         $this->assertEquals($this->creator->id, $competency->usermodified);
758         $this->assertEquals('shortname1', $competency->shortname);
759         $this->assertEquals('idnumber1', $competency->idnumber);
760         $this->assertEquals('description1', $competency->description);
761         $this->assertEquals(FORMAT_HTML, $competency->descriptionformat);
762         $this->assertEquals(0, $competency->parentid);
763         $this->assertEquals($framework->id, $competency->competencyframeworkid);
764     }
767     /**
768      * Test we can create a competency with manage permissions.
769      */
770     public function test_create_competency_with_manage_permissions_in_category() {
771         $this->setUser($this->creator);
773         $insystem = $this->create_competency_framework(1, true);
774         $incat = $this->create_competency_framework(2, false);
776         $this->setUser($this->catcreator);
778         $competency = $this->create_competency(1, $incat->id);
780         $this->assertGreaterThan(0, $competency->timecreated);
781         $this->assertGreaterThan(0, $competency->timemodified);
782         $this->assertEquals($this->catcreator->id, $competency->usermodified);
783         $this->assertEquals('shortname1', $competency->shortname);
784         $this->assertEquals('idnumber1', $competency->idnumber);
785         $this->assertEquals('description1', $competency->description);
786         $this->assertEquals(FORMAT_HTML, $competency->descriptionformat);
787         $this->assertEquals(0, $competency->parentid);
788         $this->assertEquals($incat->id, $competency->competencyframeworkid);
790         try {
791             $competency = $this->create_competency(2, $insystem->id);
792             $this->fail('User should not be able to create a competency in system context.');
793         } catch (required_capability_exception $e) {
794             // All good.
795         }
796     }
798     /**
799      * Test we cannot create a competency with nasty data.
800      */
801     public function test_create_competency_with_nasty_data() {
802         $this->setUser($this->creator);
803         $framework = $this->create_competency_framework(1, true);
804         $this->setExpectedException('invalid_parameter_exception');
805         $competency = array(
806             'shortname' => 'shortname<a href="">',
807             'idnumber' => 'id;"number',
808             'description' => 'de<>\\..scription',
809             'descriptionformat' => FORMAT_HTML,
810             'competencyframeworkid' => $framework->id,
811             'sortorder' => 0
812         );
813         $result = external::create_competency($competency);
814         $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
815     }
817     /**
818      * Test we can read a competency with manage permissions.
819      */
820     public function test_read_competencies_with_manage_permissions() {
821         $this->setUser($this->creator);
822         $framework = $this->create_competency_framework(1, true);
823         $competency = $this->create_competency(1, $framework->id);
825         $id = $competency->id;
826         $result = external::read_competency($id);
827         $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
829         $this->assertGreaterThan(0, $result->timecreated);
830         $this->assertGreaterThan(0, $result->timemodified);
831         $this->assertEquals($this->creator->id, $result->usermodified);
832         $this->assertEquals('shortname1', $result->shortname);
833         $this->assertEquals('idnumber1', $result->idnumber);
834         $this->assertEquals('description1', $result->description);
835         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
836         $this->assertEquals(0, $result->parentid);
837         $this->assertEquals($framework->id, $result->competencyframeworkid);
838     }
840     /**
841      * Test we can read a competency with manage permissions.
842      */
843     public function test_read_competencies_with_manage_permissions_in_category() {
844         $this->setUser($this->creator);
846         $sysframework = $this->create_competency_framework(1, true);
847         $insystem = $this->create_competency(1, $sysframework->id);
849         $catframework = $this->create_competency_framework(2, false);
850         $incat = $this->create_competency(2, $catframework->id);
852         $this->setUser($this->catcreator);
853         $id = $incat->id;
854         $result = external::read_competency($id);
855         $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
857         $this->assertGreaterThan(0, $result->timecreated);
858         $this->assertGreaterThan(0, $result->timemodified);
859         $this->assertEquals($this->creator->id, $result->usermodified);
860         $this->assertEquals('shortname2', $result->shortname);
861         $this->assertEquals('idnumber2', $result->idnumber);
862         $this->assertEquals('description2', $result->description);
863         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
864         $this->assertEquals(0, $result->parentid);
865         $this->assertEquals($catframework->id, $result->competencyframeworkid);
867         try {
868             external::read_competency($insystem->id);
869             $this->fail('User should not be able to read a competency in system context.');
870         } catch (required_capability_exception $e) {
871             // All good.
872         }
873     }
875     /**
876      * Test we can read a competency with read permissions.
877      */
878     public function test_read_competencies_with_read_permissions() {
879         $this->setUser($this->creator);
880         $framework = $this->create_competency_framework(1, true);
881         $competency = $this->create_competency(1, $framework->id);
883         // Switch users to someone with less permissions.
884         $this->setUser($this->user);
885         $id = $competency->id;
886         $result = external::read_competency($id);
887         $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
889         $this->assertGreaterThan(0, $result->timecreated);
890         $this->assertGreaterThan(0, $result->timemodified);
891         $this->assertEquals($this->creator->id, $result->usermodified);
892         $this->assertEquals('shortname1', $result->shortname);
893         $this->assertEquals('idnumber1', $result->idnumber);
894         $this->assertEquals('description1', $result->description);
895         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
896         $this->assertEquals(0, $result->parentid);
897         $this->assertEquals($framework->id, $result->competencyframeworkid);
898     }
900     /**
901      * Test we can read a competency with read permissions.
902      */
903     public function test_read_competencies_with_read_permissions_in_category() {
904         $this->setUser($this->creator);
905         $sysframework = $this->create_competency_framework(1, true);
906         $insystem = $this->create_competency(1, $sysframework->id);
907         $catframework = $this->create_competency_framework(2, false);
908         $incat = $this->create_competency(2, $catframework->id);
910         // Switch users to someone with less permissions.
911         $this->setUser($this->catuser);
912         $id = $incat->id;
913         $result = external::read_competency($id);
914         $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
916         $this->assertGreaterThan(0, $result->timecreated);
917         $this->assertGreaterThan(0, $result->timemodified);
918         $this->assertEquals($this->creator->id, $result->usermodified);
919         $this->assertEquals('shortname2', $result->shortname);
920         $this->assertEquals('idnumber2', $result->idnumber);
921         $this->assertEquals('description2', $result->description);
922         $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
923         $this->assertEquals(0, $result->parentid);
924         $this->assertEquals($catframework->id, $result->competencyframeworkid);
926         try {
927             external::read_competency($insystem->id);
928             $this->fail('User should not be able to read a competency in system context.');
929         } catch (required_capability_exception $e) {
930             // All good.
931         }
932     }
934     /**
935      * Test we can delete a competency with manage permissions.
936      */
937     public function test_delete_competency_with_manage_permissions() {
938         $this->setUser($this->creator);
939         $framework = $this->create_competency_framework(1, true);
940         $result = $this->create_competency(1, $framework->id);
942         $id = $result->id;
943         $result = external::delete_competency($id);
944         $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
946         $this->assertTrue($result);
947     }
949     /**
950      * Test we can delete a competency with manage permissions.
951      */
952     public function test_delete_competency_with_manage_permissions_in_category() {
953         $this->setUser($this->creator);
955         $sysframework = $this->create_competency_framework(1, true);
956         $insystem = $this->create_competency(1, $sysframework->id);
957         $catframework = $this->create_competency_framework(2, false);
958         $incat = $this->create_competency(2, $catframework->id);
960         $this->setUser($this->catcreator);
961         $id = $incat->id;
962         $result = external::delete_competency($id);
963         $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
965         $this->assertTrue($result);
967         try {
968             $result = external::delete_competency($insystem->id);
969             $this->fail('User should not be able to delete a competency in system context.');
970         } catch (required_capability_exception $e) {
971             // All good.
972         }
973     }
975     /**
976      * Test we can delete a competency with read permissions.
977      */
978     public function test_delete_competency_with_read_permissions() {
979         $this->setExpectedException('required_capability_exception');
980         $this->setUser($this->creator);
981         $framework = $this->create_competency_framework(1, true);
982         $result = $this->create_competency(1, $framework->id);
984         $id = $result->id;
985         // Switch users to someone with less permissions.
986         $this->setUser($this->user);
987         $result = external::delete_competency($id);
988     }
990     /**
991      * Test we can update a competency with manage permissions.
992      */
993     public function test_update_competency_with_manage_permissions() {
994         $this->setUser($this->creator);
995         $framework = $this->create_competency_framework(1, true);
996         $result = $this->create_competency(1, $framework->id);
998         $result = $this->update_competency($result->id, 2);
1000         $this->assertTrue($result);
1001     }
1003     /**
1004      * Test we can update a competency with manage permissions.
1005      */
1006     public function test_update_competency_with_manage_permissions_in_category() {
1007         $this->setUser($this->creator);
1009         $sysframework = $this->create_competency_framework(1, true);
1010         $insystem = $this->create_competency(1, $sysframework->id);
1011         $catframework = $this->create_competency_framework(2, false);
1012         $incat = $this->create_competency(2, $catframework->id);
1014         $this->setUser($this->catcreator);
1016         $result = $this->update_competency($incat->id, 2);
1018         $this->assertTrue($result);
1020         try {
1021             $result = $this->update_competency($insystem->id, 3);
1022             $this->fail('User should not be able to update a competency in system context.');
1023         } catch (required_capability_exception $e) {
1024             // All good.
1025         }
1026     }
1028     /**
1029      * Test we can update a competency with read permissions.
1030      */
1031     public function test_update_competency_with_read_permissions() {
1032         $this->setExpectedException('required_capability_exception');
1033         $this->setUser($this->creator);
1034         $framework = $this->create_competency_framework(1, true);
1035         $result = $this->create_competency(1, $framework->id);
1037         $this->setUser($this->user);
1038         $result = $this->update_competency($result->id, 2);
1039     }
1041     /**
1042      * Test count competencies with filters.
1043      */
1044     public function test_count_competencies_with_filters() {
1045         $this->setUser($this->creator);
1047         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1048         $f1 = $lpg->create_framework();
1049         $f2 = $lpg->create_framework();
1050         $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1051         $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'shortname' => 'A'));
1052         $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1053         $c4 = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
1054         $c5 = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
1056         $result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f2->get_id())));
1057         $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1058         $this->assertEquals(2, $result);
1060         $result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f1->get_id())));
1061         $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1062         $this->assertEquals(3, $result);
1064         $result = external::count_competencies(array(array('column' => 'shortname', 'value' => 'A')));
1065         $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1066         $this->assertEquals(1, $result);
1067     }
1069     /**
1070      * Test we can list and count competencies with manage permissions.
1071      */
1072     public function test_list_and_count_competencies_with_manage_permissions() {
1073         $this->setUser($this->creator);
1074         $framework = $this->create_competency_framework(1, true);
1075         $result = $this->create_competency(1, $framework->id);
1076         $result = $this->create_competency(2, $framework->id);
1077         $result = $this->create_competency(3, $framework->id);
1079         $result = external::count_competencies(array());
1080         $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1082         $this->assertEquals($result, 3);
1084         array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, context_system::instance()->id));
1085         $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
1087         $this->assertEquals(count($result), 3);
1088         $result = (object) $result[0];
1090         $this->assertGreaterThan(0, $result->timecreated);
1091         $this->assertGreaterThan(0, $result->timemodified);
1092         $this->assertEquals($this->creator->id, $result->usermodified);
1093         $this->assertEquals('shortname1', $result->shortname);
1094         $this->assertEquals('idnumber1', $result->idnumber);
1095         $this->assertEquals('description1', $result->description);
1096     }
1098     /**
1099      * Test we can list and count competencies with read permissions.
1100      */
1101     public function test_list_and_count_competencies_with_read_permissions() {
1102         $this->setUser($this->creator);
1103         $framework = $this->create_competency_framework(1, true);
1104         $result = $this->create_competency(1, $framework->id);
1105         $result = $this->create_competency(2, $framework->id);
1106         $result = $this->create_competency(3, $framework->id);
1108         $this->setUser($this->user);
1110         $result = external::count_competencies(array());
1111         $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1113         $this->assertEquals($result, 3);
1115         array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, context_system::instance()->id));
1116         $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
1118         $this->assertEquals(count($result), 3);
1119         $result = (object) $result[0];
1121         $this->assertGreaterThan(0, $result->timecreated);
1122         $this->assertGreaterThan(0, $result->timemodified);
1123         $this->assertEquals($this->creator->id, $result->usermodified);
1124         $this->assertEquals('shortname1', $result->shortname);
1125         $this->assertEquals('idnumber1', $result->idnumber);
1126         $this->assertEquals('description1', $result->description);
1127     }
1129     /**
1130      * Test we can search for competencies.
1131      */
1132     public function test_search_competencies_with_read_permissions() {
1133         $this->setUser($this->creator);
1134         $framework = $this->create_competency_framework(1, true);
1135         $result = $this->create_competency(1, $framework->id);
1136         $result = $this->create_competency(2, $framework->id);
1137         $result = $this->create_competency(3, $framework->id);
1139         $this->setUser($this->user);
1141         $result = external::search_competencies('short', $framework->id);
1142         $result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);
1144         $this->assertEquals(count($result), 3);
1145         $result = (object) $result[0];
1147         $this->assertGreaterThan(0, $result->timecreated);
1148         $this->assertGreaterThan(0, $result->timemodified);
1149         $this->assertEquals($this->creator->id, $result->usermodified);
1150         $this->assertEquals('shortname1', $result->shortname);
1151         $this->assertEquals('idnumber1', $result->idnumber);
1152         $this->assertEquals('description1', $result->description);
1153     }
1155     /**
1156      * Test plans creation and updates.
1157      */
1158     public function test_create_and_update_plans() {
1159         $syscontext = context_system::instance();
1161         $this->setUser($this->creator);
1162         $plan0 = $this->create_plan(1, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);
1164         $this->setUser($this->user);
1166         try {
1167             $plan1 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1168             $this->fail('Exception expected due to not permissions to create draft plans');
1169         } catch (moodle_exception $e) {
1170             $this->assertEquals('nopermissions', $e->errorcode);
1171         }
1173         assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1174         accesslib_clear_all_caches_for_unit_testing();
1176         $this->setUser($this->user);
1178         $plan2 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1180         try {
1181             $plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1182             $this->fail('Exception expected due to not permissions to create active plans');
1183         } catch (moodle_exception $e) {
1184             $this->assertEquals('nopermissions', $e->errorcode);
1185         }
1186         try {
1187             $plan3 = $this->update_plan($plan2->id, 4, $this->user->id, 0, plan::STATUS_COMPLETE, 0);
1188             $this->fail('We cannot complete a plan using api::update_plan().');
1189         } catch (coding_exception $e) {
1190             $this->assertTrue(true);
1191         }
1193         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1194         accesslib_clear_all_caches_for_unit_testing();
1196         $plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1197         try {
1198             $plan4 = $this->create_plan(6, $this->creator->id, 0, plan::STATUS_COMPLETE, 0);
1199             $this->fail('Plans cannot be created as complete.');
1200         } catch (coding_exception $e) {
1201             $this->assertRegexp('/A plan cannot be created as complete./', $e->getMessage());
1202         }
1204         try {
1205             $plan0 = $this->update_plan($plan0->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1206         } catch (moodle_exception $e) {
1207             $this->assertEquals('nopermissions', $e->errorcode);
1208         }
1210         unassign_capability('tool/lp:planmanageown', $this->userrole, $syscontext->id);
1211         unassign_capability('tool/lp:planmanageowndraft', $this->userrole, $syscontext->id);
1212         accesslib_clear_all_caches_for_unit_testing();
1214         try {
1215             // Cannot be updated even if they created it.
1216             $this->update_plan($plan2->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1217             $this->fail('The user can not update their own plan without permissions.');
1218         } catch (required_capability_exception $e) {
1219             $this->assertRegexp('/Manage learning plans./', $e->getMessage());
1220         }
1221     }
1223     /**
1224      * Test complete plan.
1225      */
1226     public function test_complete_plan() {
1227         $syscontext = context_system::instance();
1229         $this->setUser($this->creator);
1231         $this->setUser($this->user);
1233         assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1234         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1235         accesslib_clear_all_caches_for_unit_testing();
1237         $this->setUser($this->user);
1239         $plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1241         $result = external::complete_plan($plan->id);
1242         $this->assertTrue($result);
1243     }
1245     /**
1246      * Test reopen plan.
1247      */
1248     public function test_reopen_plan() {
1249         $syscontext = context_system::instance();
1251         $this->setUser($this->creator);
1253         $this->setUser($this->user);
1255         assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1256         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1257         accesslib_clear_all_caches_for_unit_testing();
1259         $this->setUser($this->user);
1261         $plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1262         external::complete_plan($plan->id);
1264         $result = external::reopen_plan($plan->id);
1265         $this->assertTrue($result);
1266     }
1268     /**
1269      * Test that we can read plans.
1270      */
1271     public function test_read_plans() {
1272         global $OUTPUT;
1273         $this->setUser($this->creator);
1275         $syscontext = context_system::instance();
1277         $plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1278         $plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1279         $plan3 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1280         external::complete_plan($plan3->id);
1281         $plan3 = (object) external::read_plan($plan3->id);
1283         $data = external::read_plan($plan1->id);
1284         $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1285         $data = external::read_plan($plan2->id);
1286         $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1287         $data = external::read_plan($plan3->id);
1288         $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1290         $this->setUser($this->user);
1292         // The normal user can not edit these plans.
1293         $plan1->canmanage = false;
1294         $plan2->canmanage = false;
1295         $plan3->canmanage = false;
1296         $plan1->canbeedited = false;
1297         $plan2->canbeedited = false;
1298         $plan3->canbeedited = false;
1299         $plan1->canrequestreview = true;
1300         $plan2->canrequestreview = true;
1301         $plan3->canrequestreview = true;
1302         $plan1->canreview = false;
1303         $plan2->canreview = false;
1304         $plan3->canreview = false;
1305         $plan1->iscompleteallowed = false;
1306         $plan2->iscompleteallowed = false;
1307         $plan3->iscompleteallowed = false;
1308         $plan1->isrequestreviewallowed = true;
1309         $plan2->isrequestreviewallowed = true;
1310         $plan3->isrequestreviewallowed = true;
1311         $plan1->isapproveallowed = false;
1312         $plan2->isapproveallowed = false;
1313         $plan3->isapproveallowed = false;
1314         $plan1->isunapproveallowed = false;
1315         $plan2->isunapproveallowed = false;
1316         $plan3->isunapproveallowed = false;
1317         $plan3->isreopenallowed = false;
1318         $plan1->commentarea['canpost'] = false;
1319         $plan1->commentarea['canview'] = true;
1321         // Prevent the user from seeing their own non-draft plans.
1322         assign_capability('tool/lp:plancommentown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1323         assign_capability('tool/lp:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1324         assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1325         accesslib_clear_all_caches_for_unit_testing();
1327         $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1329         try {
1330             external::read_plan($plan2->id);
1331             $this->fail('Exception expected due to not permissions to read plan');
1332         } catch (moodle_exception $e) {
1333             $this->assertEquals('nopermissions', $e->errorcode);
1334         }
1335         try {
1336             external::read_plan($plan3->id);
1337             $this->fail('Exception expected due to not permissions to read plan');
1338         } catch (moodle_exception $e) {
1339             $this->assertEquals('nopermissions', $e->errorcode);
1340         }
1342         // Allow user to see their plan.
1343         assign_capability('tool/lp:plancommentown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1344         assign_capability('tool/lp:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1345         assign_capability('tool/lp:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1346         accesslib_clear_all_caches_for_unit_testing();
1348         $plan1->commentarea['canpost'] = true;
1349         $plan1->commentarea['canview'] = true;
1350         $plan2->commentarea['canpost'] = true;
1351         $plan2->isrequestreviewallowed = false;
1352         $plan3->commentarea['canpost'] = true;
1353         $plan3->isrequestreviewallowed = false;
1354         $plan1->commentarea['canpostorhascomments'] = true;
1355         $plan2->commentarea['canpostorhascomments'] = true;
1356         $plan3->commentarea['canpostorhascomments'] = true;
1358         $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1359         $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1360         $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1362         // Allow use to manage their own draft plan.
1363         assign_capability('tool/lp:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1364         assign_capability('tool/lp:planmanageown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1365         assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1366         accesslib_clear_all_caches_for_unit_testing();
1368         $plan1->canmanage = true;
1369         $plan1->canbeedited = true;
1370         $plan1->canrequestreview = true;
1371         $plan1->isrequestreviewallowed = true;
1372         $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1373         try {
1374             external::read_plan($plan2->id);
1375             $this->fail('Exception expected due to not permissions to read plan');
1376         } catch (moodle_exception $e) {
1377             $this->assertEquals('nopermissions', $e->errorcode);
1378         }
1379         try {
1380             external::read_plan($plan3->id);
1381             $this->fail('Exception expected due to not permissions to read plan');
1382         } catch (moodle_exception $e) {
1383             $this->assertEquals('nopermissions', $e->errorcode);
1384         }
1386         // Allow use to manage their plan.
1387         assign_capability('tool/lp:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1388         assign_capability('tool/lp:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1389         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1390         accesslib_clear_all_caches_for_unit_testing();
1392         $plan1->canmanage = false;
1393         $plan1->canbeedited = false;
1394         $plan1->canrequestreview = true;
1395         $plan1->canreview = true;
1396         $plan1->isrequestreviewallowed = true;
1397         $plan1->isapproveallowed = true;
1398         $plan1->iscompleteallowed = false;
1400         $plan2->canmanage = true;
1401         $plan2->canbeedited = true;
1402         $plan2->canreview = true;
1403         $plan2->iscompleteallowed = true;
1404         $plan2->isunapproveallowed = true;
1406         $plan3->canmanage = true;
1407         $plan3->canreview = true;
1408         $plan3->isreopenallowed = true;
1410         $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1411         $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1412         $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1413     }
1415     public function test_delete_plans() {
1416         $this->setUser($this->creator);
1418         $syscontext = context_system::instance();
1420         $plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1421         $plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1422         $plan3 = $this->create_plan(3, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);
1424         $this->assertTrue(external::delete_plan($plan1->id));
1426         unassign_capability('tool/lp:planmanage', $this->creatorrole, $syscontext->id);
1427         accesslib_clear_all_caches_for_unit_testing();
1429         try {
1430             external::delete_plan($plan2->id);
1431             $this->fail('Exception expected due to not permissions to manage plans');
1432         } catch (moodle_exception $e) {
1433             $this->assertEquals('nopermissions', $e->errorcode);
1434         }
1436         $this->setUser($this->user);
1438         // Can not delete plans created by other users.
1439         try {
1440             external::delete_plan($plan2->id);
1441             $this->fail('Exception expected due to not permissions to manage plans');
1442         } catch (moodle_exception $e) {
1443             $this->assertEquals('nopermissions', $e->errorcode);
1444         }
1446         assign_capability('tool/lp:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1447         accesslib_clear_all_caches_for_unit_testing();
1449         $this->assertTrue(external::delete_plan($plan2->id));
1451         // Can not delete plans created for other users.
1452         try {
1453             external::delete_plan($plan3->id);
1454             $this->fail('Exception expected due to not permissions to manage plans');
1455         } catch (moodle_exception $e) {
1456             $this->assertEquals('nopermissions', $e->errorcode);
1457         }
1459         $plan4 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1460         $this->assertTrue(external::delete_plan($plan4->id));
1461     }
1463     public function test_delete_plan_removes_relations() {
1464         $this->setAdminUser();
1465         $dg = $this->getDataGenerator();
1466         $lpg = $dg->get_plugin_generator('tool_lp');
1468         $user = $dg->create_user();
1469         $plan = $lpg->create_plan(array('userid' => $user->id));
1470         $framework = $lpg->create_framework();
1471         $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1472         $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1473         $comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1474         $pc1 = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $comp1->get_id()));
1475         $pc2 = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $comp2->get_id()));
1476         $pc3 = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $comp3->get_id()));
1478         // Complete the plan to generate user_competency_plan entries.
1479         api::complete_plan($plan);
1481         // Confirm the data we have.
1482         $this->assertEquals(3, plan_competency::count_records(array('planid' => $plan->get_id())));
1483         $this->assertEquals(3, user_competency_plan::count_records(array('planid' => $plan->get_id(), 'userid' => $user->id)));
1485         // Delete the plan now.
1486         api::delete_plan($plan->get_id());
1487         $this->assertEquals(0, plan_competency::count_records(array('planid' => $plan->get_id())));
1488         $this->assertEquals(0, user_competency_plan::count_records(array('planid' => $plan->get_id(), 'userid' => $user->id)));
1489     }
1491     public function test_list_plan_competencies() {
1492         $this->setUser($this->creator);
1494         $dg = $this->getDataGenerator();
1495         $lpg = $dg->get_plugin_generator('tool_lp');
1497         $f1 = $lpg->create_framework();
1498         $f2 = $lpg->create_framework();
1500         $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1501         $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1502         $c1c = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1503         $c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
1504         $c2b = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
1506         $tpl = $lpg->create_template();
1507         $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1a->get_id()));
1508         $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1c->get_id()));
1509         $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2b->get_id()));
1511         $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get_id()));
1513         $uc1a = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1a->get_id(),
1514             'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $this->creator->id));
1515         $uc1b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1b->get_id()));
1516         $uc2b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2b->get_id(),
1517             'grade' => 2, 'proficiency' => 1));
1518         $ux1a = $lpg->create_user_competency(array('userid' => $this->creator->id, 'competencyid' => $c1a->get_id()));
1520         $result = external::list_plan_competencies($plan->get_id());
1521         $result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);
1523         $this->assertCount(3, $result);
1524         $this->assertEquals($c1a->get_id(), $result[0]['competency']['id']);
1525         $this->assertEquals($this->user->id, $result[0]['usercompetency']['userid']);
1526         $this->assertArrayNotHasKey('usercompetencyplan', $result[0]);
1527         $this->assertEquals($c1c->get_id(), $result[1]['competency']['id']);
1528         $this->assertEquals($this->user->id, $result[1]['usercompetency']['userid']);
1529         $this->assertArrayNotHasKey('usercompetencyplan', $result[1]);
1530         $this->assertEquals($c2b->get_id(), $result[2]['competency']['id']);
1531         $this->assertEquals($this->user->id, $result[2]['usercompetency']['userid']);
1532         $this->assertArrayNotHasKey('usercompetencyplan', $result[2]);
1533         $this->assertEquals(user_competency::STATUS_IN_REVIEW, $result[0]['usercompetency']['status']);
1534         $this->assertEquals(null, $result[1]['usercompetency']['grade']);
1535         $this->assertEquals(2, $result[2]['usercompetency']['grade']);
1536         $this->assertEquals(1, $result[2]['usercompetency']['proficiency']);
1538         // Check the return values when the plan status is complete.
1539         $completedplan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get_id(),
1540                 'status' => plan::STATUS_COMPLETE));
1542         $uc1a = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1a->get_id(),
1543                 'planid' => $completedplan->get_id()));
1544         $uc1b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1c->get_id(),
1545                 'planid' => $completedplan->get_id()));
1546         $uc2b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c2b->get_id(),
1547                 'planid' => $completedplan->get_id(), 'grade' => 2, 'proficiency' => 1));
1548         $ux1a = $lpg->create_user_competency_plan(array('userid' => $this->creator->id, 'competencyid' => $c1a->get_id(),
1549                 'planid' => $completedplan->get_id()));
1551         $result = external::list_plan_competencies($completedplan->get_id());
1552         $result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);
1554         $this->assertCount(3, $result);
1555         $this->assertEquals($c1a->get_id(), $result[0]['competency']['id']);
1556         $this->assertEquals($this->user->id, $result[0]['usercompetencyplan']['userid']);
1557         $this->assertArrayNotHasKey('usercompetency', $result[0]);
1558         $this->assertEquals($c1c->get_id(), $result[1]['competency']['id']);
1559         $this->assertEquals($this->user->id, $result[1]['usercompetencyplan']['userid']);
1560         $this->assertArrayNotHasKey('usercompetency', $result[1]);
1561         $this->assertEquals($c2b->get_id(), $result[2]['competency']['id']);
1562         $this->assertEquals($this->user->id, $result[2]['usercompetencyplan']['userid']);
1563         $this->assertArrayNotHasKey('usercompetency', $result[2]);
1564         $this->assertEquals(null, $result[1]['usercompetencyplan']['grade']);
1565         $this->assertEquals(2, $result[2]['usercompetencyplan']['grade']);
1566         $this->assertEquals(1, $result[2]['usercompetencyplan']['proficiency']);
1567     }
1569     public function test_add_competency_to_template() {
1570         $this->setUser($this->creator);
1572         $syscontext = context_system::instance();
1574         // Create a template.
1575         $template = $this->create_template(1, true);
1577         // Create a competency.
1578         $framework = $this->create_competency_framework(1, true);
1579         $competency = $this->create_competency(1, $framework->id);
1581         // Add the competency.
1582         external::add_competency_to_template($template->id, $competency->id);
1584         // Check that it was added.
1585         $this->assertEquals(1, external::count_competencies_in_template($template->id));
1587         // Unassign capability.
1588         unassign_capability('tool/lp:templatemanage', $this->creatorrole, $syscontext->id);
1589         accesslib_clear_all_caches_for_unit_testing();
1591         // Check we can not add the competency now.
1592         try {
1593             external::add_competency_to_template($template->id, $competency->id);
1594             $this->fail('Exception expected due to not permissions to manage template competencies');
1595         } catch (moodle_exception $e) {
1596             $this->assertEquals('nopermissions', $e->errorcode);
1597         }
1598     }
1600     public function test_remove_competency_from_template() {
1601         $syscontext = context_system::instance();
1602         $this->setUser($this->creator);
1603         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1605         // Create a template.
1606         $template = $this->create_template(1, true);
1608         // Create a competency.
1609         $framework = $lpg->create_framework();
1610         $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1612         // Add the competency.
1613         external::add_competency_to_template($template->id, $competency->get_id());
1615         // Check that it was added.
1616         $this->assertEquals(1, external::count_competencies_in_template($template->id));
1618         // Check that we can remove the competency.
1619         external::remove_competency_from_template($template->id, $competency->get_id());
1621         // Check that it was removed.
1622         $this->assertEquals(0, external::count_competencies_in_template($template->id));
1624         // Unassign capability.
1625         unassign_capability('tool/lp:templatemanage', $this->creatorrole, $syscontext->id);
1626         accesslib_clear_all_caches_for_unit_testing();
1628         // Check we can not remove the competency now.
1629         try {
1630             external::add_competency_to_template($template->id, $competency->get_id());
1631             $this->fail('Exception expected due to not permissions to manage template competencies');
1632         } catch (moodle_exception $e) {
1633             $this->assertEquals('nopermissions', $e->errorcode);
1634         }
1635     }
1637     /**
1638      * Test we can re-order competency frameworks.
1639      */
1640     public function test_reorder_template_competencies() {
1641         $this->setUser($this->creator);
1643         $syscontext = context_system::instance();
1644         $onehour = time() + 60 * 60;
1646         // Create a template.
1647         $template = $this->create_template(1, true);
1649         // Create a competency framework.
1650         $framework = $this->create_competency_framework(1, true);
1652         // Create multiple competencies.
1653         $competency1 = $this->create_competency(1, $framework->id);
1654         $competency2 = $this->create_competency(2, $framework->id);
1655         $competency3 = $this->create_competency(3, $framework->id);
1656         $competency4 = $this->create_competency(4, $framework->id);
1658         // Add the competencies.
1659         external::add_competency_to_template($template->id, $competency1->id);
1660         external::add_competency_to_template($template->id, $competency2->id);
1661         external::add_competency_to_template($template->id, $competency3->id);
1662         external::add_competency_to_template($template->id, $competency4->id);
1664         // Test if removing competency from template don't create sortorder holes.
1665         external::remove_competency_from_template($template->id, $competency3->id);
1666         $templcomp4 = template_competency::get_record(
1667                                 array(
1668                                     'templateid' => $template->id,
1669                                     'competencyid' => $competency4->id
1670                                 ));
1672         $this->assertEquals(2, $templcomp4->get_sortorder());
1674         // This is a move up.
1675         external::reorder_template_competency($template->id, $competency4->id, $competency2->id);
1676         $result = external::list_competencies_in_template($template->id);
1677         $result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);
1679         $r1 = (object) $result[0];
1680         $r2 = (object) $result[1];
1681         $r3 = (object) $result[2];
1683         $this->assertEquals($competency1->id, $r1->id);
1684         $this->assertEquals($competency4->id, $r2->id);
1685         $this->assertEquals($competency2->id, $r3->id);
1687         // This is a move down.
1688         external::reorder_template_competency($template->id, $competency1->id, $competency4->id);
1689         $result = external::list_competencies_in_template($template->id);
1690         $result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);
1692         $r1 = (object) $result[0];
1693         $r2 = (object) $result[1];
1694         $r3 = (object) $result[2];
1696         $this->assertEquals($competency4->id, $r1->id);
1697         $this->assertEquals($competency1->id, $r2->id);
1698         $this->assertEquals($competency2->id, $r3->id);
1700         $this->setExpectedException('required_capability_exception');
1701         $this->setUser($this->user);
1702         external::reorder_template_competency($template->id, $competency1->id, $competency2->id);
1703     }
1705     /**
1706      * Test we can duplicate learning plan template.
1707      */
1708     public function test_duplicate_learning_plan_template() {
1709         $this->setUser($this->creator);
1711         $syscontext = context_system::instance();
1712         $onehour = time() + 60 * 60;
1714         // Create a template.
1715         $template = $this->create_template(1, true);
1717         // Create a competency framework.
1718         $framework = $this->create_competency_framework(1, true);
1720         // Create multiple competencies.
1721         $competency1 = $this->create_competency(1, $framework->id);
1722         $competency2 = $this->create_competency(2, $framework->id);
1723         $competency3 = $this->create_competency(3, $framework->id);
1725         // Add the competencies.
1726         external::add_competency_to_template($template->id, $competency1->id);
1727         external::add_competency_to_template($template->id, $competency2->id);
1728         external::add_competency_to_template($template->id, $competency3->id);
1730         // Duplicate the learning plan template.
1731         $duplicatedtemplate = external::duplicate_template($template->id);
1733         $result = external::list_competencies_in_template($template->id);
1734         $resultduplicated = external::list_competencies_in_template($duplicatedtemplate->id);
1736         $this->assertEquals(count($result), count($resultduplicated));
1737         $this->assertContains($template->shortname, $duplicatedtemplate->shortname);
1738         $this->assertEquals($duplicatedtemplate->description, $template->description);
1739         $this->assertEquals($duplicatedtemplate->descriptionformat, $template->descriptionformat);
1740         $this->assertEquals($duplicatedtemplate->visible, $template->visible);
1741     }
1743     /**
1744      * Test that we can return scale values for a scale with the scale ID.
1745      */
1746     public function test_get_scale_values() {
1747         global $DB;
1748         // Create a scale.
1749         $record = new stdClass();
1750         $record->courseid = 0;
1751         $record->userid = $this->creator->id;
1752         $record->name = 'Test scale';
1753         $record->scale = 'Poor, Not good, Okay, Fine, Excellent';
1754         $record->description = '<p>Test scale description.</p>';
1755         $record->descriptionformat = 1;
1756         $record->timemodified = time();
1757         $scaleid = $DB->insert_record('scale', $record);
1758         // Expected return value.
1759         $expected = array(array(
1760                 'id' => 1,
1761                 'name' => 'Poor'
1762             ), array(
1763                 'id' => 2,
1764                 'name' => 'Not good'
1765             ), array(
1766                 'id' => 3,
1767                 'name' => 'Okay'
1768             ), array(
1769                 'id' => 4,
1770                 'name' => 'Fine'
1771             ), array(
1772                 'id' => 5,
1773                 'name' => 'Excellent'
1774             )
1775         );
1776         // Call the webservice.
1777         $result = external::get_scale_values($scaleid);
1778         $this->assertEquals($expected, $result);
1779     }
1781     /**
1782      * Create a template.
1783      */
1784     public function test_create_template() {
1785         $syscontextid = context_system::instance()->id;
1786         $catcontextid = context_coursecat::instance($this->category->id)->id;
1788         // A user without permission.
1789         $this->setUser($this->user);
1790         try {
1791             $result = $this->create_template(1, true);
1792             $this->fail('Invalid permissions');
1793         } catch (required_capability_exception $e) {
1794             // All good.
1795         }
1797         // A user without permission in a category.
1798         $this->setUser($this->catuser);
1799         try {
1800             $result = $this->create_template(1, false);
1801             $this->fail('Invalid permissions');
1802         } catch (required_capability_exception $e) {
1803             // All good.
1804         }
1806         // A user with permissions in the system.
1807         $this->setUser($this->creator);
1808         $result = $this->create_template(1, true);
1809         $this->assertEquals('shortname1', $result->shortname);
1810         $this->assertEquals($syscontextid, $result->contextid);
1811         $this->assertNotEmpty($result->id);
1813         $result = $this->create_template(2, false);
1814         $this->assertEquals('shortname2', $result->shortname);
1815         $this->assertEquals($catcontextid, $result->contextid);
1816         $this->assertNotEmpty($result->id);
1818         // A user with permissions in the category.
1819         $this->setUser($this->catcreator);
1820         try {
1821             $result = $this->create_template(3, true);
1822             $this->fail('Invalid permissions');
1823         } catch (required_capability_exception $e) {
1824             // All good.
1825         }
1827         $result = $this->create_template(3, false);
1828         $this->assertEquals('shortname3', $result->shortname);
1829         $this->assertEquals($catcontextid, $result->contextid);
1830         $this->assertNotEmpty($result->id);
1831     }
1833     /**
1834      * Read a template.
1835      */
1836     public function test_read_template() {
1837         $syscontextid = context_system::instance()->id;
1838         $catcontextid = context_coursecat::instance($this->category->id)->id;
1840         // Set a due date for the next year.
1841         $date = new DateTime('now');
1842         $date->modify('+1 year');
1843         $duedate = $date->getTimestamp();
1845         // Creating two templates.
1846         $this->setUser($this->creator);
1847         $systemplate = $this->create_template(1, true);
1848         $cattemplate = $this->create_template(2, false);
1850         // User without permissions to read in system.
1851         assign_capability('tool/lp:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
1852         accesslib_clear_all_caches_for_unit_testing();
1853         $this->setUser($this->user);
1854         $this->assertFalse(has_capability('tool/lp:templateview', context_system::instance()));
1855         try {
1856             external::read_template($systemplate->id);
1857             $this->fail('Invalid permissions');
1858         } catch (required_capability_exception $e) {
1859             // All good.
1860         }
1861         try {
1862             external::read_template($cattemplate->id);
1863             $this->fail('Invalid permissions');
1864         } catch (required_capability_exception $e) {
1865             // All good.
1866         }
1868         // User with permissions to read in a category.
1869         assign_capability('tool/lp:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
1870         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
1871         accesslib_clear_all_caches_for_unit_testing();
1872         $this->assertFalse(has_capability('tool/lp:templateview', context_system::instance()));
1873         $this->assertTrue(has_capability('tool/lp:templateview', context_coursecat::instance($this->category->id)));
1874         try {
1875             external::read_template($systemplate->id);
1876             $this->fail('Invalid permissions');
1877         } catch (required_capability_exception $e) {
1878             // All good.
1879         }
1881         $result = external::read_template($cattemplate->id);
1882         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1883         $this->assertEquals($cattemplate->id, $result['id']);
1884         $this->assertEquals('shortname2', $result['shortname']);
1885         $this->assertEquals('description2', $result['description']);
1886         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1887         $this->assertEquals(1, $result['visible']);
1888         $this->assertEquals(0, $result['duedate']);
1889         $this->assertEquals(userdate(0), $result['duedateformatted']);
1891         // User with permissions to read in the system.
1892         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
1893         accesslib_clear_all_caches_for_unit_testing();
1894         $this->assertTrue(has_capability('tool/lp:templateview', context_system::instance()));
1895         $result = external::read_template($systemplate->id);
1896         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1897         $this->assertEquals($systemplate->id, $result['id']);
1898         $this->assertEquals('shortname1', $result['shortname']);
1899         $this->assertEquals('description1', $result['description']);
1900         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1901         $this->assertEquals(true, $result['visible']);
1902         $this->assertEquals(0, $result['duedate']);
1903         $this->assertEquals(userdate(0), $result['duedateformatted']);
1905         $result = external::read_template($cattemplate->id);
1906         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1907         $this->assertEquals($cattemplate->id, $result['id']);
1908         $this->assertEquals('shortname2', $result['shortname']);
1909         $this->assertEquals('description2', $result['description']);
1910         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1911         $this->assertEquals(true, $result['visible']);
1912         $this->assertEquals(0, $result['duedate']);
1913         $this->assertEquals(userdate(0), $result['duedateformatted']);
1914     }
1916     /**
1917      * Update a template.
1918      */
1919     public function test_update_template() {
1920         $syscontextid = context_system::instance()->id;
1921         $catcontextid = context_coursecat::instance($this->category->id)->id;
1923         // Set a due date for the next year.
1924         $date = new DateTime('now');
1925         $date->modify('+1 year');
1926         $duedate = $date->getTimestamp();
1928         // Creating two templates.
1929         $this->setUser($this->creator);
1930         $systemplate = $this->create_template(1, true);
1931         $cattemplate = $this->create_template(2, false);
1933         // Trying to update in a without permissions.
1934         $this->setUser($this->user);
1935         try {
1936             $this->update_template($systemplate->id, 3);
1937             $this->fail('Invalid permissions');
1938         } catch (required_capability_exception $e) {
1939             // All good.
1940         }
1942         try {
1943             $this->update_template($cattemplate->id, 3);
1944             $this->fail('Invalid permissions');
1945         } catch (required_capability_exception $e) {
1946             // All good.
1947         }
1949         // User with permissions to update in category.
1950         $this->setUser($this->catcreator);
1951         try {
1952             $this->update_template($systemplate->id, 3);
1953             $this->fail('Invalid permissions');
1954         } catch (required_capability_exception $e) {
1955             // All good.
1956         }
1958         $result = $this->update_template($cattemplate->id, 3);
1959         $this->assertTrue($result);
1960         $result = external::read_template($cattemplate->id);
1961         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1962         $this->assertEquals($cattemplate->id, $result['id']);
1963         $this->assertEquals('shortname3', $result['shortname']);
1964         $this->assertEquals("description3", $result['description']);
1965         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1966         $this->assertEquals(true, $result['visible']);
1967         $this->assertEquals(0, $result['duedate']);
1968         $this->assertEquals(userdate(0), $result['duedateformatted']);
1970         // User with permissions to update in the system.
1971         $this->setUser($this->creator);
1972         $result = $this->update_template($systemplate->id, 4);
1973         $this->assertTrue($result);
1974         $result = external::read_template($systemplate->id);
1975         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1976         $this->assertEquals($systemplate->id, $result['id']);
1977         $this->assertEquals('shortname4', $result['shortname']);
1978         $this->assertEquals('description4', $result['description']);
1979         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1980         $this->assertEquals(true, $result['visible']);
1981         $this->assertEquals(0, $result['duedate']);
1982         $this->assertEquals(userdate(0), $result['duedateformatted']);
1984         $result = $this->update_template($cattemplate->id, 5);
1985         $this->assertTrue($result);
1986         $result = external::read_template($cattemplate->id);
1987         $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1988         $this->assertEquals($cattemplate->id, $result['id']);
1989         $this->assertEquals('shortname5', $result['shortname']);
1990         $this->assertEquals('description5', $result['description']);
1991         $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1992         $this->assertEquals(1, $result['visible']);
1993         $this->assertEquals(0, $result['duedate']);
1994         $this->assertEquals(userdate(0), $result['duedateformatted']);
1995     }
1997     /**
1998      * Delete a template.
1999      */
2000     public function test_delete_template() {
2001         global $DB;
2002         $syscontextid = context_system::instance()->id;
2003         $catcontextid = context_coursecat::instance($this->category->id)->id;
2005         // Creating a few templates.
2006         $this->setUser($this->creator);
2007         $sys1 = $this->create_template(1, true);
2008         $cat1 = $this->create_template(2, false);
2009         $cat2 = $this->create_template(3, false);
2010         $this->assertTrue($DB->record_exists('tool_lp_template', array('id' => $sys1->id)));
2011         $this->assertTrue($DB->record_exists('tool_lp_template', array('id' => $cat1->id)));
2012         $this->assertTrue($DB->record_exists('tool_lp_template', array('id' => $cat2->id)));
2014         // User without permissions.
2015         $this->setUser($this->user);
2016         try {
2017             external::delete_template($sys1->id);
2018             $this->fail('Invalid permissions');
2019         } catch (required_capability_exception $e) {
2020             // All good.
2021         }
2022         try {
2023             external::delete_template($cat1->id);
2024             $this->fail('Invalid permissions');
2025         } catch (required_capability_exception $e) {
2026             // All good.
2027         }
2029         // User with category permissions.
2030         $this->setUser($this->catcreator);
2031         try {
2032             external::delete_template($sys1->id);
2033             $this->fail('Invalid permissions');
2034         } catch (required_capability_exception $e) {
2035             // All good.
2036         }
2038         $result = external::delete_template($cat1->id);
2039         $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2040         $this->assertTrue($result);
2041         $this->assertFalse($DB->record_exists('tool_lp_template', array('id' => $cat1->id)));
2043         // User with system permissions.
2044         $this->setUser($this->creator);
2045         $result = external::delete_template($sys1->id);
2046         $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2047         $this->assertTrue($result);
2048         $result = external::delete_template($cat2->id);
2049         $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2050         $this->assertTrue($result);
2051         $this->assertFalse($DB->record_exists('tool_lp_template', array('id' => $sys1->id)));
2052         $this->assertFalse($DB->record_exists('tool_lp_template', array('id' => $cat2->id)));
2053     }
2055     /**
2056      * List templates.
2057      */
2058     public function test_list_templates() {
2059         $syscontextid = context_system::instance()->id;
2060         $catcontextid = context_coursecat::instance($this->category->id)->id;
2062         // Creating a few templates.
2063         $this->setUser($this->creator);
2064         $sys1 = $this->create_template(1, true);
2065         $sys2 = $this->create_template(2, true);
2066         $cat1 = $this->create_template(3, false);
2067         $cat2 = $this->create_template(4, false);
2069         // User without permission.
2070         $this->setUser($this->user);
2071         assign_capability('tool/lp:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
2072         accesslib_clear_all_caches_for_unit_testing();
2073         try {
2074             external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);
2075             $this->fail('Invalid permissions');
2076         } catch (required_capability_exception $e) {
2077             // All good.
2078         }
2080         // User with category permissions.
2081         assign_capability('tool/lp:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
2082         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
2083         accesslib_clear_all_caches_for_unit_testing();
2084         $result = external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);
2085         $result = external_api::clean_returnvalue(external::list_templates_returns(), $result);
2086         $this->assertCount(2, $result);
2087         $this->assertEquals($cat1->id, $result[0]['id']);
2088         $this->assertEquals($cat2->id, $result[1]['id']);
2090         // User with system permissions.
2091         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
2092         accesslib_clear_all_caches_for_unit_testing();
2093         $result = external::list_templates('id', 'DESC', 0, 3, array('contextid' => $catcontextid), 'parents', false);
2094         $result = external_api::clean_returnvalue(external::list_templates_returns(), $result);
2095         $this->assertCount(3, $result);
2096         $this->assertEquals($cat2->id, $result[0]['id']);
2097         $this->assertEquals($cat1->id, $result[1]['id']);
2098         $this->assertEquals($sys2->id, $result[2]['id']);
2099     }
2101     /**
2102      * List templates using competency.
2103      */
2104     public function test_list_templates_using_competency() {
2105         $this->setUser($this->creator);
2107         // Create a template.
2108         $template1 = $this->create_template(1, true);
2109         $template2 = $this->create_template(2, true);
2110         $template3 = $this->create_template(3, true);
2111         $template4 = $this->create_template(4, true);
2113         // Create a competency.
2114         $framework = $this->create_competency_framework(1, true);
2115         $competency1 = $this->create_competency(1, $framework->id);
2116         $competency2 = $this->create_competency(2, $framework->id);
2118         // Add the competency.
2119         external::add_competency_to_template($template1->id, $competency1->id);
2120         external::add_competency_to_template($template2->id, $competency1->id);
2121         external::add_competency_to_template($template3->id, $competency1->id);
2123         external::add_competency_to_template($template4->id, $competency2->id);
2125         $listcomp1 = external::list_templates_using_competency($competency1->id);
2126         $listcomp2 = external::list_templates_using_competency($competency2->id);
2128         // Test count_templates_using_competency.
2129         $counttempcomp1 = external::count_templates_using_competency($competency1->id);
2130         $counttempcomp2 = external::count_templates_using_competency($competency2->id);
2132         $comptemp1 = $listcomp1[0];
2133         $comptemp2 = $listcomp1[1];
2134         $comptemp3 = $listcomp1[2];
2136         $comptemp4 = $listcomp2[0];
2138         $this->assertCount(3, $listcomp1);
2139         $this->assertCount(1, $listcomp2);
2140         $this->assertEquals(3, $counttempcomp1);
2141         $this->assertEquals(1, $counttempcomp2);
2142         $this->assertEquals($template1->id, $comptemp1->id);
2143         $this->assertEquals($template2->id, $comptemp2->id);
2144         $this->assertEquals($template3->id, $comptemp3->id);
2145         $this->assertEquals($template4->id, $comptemp4->id);
2146     }
2148     public function test_count_templates() {
2149         $syscontextid = context_system::instance()->id;
2150         $catcontextid = context_coursecat::instance($this->category->id)->id;
2152         // Creating a few templates.
2153         $this->setUser($this->creator);
2154         $sys1 = $this->create_template(1, true);
2155         $sys2 = $this->create_template(2, true);
2156         $cat1 = $this->create_template(3, false);
2157         $cat2 = $this->create_template(4, false);
2158         $cat3 = $this->create_template(5, false);
2160         // User without permission.
2161         $this->setUser($this->user);
2162         assign_capability('tool/lp:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
2163         accesslib_clear_all_caches_for_unit_testing();
2164         try {
2165             external::count_templates(array('contextid' => $syscontextid), 'children');
2166             $this->fail('Invalid permissions');
2167         } catch (required_capability_exception $e) {
2168             // All good.
2169         }
2171         // User with category permissions.
2172         assign_capability('tool/lp:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
2173         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
2174         accesslib_clear_all_caches_for_unit_testing();
2175         $result = external::count_templates(array('contextid' => $syscontextid), 'children');
2176         $result = external_api::clean_returnvalue(external::count_templates_returns(), $result);
2177         $this->assertEquals(3, $result);
2179         // User with system permissions.
2180         assign_capability('tool/lp:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
2181         accesslib_clear_all_caches_for_unit_testing();
2182         $result = external::count_templates(array('contextid' => $catcontextid), 'parents');
2183         $result = external_api::clean_returnvalue(external::count_templates_returns(), $result);
2184         $this->assertEquals(5, $result);
2185     }
2187     /**
2188      * Test that we can add related competencies.
2189      *
2190      * @return void
2191      */
2192     public function test_add_related_competency() {
2193         global $DB;
2194         $this->setUser($this->creator);
2196         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2197         $framework = $lpg->create_framework();
2198         $framework2 = $lpg->create_framework();
2199         $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2200         $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2201         $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2202         $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework2->get_id()));
2204         // The lower one always as competencyid.
2205         $result = external::add_related_competency($competency1->get_id(), $competency2->get_id());
2206         $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2207         $this->assertTrue($result);
2208         $this->assertTrue($DB->record_exists_select(
2209             related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2210             array(
2211                 'cid' => $competency1->get_id(),
2212                 'rid' => $competency2->get_id()
2213             )
2214         ));
2215         $this->assertFalse($DB->record_exists_select(
2216             related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2217             array(
2218                 'cid' => $competency2->get_id(),
2219                 'rid' => $competency1->get_id()
2220             )
2221         ));
2223         $result = external::add_related_competency($competency3->get_id(), $competency1->get_id());
2224         $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2225         $this->assertTrue($result);
2226         $this->assertTrue($DB->record_exists_select(
2227             related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2228             array(
2229                 'cid' => $competency1->get_id(),
2230                 'rid' => $competency3->get_id()
2231             )
2232         ));
2233         $this->assertFalse($DB->record_exists_select(
2234             related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2235             array(
2236                 'cid' => $competency3->get_id(),
2237                 'rid' => $competency1->get_id()
2238             )
2239         ));
2241         // We can not allow a duplicate relation, not even in the other direction.
2242         $this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,
2243             'competencyid = :cid AND relatedcompetencyid = :rid',
2244             array('cid' => $competency1->get_id(), 'rid' => $competency2->get_id())));
2245         $this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,
2246             'competencyid = :cid AND relatedcompetencyid = :rid',
2247             array('rid' => $competency1->get_id(), 'cid' => $competency2->get_id())));
2248         $result = external::add_related_competency($competency2->get_id(), $competency1->get_id());
2249         $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2250         $this->assertTrue($result);
2251         $this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,
2252             'competencyid = :cid AND relatedcompetencyid = :rid',
2253             array('cid' => $competency1->get_id(), 'rid' => $competency2->get_id())));
2254         $this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,
2255             'competencyid = :cid AND relatedcompetencyid = :rid',
2256             array('rid' => $competency1->get_id(), 'cid' => $competency2->get_id())));
2258         // Check that we cannot create links across frameworks.
2259         try {
2260             external::add_related_competency($competency1->get_id(), $competency4->get_id());
2261             $this->fail('Exception expected due mis-use of shared competencies');
2262         } catch (tool_lp\invalid_persistent_exception $e) {
2263             // Yay!
2264         }
2266         // User without permission.
2267         $this->setUser($this->user);
2269         // Check we can not add the related competency now.
2270         try {
2271             external::add_related_competency($competency1->get_id(), $competency3->get_id());
2272             $this->fail('Exception expected due to not permissions to manage template competencies');
2273         } catch (moodle_exception $e) {
2274             $this->assertEquals('nopermissions', $e->errorcode);
2275         }
2277     }
2279     /**
2280      * Test that we can remove related competencies.
2281      *
2282      * @return void
2283      */
2284     public function test_remove_related_competency() {
2285         $this->setUser($this->creator);
2287         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2288         $framework = $lpg->create_framework();
2289         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2290         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2291         $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2292         $rc1 = $lpg->create_related_competency(array('competencyid' => $c1->get_id(), 'relatedcompetencyid' => $c2->get_id()));
2293         $rc2 = $lpg->create_related_competency(array('competencyid' => $c2->get_id(), 'relatedcompetencyid' => $c3->get_id()));
2295         $this->assertEquals(2, related_competency::count_records());
2297         // Returns false when the relation does not exist.
2298         $result = external::remove_related_competency($c1->get_id(), $c3->get_id());
2299         $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2300         $this->assertFalse($result);
2302         // Returns true on success.
2303         $result = external::remove_related_competency($c2->get_id(), $c3->get_id());
2304         $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2305         $this->assertTrue($result);
2306         $this->assertEquals(1, related_competency::count_records());
2308         // We don't need to specify competencyid and relatedcompetencyid in the right order.
2309         $result = external::remove_related_competency($c2->get_id(), $c1->get_id());
2310         $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2311         $this->assertTrue($result);
2312         $this->assertEquals(0, related_competency::count_records());
2313     }
2315     /**
2316      * Test that we can search and include related competencies.
2317      *
2318      * @return void
2319      */
2320     public function test_search_competencies_including_related() {
2321         $this->setUser($this->creator);
2323         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2324         $framework = $lpg->create_framework();
2325         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2326         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2327         $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2328         $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2329         $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2331         // We have 1-2, 1-3, 2-4, and no relation between 2-3 nor 1-4 nor 5.
2332         $rc12 = $lpg->create_related_competency(array('competencyid' => $c1->get_id(), 'relatedcompetencyid' => $c2->get_id()));
2333         $rc13 = $lpg->create_related_competency(array('competencyid' => $c1->get_id(), 'relatedcompetencyid' => $c3->get_id()));
2334         $rc24 = $lpg->create_related_competency(array('competencyid' => $c2->get_id(), 'relatedcompetencyid' => $c4->get_id()));
2336         $result = external::search_competencies('comp', $framework->get_id(), true);
2337         $result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);
2339         $this->assertCount(5, $result);
2341     }
2343     /**
2344      * Test that we can add competency to plan if we have the right capability.
2345      *
2346      * @return void
2347      */
2348     public function test_add_competency_to_plan() {
2349         $this->resetAfterTest(true);
2350         $dg = $this->getDataGenerator();
2351         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2352         $usermanage = $dg->create_user();
2353         $user = $dg->create_user();
2355         $syscontext = context_system::instance();
2357         // Creating specific roles.
2358         $managerole = $dg->create_role(array(
2359             'name' => 'User manage',
2360             'shortname' => 'manage'
2361         ));
2363         assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2364         assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
2366         $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2368         $this->setUser($usermanage);
2369         $plan = array (
2370             'userid' => $usermanage->id,
2371             'status' => \tool_lp\plan::STATUS_ACTIVE
2372         );
2373         $pl1 = $lpg->create_plan($plan);
2374         $framework = $lpg->create_framework();
2375         $competency = $lpg->create_competency(
2376                 array('competencyframeworkid' => $framework->get_id())
2377                 );
2378         $this->assertTrue(external::add_competency_to_plan($pl1->get_id(), $competency->get_id()));
2380         // A competency cannot be added to plan based on template.
2381         $template = $lpg->create_template();
2382         $plan = array (
2383             'userid' => $usermanage->id,
2384             'status' => \tool_lp\plan::STATUS_ACTIVE,
2385             'templateid' => $template->get_id()
2386         );
2387         $pl2 = $lpg->create_plan($plan);
2388         try {
2389             external::add_competency_to_plan($pl2->get_id(), $competency->get_id());
2390             $this->fail('A competency cannot be added to plan based on template');
2391         } catch (coding_exception $ex) {
2392             $this->assertTrue(true);
2393         }
2395         // User without capability cannot add competency to a plan.
2396         $this->setUser($user);
2397         try {
2398             external::add_competency_to_plan($pl1->get_id(), $competency->get_id());
2399             $this->fail('User without capability cannot add competency to a plan');
2400         } catch (required_capability_exception $ex) {
2401             $this->assertTrue(true);
2402         }
2403     }
2405     /**
2406      * Test that we can add competency to plan if we have the right capability.
2407      *
2408      * @return void
2409      */
2410     public function test_remove_competency_from_plan() {
2411         $this->resetAfterTest(true);
2412         $dg = $this->getDataGenerator();
2413         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2414         $usermanage = $dg->create_user();
2415         $user = $dg->create_user();
2417         $syscontext = context_system::instance();
2419         // Creating specific roles.
2420         $managerole = $dg->create_role(array(
2421             'name' => 'User manage',
2422             'shortname' => 'manage'
2423         ));
2425         assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2426         assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
2428         $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2430         $this->setUser($usermanage);
2431         $plan = array (
2432             'userid' => $usermanage->id,
2433             'status' => \tool_lp\plan::STATUS_ACTIVE
2434         );
2435         $pl1 = $lpg->create_plan($plan);
2436         $framework = $lpg->create_framework();
2437         $competency = $lpg->create_competency(
2438                 array('competencyframeworkid' => $framework->get_id())
2439                 );
2440         $lpg->create_plan_competency(
2441                 array(
2442                     'planid' => $pl1->get_id(),
2443                     'competencyid' => $competency->get_id()
2444                     )
2445                 );
2446         $this->assertTrue(external::remove_competency_from_plan($pl1->get_id(), $competency->get_id()));
2447         $this->assertCount(0, $pl1->get_competencies());
2448     }
2450     /**
2451      * Test that we can add competency to plan if we have the right capability.
2452      *
2453      * @return void
2454      */
2455     public function test_reorder_plan_competency() {
2456         $this->resetAfterTest(true);
2457         $dg = $this->getDataGenerator();
2458         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2459         $usermanage = $dg->create_user();
2460         $user = $dg->create_user();
2462         $syscontext = context_system::instance();
2464         // Creating specific roles.
2465         $managerole = $dg->create_role(array(
2466             'name' => 'User manage',
2467             'shortname' => 'manage'
2468         ));
2470         assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2471         assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
2473         $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2475         $this->setUser($usermanage);
2476         $plan = array (
2477             'userid' => $usermanage->id,
2478             'status' => \tool_lp\plan::STATUS_ACTIVE
2479         );
2480         $pl1 = $lpg->create_plan($plan);
2481         $framework = $lpg->create_framework();
2482         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2483         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2484         $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2485         $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2486         $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2488         $lpg->create_plan_competency(array('planid' => $pl1->get_id(), 'competencyid' => $c1->get_id(), 'sortorder' => 1));
2489         $lpg->create_plan_competency(array('planid' => $pl1->get_id(), 'competencyid' => $c2->get_id(), 'sortorder' => 2));
2490         $lpg->create_plan_competency(array('planid' => $pl1->get_id(), 'competencyid' => $c3->get_id(), 'sortorder' => 3));
2491         $lpg->create_plan_competency(array('planid' => $pl1->get_id(), 'competencyid' => $c4->get_id(), 'sortorder' => 4));
2492         $lpg->create_plan_competency(array('planid' => $pl1->get_id(), 'competencyid' => $c5->get_id(), 'sortorder' => 5));
2494         // Test if removing competency from plan don't create sortorder holes.
2495         external::remove_competency_from_plan($pl1->get_id(), $c4->get_id());
2496         $plancomp5 = plan_competency::get_record(
2497                                 array(
2498                                     'planid' => $pl1->get_id(),
2499                                     'competencyid' => $c5->get_id()
2500                                 ));
2502         $this->assertEquals(3, $plancomp5->get_sortorder());
2504         $this->assertTrue(external::reorder_plan_competency($pl1->get_id(), $c2->get_id(), $c5->get_id()));
2505         $this->assertTrue(external::reorder_plan_competency($pl1->get_id(), $c3->get_id(), $c1->get_id()));
2506         $plancompetencies = plan_competency::get_records(
2507                 array(
2508                     'planid' => $pl1->get_id()
2509                 ),
2510                 'sortorder',
2511                 'ASC'
2512                 );
2513         $plcmp1 = $plancompetencies[0];
2514         $plcmp2 = $plancompetencies[1];
2515         $plcmp3 = $plancompetencies[2];
2516         $plcmp4 = $plancompetencies[3];
2518         $this->assertEquals($plcmp1->get_competencyid(), $c3->get_id());
2519         $this->assertEquals($plcmp2->get_competencyid(), $c1->get_id());
2520         $this->assertEquals($plcmp3->get_competencyid(), $c5->get_id());
2521         $this->assertEquals($plcmp4->get_competencyid(), $c2->get_id());
2522     }
2524     /**
2525      * Test resolving sortorder when we creating competency.
2526      */
2527     public function test_fix_sortorder_when_creating_competency() {
2528         $this->resetAfterTest(true);
2529         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2530         $framework = $lpg->create_framework();
2532         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2533         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'sortorder' => 20));
2534         $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'sortorder' => 1));
2536         $this->assertEquals(0, $c1->get_sortorder());
2537         $this->assertEquals(1, $c2->get_sortorder());
2538         $this->assertEquals(2, $c3->get_sortorder());
2539     }
2541     /**
2542      * Test resolving sortorder when we delete competency.
2543      */
2544     public function test_fix_sortorder_when_delete_competency() {
2545         $this->resetAfterTest(true);
2546         $this->setUser($this->creator);
2547         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2549         $framework = $lpg->create_framework();
2551         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2552         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2553         $c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2554         $c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2555         $c2c = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2556         $c2d = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2558         $this->assertEquals(0, $c1->get_sortorder());
2559         $this->assertEquals(1, $c2->get_sortorder());
2560         $this->assertEquals(0, $c2a->get_sortorder());
2561         $this->assertEquals(1, $c2b->get_sortorder());
2562         $this->assertEquals(2, $c2c->get_sortorder());
2563         $this->assertEquals(3, $c2d->get_sortorder());
2565         $result = external::delete_competency($c1->get_id());
2566         $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
2568         $c2->read();
2569         $c2a->read();
2570         $c2b->read();
2571         $c2c->read();
2572         $c2d->read();
2574         $this->assertEquals(0, $c2->get_sortorder());
2575         $this->assertEquals(0, $c2a->get_sortorder());
2576         $this->assertEquals(1, $c2b->get_sortorder());
2577         $this->assertEquals(2, $c2c->get_sortorder());
2578         $this->assertEquals(3, $c2d->get_sortorder());
2580         $result = external::delete_competency($c2b->get_id());
2581         $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
2583         $c2->read();
2584         $c2a->read();
2585         $c2c->read();
2586         $c2d->read();
2588         $this->assertEquals(0, $c2->get_sortorder());
2589         $this->assertEquals(0, $c2a->get_sortorder());
2590         $this->assertEquals(1, $c2c->get_sortorder());
2591         $this->assertEquals(2, $c2d->get_sortorder());
2592     }
2594     /**
2595      * Test resolving sortorder when moving a competency.
2596      */
2597     public function test_fix_sortorder_when_moving_competency() {
2598         $this->resetAfterTest(true);
2599         $this->setUser($this->creator);
2600         $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2602         $framework = $lpg->create_framework();
2604         $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2605         $c1a = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
2606         $c1b = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
2607         $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2608         $c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2609         $c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c2->get_id()));
2611         $this->assertEquals(0, $c1->get_sortorder());
2612         $this->assertEquals(0, $c1a->get_sortorder());
2613         $this->assertEquals(1, $c1b->get_sortorder());
2614         $this->assertEquals(1, $c2->get_sortorder());
2615         $this->assertEquals(0, $c2a->get_sortorder());
2616         $this->assertEquals(1, $c2b->get_sortorder());
2618         $result = external::set_parent_competency($c2a->get_id(), $c1->get_id());
2619         $result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);
2621         $c1->read();
2622         $c1a->read();
2623         $c1b->read();
2624         $c2->read();
2625         $c2a->read();
2626         $c2b->read();
2628         $this->assertEquals(0, $c1->get_sortorder());
2629         $this->assertEquals(0, $c1a->get_sortorder());
2630         $this->assertEquals(1, $c1b->get_sortorder());
2631         $this->assertEquals(2, $c2a->get_sortorder());
2632         $this->assertEquals(1, $c2->get_sortorder());
2633         $this->assertEquals(0, $c2b->get_sortorder());
2635         // Move a root node.
2636         $result = external::set_parent_competency($c2->get_id(), $c1b->get_id());
2637         $result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);
2639         $c1->read();
2640         $c1a->read();
2641         $c1b->read();
2642         $c2->read();
2643         $c2a->read();
2644         $c2b->read();
2646         $this->assertEquals(0, $c1->get_sortorder());
2647         $this->assertEquals(0, $c1a->get_sortorder());
2648         $this->assertEquals(1, $c1b->get_sortorder());
2649         $this->assertEquals(0, $c2->get_sortorder());
2650         $this->assertEquals(0, $c2b->get_sortorder());
2651         $this->assertEquals(2, $c2a->get_sortorder());
2652     }
2654     public function test_search_users_by_capability() {
2655         global $CFG;
2656         $this->resetAfterTest(true);
2658         $dg = $this->getDataGenerator();
2659         $ux = $dg->create_user();
2660         $u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
2661             'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
2662             'institution' => 'HQ'));
2664         // First we search with no capability assigned.
2665         $this->setUser($ux);
2666         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2667         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2668         $this->assertCount(0, $result['users']);
2669         $this->assertEquals(0, $result['count']);
2671         // Now we assign a different capability.
2672         $usercontext = context_user::instance($u1->id);
2673         $systemcontext = context_system::instance();
2674         $customrole = $this->assignUserCapability('tool/lp:planview', $usercontext->id);
2676         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2677         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2678         $this->assertCount(0, $result['users']);
2679         $this->assertEquals(0, $result['count']);
2681         // Now we assign a matching capability in the same role.
2682         $usercontext = context_user::instance($u1->id);
2683         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $customrole);
2685         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2686         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2687         $this->assertCount(1, $result['users']);
2688         $this->assertEquals(1, $result['count']);
2690         // Now assign another role with the same capability (test duplicates).
2691         role_assign($this->creatorrole, $ux->id, $usercontext->id);
2692         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2693         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2694         $this->assertCount(1, $result['users']);
2695         $this->assertEquals(1, $result['count']);
2697         // Now lets try a different user with only the role at system level.
2698         $ux2 = $dg->create_user();
2699         role_assign($this->creatorrole, $ux2->id, $systemcontext->id);
2700         $this->setUser($ux2);
2701         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2702         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2703         $this->assertCount(1, $result['users']);
2704         $this->assertEquals(1, $result['count']);
2706         // Now lets try a different user with only the role at user level.
2707         $ux3 = $dg->create_user();
2708         role_assign($this->creatorrole, $ux3->id, $usercontext->id);
2709         $this->setUser($ux3);
2710         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2711         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2712         $this->assertCount(1, $result['users']);
2713         $this->assertEquals(1, $result['count']);
2715         // Switch back.
2716         $this->setUser($ux);
2718         // Now add a prevent override (will change nothing because we still have an ALLOW).
2719         assign_capability('tool/lp:planmanage', CAP_PREVENT, $customrole, $usercontext->id);
2720         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2721         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2722         $this->assertCount(1, $result['users']);
2723         $this->assertEquals(1, $result['count']);
2725         // Now change to a prohibit override (should prevent access).
2726         assign_capability('tool/lp:planmanage', CAP_PROHIBIT, $customrole, $usercontext->id);
2727         $result = external::search_users('yyylan', 'tool/lp:planmanage');
2728         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2729         $this->assertCount(1, $result['users']);
2730         $this->assertEquals(1, $result['count']);
2732     }
2734     /**
2735      * Ensures that overrides, as well as system permissions, are respected.
2736      */
2737     public function test_search_users_by_capability_the_comeback() {
2738         $this->resetAfterTest();
2739         $dg = $this->getDataGenerator();
2741         $master = $dg->create_user();
2742         $manager = $dg->create_user();
2743         $slave1 = $dg->create_user(array('lastname' => 'MOODLER'));
2744         $slave2 = $dg->create_user(array('lastname' => 'MOODLER'));
2745         $slave3 = $dg->create_user(array('lastname' => 'MOODLER'));
2747         $syscontext = context_system::instance();
2748         $slave1context = context_user::instance($slave1->id);
2749         $slave2context = context_user::instance($slave2->id);
2750         $slave3context = context_user::instance($slave3->id);
2752         // Creating a role giving the site config.
2753         $roleid = $dg->create_role();
2754         assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext->id, true);
2756         // Create a role override for slave 2.
2757         assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $slave2context->id, true);
2759         // Assigning the role.
2760         // Master -> System context.
2761         // Manager -> User context.
2762         role_assign($roleid, $master->id, $syscontext);
2763         role_assign($roleid, $manager->id, $slave1context);
2765         // Flush accesslib.
2766         accesslib_clear_all_caches_for_unit_testing();
2768         // Confirm.
2769         // Master has system permissions.
2770         $this->setUser($master);
2771         $this->assertTrue(has_capability('moodle/site:config', $syscontext));
2772         $this->assertTrue(has_capability('moodle/site:config', $slave1context));
2773         $this->assertFalse(has_capability('moodle/site:config', $slave2context));
2774         $this->assertTrue(has_capability('moodle/site:config', $slave3context));
2776         // Manager only has permissions in slave 1.
2777         $this->setUser($manager);
2778         $this->assertFalse(has_capability('moodle/site:config', $syscontext));
2779         $this->assertTrue(has_capability('moodle/site:config', $slave1context));
2780         $this->assertFalse(has_capability('moodle/site:config', $slave2context));
2781         $this->assertFalse(has_capability('moodle/site:config', $slave3context));
2783         // Now do the test.
2784         $this->setUser($master);
2785         $result = external::search_users('MOODLER', 'moodle/site:config');
2786         $this->assertCount(2, $result['users']);
2787         $this->assertEquals(2, $result['count']);
2788         $this->assertArrayHasKey($slave1->id, $result['users']);
2789         $this->assertArrayHasKey($slave3->id, $result['users']);
2791         $this->setUser($manager);
2792         $result = external::search_users('MOODLER', 'moodle/site:config');
2793         $this->assertCount(1, $result['users']);
2794         $this->assertEquals(1, $result['count']);
2795         $this->assertArrayHasKey($slave1->id, $result['users']);
2796     }
2798     public function test_search_users() {
2799         global $CFG;
2800         $this->resetAfterTest(true);
2802         $dg = $this->getDataGenerator();
2803         $ux = $dg->create_user();
2804         $u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
2805             'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
2806             'institution' => 'HQ'));
2807         $u2 = $dg->create_user(array('idnumber' => 'Dogs', 'firstname' => 'Alice', 'lastname' => 'Dyyylan',
2808             'email' => 'alyyyson@dyyylan.com', 'phone1' => '33333', 'phone2' => '77777', 'department' => 'Development',
2809             'institution' => 'O2'));
2810         $u3 = $dg->create_user(array('idnumber' => 'Fish', 'firstname' => 'Thomas', 'lastname' => 'Xow',
2811             'email' => 'fishyyy@moodle.com', 'phone1' => '77777', 'phone2' => '33333', 'department' => 'Research',
2812             'institution' => 'Bob'));
2814         // We need to give the user the capability we are searching for on each of the test users.
2815         $this->setAdminUser();
2816         $usercontext = context_user::instance($u1->id);
2817         $dummyrole = $this->assignUserCapability('tool/lp:planmanage', $usercontext->id);
2818         $usercontext = context_user::instance($u2->id);
2819         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $dummyrole);
2820         $usercontext = context_user::instance($u3->id);
2821         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $dummyrole);
2823         $this->setUser($ux);
2824         $usercontext = context_user::instance($u1->id);
2825         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $dummyrole);
2826         $usercontext = context_user::instance($u2->id);
2827         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $dummyrole);
2828         $usercontext = context_user::instance($u3->id);
2829         $this->assignUserCapability('tool/lp:planmanage', $usercontext->id, $dummyrole);
2831         $this->setAdminUser();
2833         // No identity fields.
2834         $CFG->showuseridentity = '';
2835         $result = external::search_users('cats', 'tool/lp:planmanage');
2836         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2837         $this->assertCount(0, $result['users']);
2838         $this->assertEquals(0, $result['count']);
2840         // Filter by name.
2841         $CFG->showuseridentity = '';
2842         $result = external::search_users('dyyylan', 'tool/lp:planmanage');
2843         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2844         $this->assertCount(2, $result['users']);
2845         $this->assertEquals(2, $result['count']);
2846         $this->assertEquals($u2->id, $result['users'][0]['id']);
2847         $this->assertEquals($u1->id, $result['users'][1]['id']);
2849         // Filter by institution and name.
2850         $CFG->showuseridentity = 'institution';
2851         $result = external::search_users('bob', 'tool/lp:planmanage');
2852         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2853         $this->assertCount(2, $result['users']);
2854         $this->assertEquals(2, $result['count']);
2855         $this->assertEquals($u1->id, $result['users'][0]['id']);
2856         $this->assertEquals($u3->id, $result['users'][1]['id']);
2858         // Filter by id number.
2859         $CFG->showuseridentity = 'idnumber';
2860         $result = external::search_users('cats', 'tool/lp:planmanage');
2861         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2862         $this->assertCount(1, $result['users']);
2863         $this->assertEquals(1, $result['count']);
2864         $this->assertEquals($u1->id, $result['users'][0]['id']);
2865         $this->assertEquals($u1->idnumber, $result['users'][0]['idnumber']);
2866         $this->assertEmpty($result['users'][0]['email']);
2867         $this->assertEmpty($result['users'][0]['phone1']);
2868         $this->assertEmpty($result['users'][0]['phone2']);
2869         $this->assertEmpty($result['users'][0]['department']);
2870         $this->assertEmpty($result['users'][0]['institution']);
2872         // Filter by email.
2873         $CFG->showuseridentity = 'email';
2874         $result = external::search_users('yyy', 'tool/lp:planmanage');
2875         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2876         $this->assertCount(3, $result['users']);
2877         $this->assertEquals(3, $result['count']);
2878         $this->assertEquals($u2->id, $result['users'][0]['id']);
2879         $this->assertEquals($u2->email, $result['users'][0]['email']);
2880         $this->assertEquals($u1->id, $result['users'][1]['id']);
2881         $this->assertEquals($u1->email, $result['users'][1]['email']);
2882         $this->assertEquals($u3->id, $result['users'][2]['id']);
2883         $this->assertEquals($u3->email, $result['users'][2]['email']);
2885         // Filter by any.
2886         $CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
2887         $result = external::search_users('yyy', 'tool/lp:planmanage');
2888         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2889         $this->assertCount(3, $result['users']);
2890         $this->assertEquals(3, $result['count']);
2891         $this->assertArrayHasKey('idnumber', $result['users'][0]);
2892         $this->assertArrayHasKey('email', $result['users'][0]);
2893         $this->assertArrayHasKey('phone1', $result['users'][0]);
2894         $this->assertArrayHasKey('phone2', $result['users'][0]);
2895         $this->assertArrayHasKey('department', $result['users'][0]);
2896         $this->assertArrayHasKey('institution', $result['users'][0]);
2898         // Switch to a user that cannot view identity fields.
2899         $this->setUser($ux);
2900         $CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
2902         // Only names are included.
2903         $result = external::search_users('fish');
2904         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2905         $this->assertCount(0, $result['users']);
2906         $this->assertEquals(0, $result['count']);
2908         $result = external::search_users('bob', 'tool/lp:planmanage');
2909         $result = external_api::clean_returnvalue(external::search_users_returns(), $result);
2910         $this->assertCount(1, $result['users']);
2911         $this->assertEquals(1, $result['count']);
2912         $this->assertEquals($u1->id, $result['users'][0]['id']);
2913         $this->assertEmpty($result['users'][0]['idnumber']);
2914         $this->assertEmpty($result['users'][0]['email']);
2915         $this->assertEmpty($result['users'][0]['phone1']);
2916         $this->assertEmpty($result['users'][0]['phone2']);
2917         $this->assertEmpty($result['users'][0]['department']);
2918         $this->assertEmpty($result['users'][0]['institution']);
2919     }
2921     public function test_grade_competency_in_plan() {
2922         global $CFG;
2924         $this->setUser($this->creator);
2926         $dg = $this->getDataGenerator();
2927         $lpg = $dg->get_plugin_generator('tool_lp');
2929         $f1 = $lpg->create_framework();
2931         $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2933         $tpl = $lpg->create_template();
2934         $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id()));
2936         $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get_id(), 'name' => 'Evil'));
2938         $uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get_id()));
2940         $evidence = external::grade_competency_in_plan($plan->get_id(), $c1->get_id(), 1, 'Evil note');
2942         $this->assertEquals('The competency grade was manually set in the plan \'Evil\'.', $evidence->description);
2943         $this->assertEquals('A', $evidence->gradename);
2944         $this->assertEquals('Evil note', $evidence->note);
2946         $this->setUser($this->user);
2948         $this->setExpectedException('required_capability_exception');
2949         $evidence = external::grade_competency_in_plan($plan->get_id(), $c1->get_id(), 1);
2950     }
2952     public function test_data_for_user_competency_summary_in_plan() {
2953         global $CFG;
2955         $this->setUser($this->creator);
2957         $dg = $this->getDataGenerator();
2958         $lpg = $dg->get_plugin_generator('tool_lp');
2960         $f1 = $lpg->create_framework();
2962         $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2964         $tpl = $lpg->create_template();
2965         $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id()));
2967         $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get_id(), 'name' => 'Evil'));
2969         $uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get_id()));
2971         $evidence = external::grade_competency_in_plan($plan->get_id(), $c1->get_id(), 1, true);
2972         $evidence = external::grade_competency_in_plan($plan->get_id(), $c1->get_id(), 2, true);
2974         $summary = external::data_for_user_competency_summary_in_plan($c1->get_id(), $plan->get_id());
2975         $this->assertTrue($summary->usercompetencysummary->cangrade);
2976         $this->assertEquals('Evil', $summary->plan->name);
2977         $this->assertEquals('B', $summary->usercompetencysummary->usercompetency->gradename);
2978         $this->assertEquals('B', $summary->usercompetencysummary->evidence[0]->gradename);
2979         $this->assertEquals('A', $summary->usercompetencysummary->evidence[1]->gradename);
2980     }
2982     /**
2983      * Search cohorts.
2984      */
2985     public function test_search_cohorts() {
2986         $this->resetAfterTest(true);
2988         $syscontext = array('contextid' => context_system::instance()->id);
2989         $catcontext = array('contextid' => context_coursecat::instance($this->category->id)->id);
2990         $othercatcontext = array('contextid' => context_coursecat::instance($this->othercategory->id)->id);
2992         $cohort1 = $this->getDataGenerator()->create_cohort(array_merge($syscontext, array('name' => 'Cohortsearch 1')));
2993         $cohort2 = $this->getDataGenerator()->create_cohort(array_merge($catcontext, array('name' => 'Cohortsearch 2')));
2994         $cohort3 = $this->getDataGenerator()->create_cohort(array_merge($othercatcontext, array('name' => 'Cohortsearch 3')));
2996         // Check for parameter $includes = 'parents'.
2998         // A user without permission in the system.
2999         $this->setUser($this->user);
3000         try {
3001             $result = external::search_cohorts("Cohortsearch", $syscontext, 'parents');
3002             $this->fail('Invalid permissions in system');
3003         } catch (required_capability_exception $e) {
3004             // All good.
3005         }
3007         // A user without permission in a category.
3008         $this->setUser($this->catuser);
3009         try {
3010             $result = external::search_cohorts("Cohortsearch", $catcontext, 'parents');
3011             $this->fail('Invalid permissions in category');
3012         } catch (required_capability_exception $e) {
3013             // All good.
3014         }
3016         // A user with permissions in the system.
3017         $this->setUser($this->creator);
3018         $result = external::search_cohorts("Cohortsearch", $syscontext, 'parents');
3019         $this->assertEquals(1, count($result['cohorts']));
3020         $this->assertEquals('Cohortsearch 1', $result['cohorts'][$cohort1->id]->name);
3022         // A user with permissions in the category.
3023         $this->setUser($this->catcreator);
3024         $result = external::search_cohorts("Cohortsearch", $catcontext, 'parents');
3025         $this->assertEquals(2, count($result['cohorts']));
3026         $cohorts = array();
3027         foreach ($result['cohorts'] as $cohort) {
3028             $cohorts[] = $cohort->name;
3029         }
3030         $this->assertTrue(in_array('Cohortsearch 1', $cohorts));
3031         $this->assertTrue(in_array('Cohortsearch 2', $cohorts));
3033         // Check for parameter $includes = 'self'.
3034         $this->setUser($this->creator);
3035         $result = external::search_cohorts("Cohortsearch", $othercatcontext, 'self');
3036         $this->assertEquals(1, count($result['cohorts']));
3037         $this->assertEquals('Cohortsearch 3', $result['cohorts'][$cohort3->id]->name);
3039         // Check for parameter $includes = 'all'.
3040         $this->setUser($this->creator);
3041         $result = external::search_cohorts("Cohortsearch", $syscontext, 'all');
3042         $this->assertEquals(3, count($result['cohorts']));
3044         // Detect invalid parameter $includes.
3045         $this->setUser($this->creator);
3046         try {
3047             $result = external::search_cohorts("Cohortsearch", $syscontext, 'invalid');
3048             $this->fail('Invalid parameter includes');
3049         } catch (coding_exception $e) {
3050             // All good.
3051         }
3052     }
3054     /**
3055      * Test update course competency settings.
3056      */
3057     public function test_update_course_competency_settings() {
3058         $this->resetAfterTest(true);
3060         $dg = $this->getDataGenerator();
3062         $course = $dg->create_course();
3063         $roleid = $dg->create_role();
3064         $noobroleid = $dg->create_role();
3065         $context = context_course::instance($course->id);
3066         $compmanager = $this->getDataGenerator()->create_user();
3067         $compnoob = $this->getDataGenerator()->create_user();
3069         assign_capability('tool/lp:coursecompetencyconfigure', CAP_ALLOW, $roleid, $context->id, true);
3070         assign_capability('tool/lp:coursecompetencyview', CAP_ALLOW, $roleid, $context->id, true);
3071         assign_capability('tool/lp:coursecompetencyview', CAP_ALLOW, $noobroleid, $context->id, true);
3073         role_assign($roleid, $compmanager->id, $context->id);
3074         role_assign($noobroleid, $compnoob->id, $context->id);
3075         $dg->enrol_user($compmanager->id, $course->id, $roleid);
3076         $dg->enrol_user($compnoob->id, $course->id, $noobroleid);
3078         $this->setUser($compmanager);
3080         // Start the test.
3081         $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));
3083         $settings = course_competency_settings::get_by_courseid($course->id);
3085         $this->assertTrue((bool)$settings->get_pushratingstouserplans());
3087         $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => false));
3089         $settings = course_competency_settings::get_by_courseid($course->id);
3091         $this->assertFalse((bool)$settings->get_pushratingstouserplans());
3092         $this->setUser($compnoob);
3094         $this->setExpectedException('required_capability_exception');
3095         $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));
3096     }
3098     public function test_list_course_modules_using_competency() {
3099         $this->setAdminUser();
3101         $dg = $this->getDataGenerator();
3102         $lpg = $dg->get_plugin_generator('tool_lp');
3104         $course = $dg->create_course();
3105         $cm1 = $dg->create_module('assign', array('course' => $course->id));
3107         $f1 = $lpg->create_framework();
3108         $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3109         $lpg->create_course_competency(array('courseid' => $course->id, 'competencyid' => $c1->get_id()));
3110         $lpg->create_course_module_competency(array('cmid' => $cm1->cmid, 'competencyid' => $c1->get_id()));
3112         $result = external::list_course_modules_using_competency($c1->get_id(), $course->id);
3113         $result = external_api::clean_returnvalue(external::list_course_modules_using_competency_returns(), $result);
3114         $this->assertCount(1, $result);
3115         $this->assertEquals($cm1->cmid, $result[0]['id']);
3116     }