Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * External tests.
19
 *
20
 * @package    core_competency
21
 * @copyright  2016 Frédéric Massart - FMCorz.net
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_competency\external;
26
 
27
use core_competency\api;
28
use core_competency\course_competency_settings;
29
use core_competency\external;
30
use core_competency\invalid_persistent_exception;
31
use core_competency\plan;
32
use core_competency\plan_competency;
33
use core_competency\related_competency;
34
use core_competency\template;
35
use core_competency\template_competency;
36
use core_competency\user_competency;
37
use core_competency\user_competency_plan;
38
use core_external\external_api;
39
use externallib_advanced_testcase;
40
 
41
defined('MOODLE_INTERNAL') || die();
42
global $CFG;
43
 
44
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
45
 
46
/**
47
 * External testcase.
48
 *
49
 * @package    core_competency
50
 * @copyright  2016 Frédéric Massart - FMCorz.net
51
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
52
 */
53
class external_test extends externallib_advanced_testcase {
54
 
55
    /** @var \stdClass $creator User with enough permissions to create insystem context. */
56
    protected $creator = null;
57
 
58
    /** @var \stdClass $learningplancreator User with enough permissions to create incategory context. */
59
    protected $catcreator = null;
60
 
61
    /** @var \stdClass $category Category */
62
    protected $category = null;
63
 
64
    /** @var \stdClass $user User with enough permissions to view insystem context */
65
    protected $user = null;
66
 
67
    /** @var \stdClass $catuser User with enough permissions to view incategory context */
68
    protected $catuser = null;
69
 
70
    /** @var int Creator role id */
71
    protected $creatorrole = null;
72
 
73
    /** @var int User role id */
74
    protected $userrole = null;
75
 
76
    /** @var \stdClass $scale1 Scale */
77
    protected $scale1 = null;
78
 
79
    /** @var \stdClass $scale2 Scale */
80
    protected $scale2 = null;
81
 
82
    /** @var \stdClass $scale3 Scale */
83
    protected $scale3 = null;
84
 
85
    /** @var \stdClass $scale4 Scale */
86
    protected $scale4 = null;
87
 
88
    /** @var string scaleconfiguration */
89
    protected $scaleconfiguration1 = null;
90
 
91
    /** @var string scaleconfiguration */
92
    protected $scaleconfiguration2 = null;
93
 
94
    /** @var string catscaleconfiguration */
95
    protected $scaleconfiguration3 = null;
96
 
97
    /** @var string category scale configuration. */
98
    protected $scaleconfiguration4 = null;
99
 
100
    /** @var \core_course_category course category record. */
101
    protected $othercategory = null;
102
 
103
    /**
104
     * Setup function- we will create a course and add an assign instance to it.
105
     */
106
    protected function setUp(): void {
107
        global $DB, $CFG;
108
 
109
        $this->resetAfterTest(true);
110
 
111
        // Create some users.
112
        $creator = $this->getDataGenerator()->create_user();
113
        $user = $this->getDataGenerator()->create_user();
114
        $catuser = $this->getDataGenerator()->create_user();
115
        $category = $this->getDataGenerator()->create_category();
116
        $othercategory = $this->getDataGenerator()->create_category();
117
        $catcreator = $this->getDataGenerator()->create_user();
118
 
119
        $syscontext = \context_system::instance();
120
        $catcontext = \context_coursecat::instance($category->id);
121
        $othercatcontext = \context_coursecat::instance($othercategory->id);
122
 
123
        // Fetching default authenticated user role.
124
        $authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid));
125
 
126
        // Reset all default authenticated users permissions.
127
        unassign_capability('moodle/competency:competencygrade', $authrole->id);
128
        unassign_capability('moodle/competency:competencymanage', $authrole->id);
129
        unassign_capability('moodle/competency:competencyview', $authrole->id);
130
        unassign_capability('moodle/competency:planmanage', $authrole->id);
131
        unassign_capability('moodle/competency:planmanagedraft', $authrole->id);
132
        unassign_capability('moodle/competency:planmanageown', $authrole->id);
133
        unassign_capability('moodle/competency:planview', $authrole->id);
134
        unassign_capability('moodle/competency:planviewdraft', $authrole->id);
135
        unassign_capability('moodle/competency:planviewown', $authrole->id);
136
        unassign_capability('moodle/competency:planviewowndraft', $authrole->id);
137
        unassign_capability('moodle/competency:templatemanage', $authrole->id);
138
        unassign_capability('moodle/competency:templateview', $authrole->id);
139
        unassign_capability('moodle/cohort:manage', $authrole->id);
140
        unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id);
141
 
142
        // Creating specific roles.
143
        $this->creatorrole = create_role('Creator role', 'creatorrole', 'learning plan creator role description');
144
        $this->userrole = create_role('User role', 'userrole', 'learning plan user role description');
145
 
146
        assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
147
        assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id);
148
        assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id);
149
        assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
150
        assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
151
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id);
152
        assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id);
153
        assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
154
        assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
155
        assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id);
156
        assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
157
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id);
158
        assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id);
159
        assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
160
 
161
        role_assign($this->creatorrole, $creator->id, $syscontext->id);
162
        role_assign($this->creatorrole, $catcreator->id, $catcontext->id);
163
        role_assign($this->userrole, $user->id, $syscontext->id);
164
        role_assign($this->userrole, $catuser->id, $catcontext->id);
165
 
166
        $this->creator = $creator;
167
        $this->catcreator = $catcreator;
168
        $this->user = $user;
169
        $this->catuser = $catuser;
170
        $this->category = $category;
171
        $this->othercategory = $othercategory;
172
 
173
        $this->scale1 = $this->getDataGenerator()->create_scale(array("scale" => "value1, value2"));
174
        $this->scale2 = $this->getDataGenerator()->create_scale(array("scale" => "value3, value4"));
175
        $this->scale3 = $this->getDataGenerator()->create_scale(array("scale" => "value5, value6"));
176
        $this->scale4 = $this->getDataGenerator()->create_scale(array("scale" => "value7, value8"));
177
 
178
        $this->scaleconfiguration1 = '[{"scaleid":"'.$this->scale1->id.'"},' .
179
                '{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .
180
                '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';
181
        $this->scaleconfiguration2 = '[{"scaleid":"'.$this->scale2->id.'"},' .
182
                '{"name":"value3","id":1,"scaledefault":1,"proficient":0},' .
183
                '{"name":"value4","id":2,"scaledefault":0,"proficient":1}]';
184
        $this->scaleconfiguration3 = '[{"scaleid":"'.$this->scale3->id.'"},' .
185
                '{"name":"value5","id":1,"scaledefault":1,"proficient":0},' .
186
                '{"name":"value6","id":2,"scaledefault":0,"proficient":1}]';
187
        $this->scaleconfiguration4 = '[{"scaleid":"'.$this->scale4->id.'"},'.
188
                '{"name":"value8","id":1,"scaledefault":1,"proficient":0},' .
189
                '{"name":"value8","id":2,"scaledefault":0,"proficient":1}]';
190
        accesslib_clear_all_caches_for_unit_testing();
191
    }
192
 
193
 
194
    protected function create_competency_framework($number = 1, $system = true) {
195
        $scalename = 'scale' . $number;
196
        $scalepropname = 'scaleconfiguration' . $number;
197
        $framework = array(
198
            'shortname' => 'shortname' . $number,
199
            'idnumber' => 'idnumber' . $number,
200
            'description' => 'description' . $number,
201
            'descriptionformat' => FORMAT_HTML,
202
            'scaleid' => $this->$scalename->id,
203
            'scaleconfiguration' => $this->$scalepropname,
204
            'visible' => true,
205
            'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id
206
        );
207
        $result = external::create_competency_framework($framework);
208
        return (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
209
    }
210
 
211
    protected function create_plan($number, $userid, $templateid, $status, $duedate) {
212
        $plan = array(
213
            'name' => 'name' . $number,
214
            'description' => 'description' . $number,
215
            'descriptionformat' => FORMAT_HTML,
216
            'userid' => $userid,
217
            'templateid' => empty($templateid) ? null : $templateid,
218
            'status' => $status,
219
            'duedate' => $duedate
220
        );
221
        $result = external::create_plan($plan);
222
        return (object) external_api::clean_returnvalue(external::create_plan_returns(), $result);
223
    }
224
 
225
    protected function create_template($number, $system) {
226
        $template = array(
227
            'shortname' => 'shortname' . $number,
228
            'description' => 'description' . $number,
229
            'descriptionformat' => FORMAT_HTML,
230
            'duedate' => 0,
231
            'visible' => true,
232
            'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id
233
        );
234
        $result = external::create_template($template);
235
        return (object) external_api::clean_returnvalue(external::create_template_returns(), $result);
236
    }
237
 
238
    protected function update_template($templateid, $number) {
239
        $template = array(
240
            'id' => $templateid,
241
            'shortname' => 'shortname' . $number,
242
            'description' => 'description' . $number,
243
            'descriptionformat' => FORMAT_HTML,
244
            'visible' => true
245
        );
246
        $result = external::update_template($template);
247
        return external_api::clean_returnvalue(external::update_template_returns(), $result);
248
    }
249
 
250
    protected function update_plan($planid, $number, $userid, $templateid, $status, $duedate) {
251
        $plan = array(
252
            'id' => $planid,
253
            'name' => 'name' . $number,
254
            'description' => 'description' . $number,
255
            'descriptionformat' => FORMAT_HTML,
256
            'userid' => $userid,
257
            'templateid' => $templateid,
258
            'status' => $status,
259
            'duedate' => $duedate
260
        );
261
        $result = external::update_plan($plan);
262
        return external_api::clean_returnvalue(external::update_plan_returns(), $result);
263
    }
264
 
265
    protected function update_competency_framework($id, $number = 1, $system = true) {
266
        $scalename = 'scale' . $number;
267
        $scalepropname = 'scaleconfiguration' . $number;
268
        $framework = array(
269
            'id' => $id,
270
            'shortname' => 'shortname' . $number,
271
            'idnumber' => 'idnumber' . $number,
272
            'description' => 'description' . $number,
273
            'descriptionformat' => FORMAT_HTML,
274
            'scaleid' => $this->$scalename->id,
275
            'scaleconfiguration' => $this->$scalepropname,
276
            'visible' => true,
277
            'contextid' => $system ? \context_system::instance()->id : \context_coursecat::instance($this->category->id)->id
278
        );
279
        $result = external::update_competency_framework($framework);
280
        return external_api::clean_returnvalue(external::update_competency_framework_returns(), $result);
281
    }
282
 
283
    protected function create_competency($number, $frameworkid) {
284
        $competency = array(
285
            'shortname' => 'shortname' . $number,
286
            'idnumber' => 'idnumber' . $number,
287
            'description' => 'description' . $number,
288
            'descriptionformat' => FORMAT_HTML,
289
            'competencyframeworkid' => $frameworkid
290
        );
291
        $result = external::create_competency($competency);
292
        return (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
293
    }
294
 
295
    protected function update_competency($id, $number) {
296
        $competency = array(
297
            'id' => $id,
298
            'shortname' => 'shortname' . $number,
299
            'idnumber' => 'idnumber' . $number,
300
            'description' => 'description' . $number,
301
            'descriptionformat' => FORMAT_HTML
302
        );
303
        $result = external::update_competency($competency);
304
        return external_api::clean_returnvalue(external::update_competency_returns(), $result);
305
    }
306
 
307
    /**
308
     * Test we can't create a competency framework with only read permissions.
309
     */
11 efrain 310
    public function test_create_competency_frameworks_with_read_permissions(): void {
1 efrain 311
        $this->setUser($this->user);
312
 
313
        $this->expectException(\required_capability_exception::class);
314
        $result = $this->create_competency_framework(1, true);
315
    }
316
 
317
    /**
318
     * Test we can't create a competency framework with only read permissions.
319
     */
11 efrain 320
    public function test_create_competency_frameworks_with_read_permissions_in_category(): void {
1 efrain 321
        $this->setUser($this->catuser);
322
        $this->expectException(\required_capability_exception::class);
323
        $result = $this->create_competency_framework(1, false);
324
    }
325
 
326
    /**
327
     * Test we can create a competency framework with manage permissions.
328
     */
11 efrain 329
    public function test_create_competency_frameworks_with_manage_permissions(): void {
1 efrain 330
        $this->setUser($this->creator);
331
        $result = $this->create_competency_framework(1, true);
332
 
333
        $this->assertGreaterThan(0, $result->timecreated);
334
        $this->assertGreaterThan(0, $result->timemodified);
335
        $this->assertEquals($this->creator->id, $result->usermodified);
336
        $this->assertEquals('shortname1', $result->shortname);
337
        $this->assertEquals('idnumber1', $result->idnumber);
338
        $this->assertEquals('description1', $result->description);
339
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
340
        $this->assertEquals($this->scale1->id, $result->scaleid);
341
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
342
        $this->assertEquals(true, $result->visible);
343
    }
344
 
345
    /**
346
     * Test we can create a competency framework with manage permissions.
347
     */
11 efrain 348
    public function test_create_competency_frameworks_with_manage_permissions_in_category(): void {
1 efrain 349
        $this->setUser($this->catcreator);
350
        $result = $this->create_competency_framework(1, false);
351
 
352
        $this->assertGreaterThan(0, $result->timecreated);
353
        $this->assertGreaterThan(0, $result->timemodified);
354
        $this->assertEquals($this->catcreator->id, $result->usermodified);
355
        $this->assertEquals('shortname1', $result->shortname);
356
        $this->assertEquals('idnumber1', $result->idnumber);
357
        $this->assertEquals('description1', $result->description);
358
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
359
        $this->assertEquals($this->scale1->id, $result->scaleid);
360
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
361
        $this->assertEquals(true, $result->visible);
362
 
363
        try {
364
            $result = $this->create_competency_framework(1, true);
365
            $this->fail('User cannot create a framework at system level.');
366
        } catch (\required_capability_exception $e) {
367
            // All good.
368
        }
369
    }
370
 
371
    /**
372
     * Test we cannot create a competency framework with nasty data.
373
     */
11 efrain 374
    public function test_create_competency_frameworks_with_nasty_data(): void {
1 efrain 375
        $this->setUser($this->creator);
376
        $framework = array(
377
            'shortname' => 'short<a href="">',
378
            'idnumber' => 'id;"number',
379
            'description' => 'de<>\\..scription',
380
            'descriptionformat' => FORMAT_HTML,
381
            'scaleid' => $this->scale1->id,
382
            'scaleconfiguration' => $this->scaleconfiguration1,
383
            'visible' => true,
384
            'contextid' => \context_system::instance()->id
385
        );
386
        $this->expectException(\invalid_parameter_exception::class);
387
        $result = external::create_competency_framework($framework);
388
    }
389
 
390
    /**
391
     * Test we can read a competency framework with manage permissions.
392
     */
11 efrain 393
    public function test_read_competency_frameworks_with_manage_permissions(): void {
1 efrain 394
        $this->setUser($this->creator);
395
        $result = $this->create_competency_framework(1, true);
396
 
397
        $id = $result->id;
398
        $result = external::read_competency_framework($id);
399
        $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
400
 
401
        $this->assertGreaterThan(0, $result->timecreated);
402
        $this->assertGreaterThan(0, $result->timemodified);
403
        $this->assertEquals($this->creator->id, $result->usermodified);
404
        $this->assertEquals('shortname1', $result->shortname);
405
        $this->assertEquals('idnumber1', $result->idnumber);
406
        $this->assertEquals('description1', $result->description);
407
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
408
        $this->assertEquals($this->scale1->id, $result->scaleid);
409
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
410
        $this->assertEquals(true, $result->visible);
411
    }
412
 
413
    /**
414
     * Test we can read a competency framework with manage permissions.
415
     */
11 efrain 416
    public function test_read_competency_frameworks_with_manage_permissions_in_category(): void {
1 efrain 417
        $this->setUser($this->creator);
418
 
419
        $insystem = $this->create_competency_framework(1, true);
420
        $incat = $this->create_competency_framework(2, false);
421
 
422
        $this->setUser($this->catcreator);
423
        $id = $incat->id;
424
        $result = external::read_competency_framework($id);
425
        $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
426
 
427
        $this->assertGreaterThan(0, $result->timecreated);
428
        $this->assertGreaterThan(0, $result->timemodified);
429
        $this->assertEquals($this->creator->id, $result->usermodified);
430
        $this->assertEquals('shortname2', $result->shortname);
431
        $this->assertEquals('idnumber2', $result->idnumber);
432
        $this->assertEquals('description2', $result->description);
433
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
434
        $this->assertEquals($this->scale2->id, $result->scaleid);
435
        $this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);
436
        $this->assertEquals(true, $result->visible);
437
 
438
        try {
439
            $id = $insystem->id;
440
            $result = external::read_competency_framework($id);
441
            $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
442
            $this->fail('User cannot read a framework at system level.');
443
        } catch (\required_capability_exception $e) {
444
            // All good.
445
        }
446
    }
447
 
448
    /**
449
     * Test we can read a competency framework with read permissions.
450
     */
11 efrain 451
    public function test_read_competency_frameworks_with_read_permissions(): void {
1 efrain 452
        $this->setUser($this->creator);
453
        $result = $this->create_competency_framework(1, true);
454
 
455
        // Switch users to someone with less permissions.
456
        $this->setUser($this->user);
457
        $id = $result->id;
458
        $result = external::read_competency_framework($id);
459
        $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
460
 
461
        $this->assertGreaterThan(0, $result->timecreated);
462
        $this->assertGreaterThan(0, $result->timemodified);
463
        $this->assertEquals($this->creator->id, $result->usermodified);
464
        $this->assertEquals('shortname1', $result->shortname);
465
        $this->assertEquals('idnumber1', $result->idnumber);
466
        $this->assertEquals('description1', $result->description);
467
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
468
        $this->assertEquals($this->scale1->id, $result->scaleid);
469
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
470
        $this->assertEquals(true, $result->visible);
471
    }
472
    /**
473
     * Test we can read a competency framework with read permissions.
474
     */
11 efrain 475
    public function test_read_competency_frameworks_with_read_permissions_in_category(): void {
1 efrain 476
        $this->setUser($this->creator);
477
 
478
        $insystem = $this->create_competency_framework(1, true);
479
        $incat = $this->create_competency_framework(2, false);
480
 
481
        // Switch users to someone with less permissions.
482
        $this->setUser($this->catuser);
483
        $id = $incat->id;
484
        $result = external::read_competency_framework($id);
485
        $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
486
 
487
        $this->assertGreaterThan(0, $result->timecreated);
488
        $this->assertGreaterThan(0, $result->timemodified);
489
        $this->assertEquals($this->creator->id, $result->usermodified);
490
        $this->assertEquals('shortname2', $result->shortname);
491
        $this->assertEquals('idnumber2', $result->idnumber);
492
        $this->assertEquals('description2', $result->description);
493
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
494
        $this->assertEquals($this->scale2->id, $result->scaleid);
495
        $this->assertEquals($this->scaleconfiguration2, $result->scaleconfiguration);
496
        $this->assertEquals(true, $result->visible);
497
 
498
        // Switching to user with no permissions.
499
        try {
500
            $result = external::read_competency_framework($insystem->id);
501
            $this->fail('Current user cannot should not be able to read the framework.');
502
        } catch (\required_capability_exception $e) {
503
            // All good.
504
        }
505
    }
506
 
507
    /**
508
     * Test we can delete a competency framework with manage permissions.
509
     */
11 efrain 510
    public function test_delete_competency_frameworks_with_manage_permissions(): void {
1 efrain 511
        $this->setUser($this->creator);
512
        $result = $this->create_competency_framework(1, true);
513
 
514
        $id = $result->id;
515
        $result = external::delete_competency_framework($id);
516
        $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
517
 
518
        $this->assertTrue($result);
519
    }
520
 
521
    /**
522
     * Test we can delete a competency framework with manage permissions.
523
     */
11 efrain 524
    public function test_delete_competency_frameworks_with_manage_permissions_in_category(): void {
1 efrain 525
        $this->setUser($this->creator);
526
 
527
        $insystem = $this->create_competency_framework(1, true);
528
        $incat = $this->create_competency_framework(2, false);
529
 
530
        $this->setUser($this->catcreator);
531
        $id = $incat->id;
532
        $result = external::delete_competency_framework($id);
533
        $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
534
 
535
        $this->assertTrue($result);
536
 
537
        try {
538
            $id = $insystem->id;
539
            $result = external::delete_competency_framework($id);
540
            $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
541
            $this->fail('Current user cannot should not be able to delete the framework.');
542
        } catch (\required_capability_exception $e) {
543
            // All good.
544
        }
545
    }
546
 
547
    /**
548
     * Test we can delete a competency framework with read permissions.
549
     */
11 efrain 550
    public function test_delete_competency_frameworks_with_read_permissions(): void {
1 efrain 551
        $this->setUser($this->creator);
552
        $result = $this->create_competency_framework(1, true);
553
 
554
        $id = $result->id;
555
        // Switch users to someone with less permissions.
556
        $this->setUser($this->user);
557
        $this->expectException(\required_capability_exception::class);
558
        $result = external::delete_competency_framework($id);
559
    }
560
 
561
    /**
562
     * Test we can update a competency framework with manage permissions.
563
     */
11 efrain 564
    public function test_update_competency_frameworks_with_manage_permissions(): void {
1 efrain 565
        $this->setUser($this->creator);
566
        $result = $this->create_competency_framework(1, true);
567
 
568
        $result = $this->update_competency_framework($result->id, 2, true);
569
 
570
        $this->assertTrue($result);
571
    }
572
 
573
    /**
574
     * Test we can update a competency framework with manage permissions.
575
     */
11 efrain 576
    public function test_update_competency_frameworks_with_manage_permissions_in_category(): void {
1 efrain 577
        $this->setUser($this->creator);
578
 
579
        $insystem = $this->create_competency_framework(1, true);
580
        $incat = $this->create_competency_framework(2, false);
581
 
582
        $this->setUser($this->catcreator);
583
        $id = $incat->id;
584
 
585
        $result = $this->update_competency_framework($incat->id, 3, false);
586
 
587
        $this->assertTrue($result);
588
 
589
        try {
590
            $result = $this->update_competency_framework($insystem->id, 4, true);
591
            $this->fail('Current user should not be able to update the framework.');
592
        } catch (\required_capability_exception $e) {
593
            // All good.
594
        }
595
    }
596
 
11 efrain 597
    public function test_update_framework_scale(): void {
1 efrain 598
        $this->setUser($this->creator);
599
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
600
 
601
        $s1 = $this->getDataGenerator()->create_scale();
602
 
603
        $f1 = $lpg->create_framework(array('scaleid' => $s1->id));
604
        $f2 = $lpg->create_framework(array('scaleid' => $s1->id));
605
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
606
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));
607
 
608
        $this->assertEquals($s1->id, $f1->get('scaleid'));
609
 
610
        // Make the scale of f2 being used.
611
        $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2->get('id')));
612
 
613
        // Changing the framework where the scale is not used.
614
        $result = $this->update_competency_framework($f1->get('id'), 3, true);
615
 
616
        $f1 = new \core_competency\competency_framework($f1->get('id'));
617
        $this->assertEquals($this->scale3->id, $f1->get('scaleid'));
618
 
619
        // Changing the framework where the scale is used.
620
        try {
621
            $result = $this->update_competency_framework($f2->get('id'), 4, true);
622
            $this->fail('The scale cannot be changed once used.');
623
        } catch (\core\invalid_persistent_exception $e) {
624
            $this->assertMatchesRegularExpression('/scaleid/', $e->getMessage());
625
        }
626
    }
627
 
628
    /**
629
     * Test we can update a competency framework with read permissions.
630
     */
11 efrain 631
    public function test_update_competency_frameworks_with_read_permissions(): void {
1 efrain 632
        $this->setUser($this->creator);
633
        $result = $this->create_competency_framework(1, true);
634
 
635
        $this->setUser($this->user);
636
        $this->expectException(\required_capability_exception::class);
637
        $result = $this->update_competency_framework($result->id, 2, true);
638
    }
639
 
640
    /**
641
     * Test we can list and count competency frameworks with manage permissions.
642
     */
11 efrain 643
    public function test_list_and_count_competency_frameworks_with_manage_permissions(): void {
1 efrain 644
        $this->setUser($this->creator);
645
        $result = $this->create_competency_framework(1, true);
646
        $result = $this->create_competency_framework(2, true);
647
        $result = $this->create_competency_framework(3, true);
648
        $result = $this->create_competency_framework(4, false);
649
 
650
        $result = external::count_competency_frameworks(array('contextid' => \context_system::instance()->id), 'self');
651
        $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
652
 
653
        $this->assertEquals($result, 3);
654
 
655
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
656
            array('contextid' => \context_system::instance()->id), 'self', false);
657
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
658
 
659
        $this->assertEquals(count($result), 3);
660
        $result = (object) $result[0];
661
 
662
        $this->assertGreaterThan(0, $result->timecreated);
663
        $this->assertGreaterThan(0, $result->timemodified);
664
        $this->assertEquals($this->creator->id, $result->usermodified);
665
        $this->assertEquals('shortname1', $result->shortname);
666
        $this->assertEquals('idnumber1', $result->idnumber);
667
        $this->assertEquals('description1', $result->description);
668
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
669
        $this->assertEquals($this->scale1->id, $result->scaleid);
670
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
671
        $this->assertEquals(true, $result->visible);
672
    }
673
 
11 efrain 674
    public function test_list_competency_frameworks_with_query(): void {
1 efrain 675
        $this->setUser($this->creator);
676
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
677
        $framework1 = $lpg->create_framework(array(
678
            'shortname' => 'shortname_beetroot',
679
            'idnumber' => 'idnumber_cinnamon',
680
            'description' => 'description',
681
            'descriptionformat' => FORMAT_HTML,
682
            'visible' => true,
683
            'contextid' => \context_system::instance()->id
684
        ));
685
        $framework2 = $lpg->create_framework(array(
686
            'shortname' => 'shortname_citrus',
687
            'idnumber' => 'idnumber_beer',
688
            'description' => 'description',
689
            'descriptionformat' => FORMAT_HTML,
690
            'visible' => true,
691
            'contextid' => \context_system::instance()->id
692
        ));
693
 
694
        // Search on both ID number and shortname.
695
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
696
            array('contextid' => \context_system::instance()->id), 'self', false, 'bee');
697
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
698
        $this->assertCount(2, $result);
699
        $f = (object) array_shift($result);
700
        $this->assertEquals($framework1->get('id'), $f->id);
701
        $f = (object) array_shift($result);
702
        $this->assertEquals($framework2->get('id'), $f->id);
703
 
704
        // Search on ID number.
705
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
706
            array('contextid' => \context_system::instance()->id), 'self', false, 'beer');
707
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
708
        $this->assertCount(1, $result);
709
        $f = (object) array_shift($result);
710
        $this->assertEquals($framework2->get('id'), $f->id);
711
 
712
        // Search on shortname.
713
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
714
            array('contextid' => \context_system::instance()->id), 'self', false, 'cinnamon');
715
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
716
        $this->assertCount(1, $result);
717
        $f = (object) array_shift($result);
718
        $this->assertEquals($framework1->get('id'), $f->id);
719
 
720
        // No match.
721
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
722
            array('contextid' => \context_system::instance()->id), 'self', false, 'pwnd!');
723
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
724
        $this->assertCount(0, $result);
725
    }
726
 
727
    /**
728
     * Test we can list and count competency frameworks with read permissions.
729
     */
11 efrain 730
    public function test_list_and_count_competency_frameworks_with_read_permissions(): void {
1 efrain 731
        $this->setUser($this->creator);
732
        $result = $this->create_competency_framework(1, true);
733
        $result = $this->create_competency_framework(2, true);
734
        $result = $this->create_competency_framework(3, true);
735
        $result = $this->create_competency_framework(4, false);
736
 
737
        $this->setUser($this->user);
738
        $result = external::count_competency_frameworks(array('contextid' => \context_system::instance()->id), 'self');
739
        $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
740
        $this->assertEquals($result, 3);
741
 
742
        $result = external::list_competency_frameworks('shortname', 'ASC', 0, 10,
743
            array('contextid' => \context_system::instance()->id), 'self', false);
744
        $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
745
 
746
        $this->assertEquals(count($result), 3);
747
        $result = (object) $result[0];
748
 
749
        $this->assertGreaterThan(0, $result->timecreated);
750
        $this->assertGreaterThan(0, $result->timemodified);
751
        $this->assertEquals($this->creator->id, $result->usermodified);
752
        $this->assertEquals('shortname1', $result->shortname);
753
        $this->assertEquals('idnumber1', $result->idnumber);
754
        $this->assertEquals('description1', $result->description);
755
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
756
        $this->assertEquals($this->scale1->id, $result->scaleid);
757
        $this->assertEquals($this->scaleconfiguration1, $result->scaleconfiguration);
758
        $this->assertEquals(true, $result->visible);
759
    }
760
 
761
    /**
762
     * Test we can't create a competency with only read permissions.
763
     */
11 efrain 764
    public function test_create_competency_with_read_permissions(): void {
1 efrain 765
        $framework = $this->getDataGenerator()->get_plugin_generator('core_competency')->create_framework();
766
        $this->setUser($this->user);
767
        $this->expectException(\required_capability_exception::class);
768
        $competency = $this->create_competency(1, $framework->get('id'));
769
    }
770
 
771
    /**
772
     * Test we can create a competency with manage permissions.
773
     */
11 efrain 774
    public function test_create_competency_with_manage_permissions(): void {
1 efrain 775
        $this->setUser($this->creator);
776
        $framework = $this->create_competency_framework(1, true);
777
        $competency = $this->create_competency(1, $framework->id);
778
 
779
        $this->assertGreaterThan(0, $competency->timecreated);
780
        $this->assertGreaterThan(0, $competency->timemodified);
781
        $this->assertEquals($this->creator->id, $competency->usermodified);
782
        $this->assertEquals('shortname1', $competency->shortname);
783
        $this->assertEquals('idnumber1', $competency->idnumber);
784
        $this->assertEquals('description1', $competency->description);
785
        $this->assertEquals(FORMAT_HTML, $competency->descriptionformat);
786
        $this->assertEquals(0, $competency->parentid);
787
        $this->assertEquals($framework->id, $competency->competencyframeworkid);
788
    }
789
 
790
 
791
    /**
792
     * Test we can create a competency with manage permissions.
793
     */
11 efrain 794
    public function test_create_competency_with_manage_permissions_in_category(): void {
1 efrain 795
        $this->setUser($this->creator);
796
 
797
        $insystem = $this->create_competency_framework(1, true);
798
        $incat = $this->create_competency_framework(2, false);
799
 
800
        $this->setUser($this->catcreator);
801
 
802
        $competency = $this->create_competency(1, $incat->id);
803
 
804
        $this->assertGreaterThan(0, $competency->timecreated);
805
        $this->assertGreaterThan(0, $competency->timemodified);
806
        $this->assertEquals($this->catcreator->id, $competency->usermodified);
807
        $this->assertEquals('shortname1', $competency->shortname);
808
        $this->assertEquals('idnumber1', $competency->idnumber);
809
        $this->assertEquals('description1', $competency->description);
810
        $this->assertEquals(FORMAT_HTML, $competency->descriptionformat);
811
        $this->assertEquals(0, $competency->parentid);
812
        $this->assertEquals($incat->id, $competency->competencyframeworkid);
813
 
814
        try {
815
            $competency = $this->create_competency(2, $insystem->id);
816
            $this->fail('User should not be able to create a competency in system context.');
817
        } catch (\required_capability_exception $e) {
818
            // All good.
819
        }
820
    }
821
 
822
    /**
823
     * Test we cannot create a competency with nasty data.
824
     */
11 efrain 825
    public function test_create_competency_with_nasty_data(): void {
1 efrain 826
        $this->setUser($this->creator);
827
        $framework = $this->create_competency_framework(1, true);
828
        $competency = array(
829
            'shortname' => 'shortname<a href="">',
830
            'idnumber' => 'id;"number',
831
            'description' => 'de<>\\..scription',
832
            'descriptionformat' => FORMAT_HTML,
833
            'competencyframeworkid' => $framework->id,
834
            'sortorder' => 0
835
        );
836
 
837
        $this->expectException(\invalid_parameter_exception::class);
838
        $this->expectExceptionMessage('Invalid external api parameter');
839
        $result = external::create_competency($competency);
840
    }
841
 
842
    /**
843
     * Test we can read a competency with manage permissions.
844
     */
11 efrain 845
    public function test_read_competencies_with_manage_permissions(): void {
1 efrain 846
        $this->setUser($this->creator);
847
        $framework = $this->create_competency_framework(1, true);
848
        $competency = $this->create_competency(1, $framework->id);
849
 
850
        $id = $competency->id;
851
        $result = external::read_competency($id);
852
        $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
853
 
854
        $this->assertGreaterThan(0, $result->timecreated);
855
        $this->assertGreaterThan(0, $result->timemodified);
856
        $this->assertEquals($this->creator->id, $result->usermodified);
857
        $this->assertEquals('shortname1', $result->shortname);
858
        $this->assertEquals('idnumber1', $result->idnumber);
859
        $this->assertEquals('description1', $result->description);
860
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
861
        $this->assertEquals(0, $result->parentid);
862
        $this->assertEquals($framework->id, $result->competencyframeworkid);
863
    }
864
 
865
    /**
866
     * Test we can read a competency with manage permissions.
867
     */
11 efrain 868
    public function test_read_competencies_with_manage_permissions_in_category(): void {
1 efrain 869
        $this->setUser($this->creator);
870
 
871
        $sysframework = $this->create_competency_framework(1, true);
872
        $insystem = $this->create_competency(1, $sysframework->id);
873
 
874
        $catframework = $this->create_competency_framework(2, false);
875
        $incat = $this->create_competency(2, $catframework->id);
876
 
877
        $this->setUser($this->catcreator);
878
        $id = $incat->id;
879
        $result = external::read_competency($id);
880
        $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
881
 
882
        $this->assertGreaterThan(0, $result->timecreated);
883
        $this->assertGreaterThan(0, $result->timemodified);
884
        $this->assertEquals($this->creator->id, $result->usermodified);
885
        $this->assertEquals('shortname2', $result->shortname);
886
        $this->assertEquals('idnumber2', $result->idnumber);
887
        $this->assertEquals('description2', $result->description);
888
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
889
        $this->assertEquals(0, $result->parentid);
890
        $this->assertEquals($catframework->id, $result->competencyframeworkid);
891
 
892
        try {
893
            external::read_competency($insystem->id);
894
            $this->fail('User should not be able to read a competency in system context.');
895
        } catch (\required_capability_exception $e) {
896
            // All good.
897
        }
898
    }
899
 
900
    /**
901
     * Test we can read a competency with read permissions.
902
     */
11 efrain 903
    public function test_read_competencies_with_read_permissions(): void {
1 efrain 904
        $this->setUser($this->creator);
905
        $framework = $this->create_competency_framework(1, true);
906
        $competency = $this->create_competency(1, $framework->id);
907
 
908
        // Switch users to someone with less permissions.
909
        $this->setUser($this->user);
910
        $id = $competency->id;
911
        $result = external::read_competency($id);
912
        $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
913
 
914
        $this->assertGreaterThan(0, $result->timecreated);
915
        $this->assertGreaterThan(0, $result->timemodified);
916
        $this->assertEquals($this->creator->id, $result->usermodified);
917
        $this->assertEquals('shortname1', $result->shortname);
918
        $this->assertEquals('idnumber1', $result->idnumber);
919
        $this->assertEquals('description1', $result->description);
920
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
921
        $this->assertEquals(0, $result->parentid);
922
        $this->assertEquals($framework->id, $result->competencyframeworkid);
923
    }
924
 
925
    /**
926
     * Test we can read a competency with read permissions.
927
     */
11 efrain 928
    public function test_read_competencies_with_read_permissions_in_category(): void {
1 efrain 929
        $this->setUser($this->creator);
930
        $sysframework = $this->create_competency_framework(1, true);
931
        $insystem = $this->create_competency(1, $sysframework->id);
932
        $catframework = $this->create_competency_framework(2, false);
933
        $incat = $this->create_competency(2, $catframework->id);
934
 
935
        // Switch users to someone with less permissions.
936
        $this->setUser($this->catuser);
937
        $id = $incat->id;
938
        $result = external::read_competency($id);
939
        $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
940
 
941
        $this->assertGreaterThan(0, $result->timecreated);
942
        $this->assertGreaterThan(0, $result->timemodified);
943
        $this->assertEquals($this->creator->id, $result->usermodified);
944
        $this->assertEquals('shortname2', $result->shortname);
945
        $this->assertEquals('idnumber2', $result->idnumber);
946
        $this->assertEquals('description2', $result->description);
947
        $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
948
        $this->assertEquals(0, $result->parentid);
949
        $this->assertEquals($catframework->id, $result->competencyframeworkid);
950
 
951
        try {
952
            external::read_competency($insystem->id);
953
            $this->fail('User should not be able to read a competency in system context.');
954
        } catch (\required_capability_exception $e) {
955
            // All good.
956
        }
957
    }
958
 
959
    /**
960
     * Test we can delete a competency with manage permissions.
961
     */
11 efrain 962
    public function test_delete_competency_with_manage_permissions(): void {
1 efrain 963
        $this->setUser($this->creator);
964
        $framework = $this->create_competency_framework(1, true);
965
        $result = $this->create_competency(1, $framework->id);
966
 
967
        $id = $result->id;
968
        $result = external::delete_competency($id);
969
        $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
970
 
971
        $this->assertTrue($result);
972
    }
973
 
974
    /**
975
     * Test we can delete a competency with manage permissions.
976
     */
11 efrain 977
    public function test_delete_competency_with_manage_permissions_in_category(): void {
1 efrain 978
        $this->setUser($this->creator);
979
 
980
        $sysframework = $this->create_competency_framework(1, true);
981
        $insystem = $this->create_competency(1, $sysframework->id);
982
        $catframework = $this->create_competency_framework(2, false);
983
        $incat = $this->create_competency(2, $catframework->id);
984
 
985
        $this->setUser($this->catcreator);
986
        $id = $incat->id;
987
        $result = external::delete_competency($id);
988
        $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
989
 
990
        $this->assertTrue($result);
991
 
992
        try {
993
            $result = external::delete_competency($insystem->id);
994
            $this->fail('User should not be able to delete a competency in system context.');
995
        } catch (\required_capability_exception $e) {
996
            // All good.
997
        }
998
    }
999
 
1000
    /**
1001
     * Test we can delete a competency with read permissions.
1002
     */
11 efrain 1003
    public function test_delete_competency_with_read_permissions(): void {
1 efrain 1004
        $this->setUser($this->creator);
1005
        $framework = $this->create_competency_framework(1, true);
1006
        $result = $this->create_competency(1, $framework->id);
1007
 
1008
        $id = $result->id;
1009
        // Switch users to someone with less permissions.
1010
        $this->setUser($this->user);
1011
        $this->expectException(\required_capability_exception::class);
1012
        $result = external::delete_competency($id);
1013
    }
1014
 
1015
    /**
1016
     * Test we can update a competency with manage permissions.
1017
     */
11 efrain 1018
    public function test_update_competency_with_manage_permissions(): void {
1 efrain 1019
        $this->setUser($this->creator);
1020
        $framework = $this->create_competency_framework(1, true);
1021
        $result = $this->create_competency(1, $framework->id);
1022
 
1023
        $result = $this->update_competency($result->id, 2);
1024
 
1025
        $this->assertTrue($result);
1026
    }
1027
 
1028
    /**
1029
     * Test we can update a competency with manage permissions.
1030
     */
11 efrain 1031
    public function test_update_competency_with_manage_permissions_in_category(): void {
1 efrain 1032
        $this->setUser($this->creator);
1033
 
1034
        $sysframework = $this->create_competency_framework(1, true);
1035
        $insystem = $this->create_competency(1, $sysframework->id);
1036
        $catframework = $this->create_competency_framework(2, false);
1037
        $incat = $this->create_competency(2, $catframework->id);
1038
 
1039
        $this->setUser($this->catcreator);
1040
 
1041
        $result = $this->update_competency($incat->id, 2);
1042
 
1043
        $this->assertTrue($result);
1044
 
1045
        try {
1046
            $result = $this->update_competency($insystem->id, 3);
1047
            $this->fail('User should not be able to update a competency in system context.');
1048
        } catch (\required_capability_exception $e) {
1049
            // All good.
1050
        }
1051
    }
1052
 
1053
    /**
1054
     * Test we can update a competency with read permissions.
1055
     */
11 efrain 1056
    public function test_update_competency_with_read_permissions(): void {
1 efrain 1057
        $this->setUser($this->creator);
1058
        $framework = $this->create_competency_framework(1, true);
1059
        $result = $this->create_competency(1, $framework->id);
1060
 
1061
        $this->setUser($this->user);
1062
        $this->expectException(\required_capability_exception::class);
1063
        $result = $this->update_competency($result->id, 2);
1064
    }
1065
 
1066
    /**
1067
     * Test count competencies with filters.
1068
     */
11 efrain 1069
    public function test_count_competencies_with_filters(): void {
1 efrain 1070
        $this->setUser($this->creator);
1071
 
1072
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
1073
        $f1 = $lpg->create_framework();
1074
        $f2 = $lpg->create_framework();
1075
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
1076
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id'), 'shortname' => 'A'));
1077
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
1078
        $c4 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));
1079
        $c5 = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));
1080
 
1081
        $result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f2->get('id'))));
1082
        $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1083
        $this->assertEquals(2, $result);
1084
 
1085
        $result = external::count_competencies(array(array('column' => 'competencyframeworkid', 'value' => $f1->get('id'))));
1086
        $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1087
        $this->assertEquals(3, $result);
1088
 
1089
        $result = external::count_competencies(array(array('column' => 'shortname', 'value' => 'A')));
1090
        $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1091
        $this->assertEquals(1, $result);
1092
    }
1093
 
1094
    /**
1095
     * Test we can list and count competencies with manage permissions.
1096
     */
11 efrain 1097
    public function test_list_and_count_competencies_with_manage_permissions(): void {
1 efrain 1098
        $this->setUser($this->creator);
1099
        $framework = $this->create_competency_framework(1, true);
1100
        $result = $this->create_competency(1, $framework->id);
1101
        $result = $this->create_competency(2, $framework->id);
1102
        $result = $this->create_competency(3, $framework->id);
1103
 
1104
        $result = external::count_competencies(array());
1105
        $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1106
 
1107
        $this->assertEquals($result, 3);
1108
 
1109
        array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, \context_system::instance()->id));
1110
        $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
1111
 
1112
        $this->assertEquals(count($result), 3);
1113
        $result = (object) $result[0];
1114
 
1115
        $this->assertGreaterThan(0, $result->timecreated);
1116
        $this->assertGreaterThan(0, $result->timemodified);
1117
        $this->assertEquals($this->creator->id, $result->usermodified);
1118
        $this->assertEquals('shortname1', $result->shortname);
1119
        $this->assertEquals('idnumber1', $result->idnumber);
1120
        $this->assertEquals('description1', $result->description);
1121
    }
1122
 
1123
    /**
1124
     * Test we can list and count competencies with read permissions.
1125
     */
11 efrain 1126
    public function test_list_and_count_competencies_with_read_permissions(): void {
1 efrain 1127
        $this->setUser($this->creator);
1128
        $framework = $this->create_competency_framework(1, true);
1129
        $result = $this->create_competency(1, $framework->id);
1130
        $result = $this->create_competency(2, $framework->id);
1131
        $result = $this->create_competency(3, $framework->id);
1132
 
1133
        $this->setUser($this->user);
1134
 
1135
        $result = external::count_competencies(array());
1136
        $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
1137
 
1138
        $this->assertEquals($result, 3);
1139
 
1140
        array('id' => $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10, \context_system::instance()->id));
1141
        $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
1142
 
1143
        $this->assertEquals(count($result), 3);
1144
        $result = (object) $result[0];
1145
 
1146
        $this->assertGreaterThan(0, $result->timecreated);
1147
        $this->assertGreaterThan(0, $result->timemodified);
1148
        $this->assertEquals($this->creator->id, $result->usermodified);
1149
        $this->assertEquals('shortname1', $result->shortname);
1150
        $this->assertEquals('idnumber1', $result->idnumber);
1151
        $this->assertEquals('description1', $result->description);
1152
    }
1153
 
1154
    /**
1155
     * Test we can search for competencies.
1156
     */
11 efrain 1157
    public function test_search_competencies_with_read_permissions(): void {
1 efrain 1158
        $this->setUser($this->creator);
1159
        $framework = $this->create_competency_framework(1, true);
1160
        $result = $this->create_competency(1, $framework->id);
1161
        $result = $this->create_competency(2, $framework->id);
1162
        $result = $this->create_competency(3, $framework->id);
1163
 
1164
        $this->setUser($this->user);
1165
 
1166
        $result = external::search_competencies('short', $framework->id);
1167
        $result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);
1168
 
1169
        $this->assertEquals(count($result), 3);
1170
        $result = (object) $result[0];
1171
 
1172
        $this->assertGreaterThan(0, $result->timecreated);
1173
        $this->assertGreaterThan(0, $result->timemodified);
1174
        $this->assertEquals($this->creator->id, $result->usermodified);
1175
        $this->assertEquals('shortname1', $result->shortname);
1176
        $this->assertEquals('idnumber1', $result->idnumber);
1177
        $this->assertEquals('description1', $result->description);
1178
    }
1179
 
1180
    /**
1181
     * Test plans creation and updates.
1182
     */
11 efrain 1183
    public function test_create_and_update_plans(): void {
1 efrain 1184
        $syscontext = \context_system::instance();
1185
 
1186
        $this->setUser($this->creator);
1187
        $plan0 = $this->create_plan(1, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);
1188
 
1189
        $this->setUser($this->user);
1190
 
1191
        try {
1192
            $plan1 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1193
            $this->fail('Exception expected due to not permissions to create draft plans');
1194
        } catch (\moodle_exception $e) {
1195
            $this->assertEquals('nopermissions', $e->errorcode);
1196
        }
1197
 
1198
        assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1199
        accesslib_clear_all_caches_for_unit_testing();
1200
 
1201
        $this->setUser($this->user);
1202
 
1203
        $plan2 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1204
 
1205
        // Basic update on the plan.
1206
        $this->assertNotEquals('Updated plan 2 name', $plan2->name);
1207
        $plan2 = external::update_plan(['id' => $plan2->id, 'name' => 'Updated plan 2 name']);
1208
        $this->assertEquals('Updated plan 2 name', $plan2->name);
1209
 
1210
        try {
1211
            $plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1212
            $this->fail('Exception expected due to not permissions to create active plans');
1213
        } catch (\moodle_exception $e) {
1214
            $this->assertEquals('nopermissions', $e->errorcode);
1215
        }
1216
        try {
1217
            $plan3 = $this->update_plan($plan2->id, 4, $this->user->id, 0, plan::STATUS_COMPLETE, 0);
1218
            $this->fail('We cannot complete a plan using api::update_plan().');
1219
        } catch (\coding_exception $e) {
1220
            $this->assertTrue(true);
1221
        }
1222
 
1223
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1224
        accesslib_clear_all_caches_for_unit_testing();
1225
 
1226
        $plan3 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1227
        try {
1228
            $plan4 = $this->create_plan(6, $this->creator->id, 0, plan::STATUS_COMPLETE, 0);
1229
            $this->fail('Plans cannot be created as complete.');
1230
        } catch (\coding_exception $e) {
1231
            $this->assertMatchesRegularExpression('/A plan cannot be created as complete./', $e->getMessage());
1232
        }
1233
 
1234
        try {
1235
            $plan0 = $this->update_plan($plan0->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1236
        } catch (\moodle_exception $e) {
1237
            $this->assertEquals('nopermissions', $e->errorcode);
1238
        }
1239
 
1240
        unassign_capability('moodle/competency:planmanageown', $this->userrole, $syscontext->id);
1241
        unassign_capability('moodle/competency:planmanageowndraft', $this->userrole, $syscontext->id);
1242
        accesslib_clear_all_caches_for_unit_testing();
1243
 
1244
        try {
1245
            // Cannot be updated even if they created it.
1246
            $this->update_plan($plan2->id, 1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1247
            $this->fail('The user can not update their own plan without permissions.');
1248
        } catch (\required_capability_exception $e) {
1249
            $this->assertMatchesRegularExpression('/Manage learning plans./', $e->getMessage());
1250
        }
1251
    }
1252
 
1253
    /**
1254
     * Test complete plan.
1255
     */
11 efrain 1256
    public function test_complete_plan(): void {
1 efrain 1257
        $syscontext = \context_system::instance();
1258
 
1259
        $this->setUser($this->creator);
1260
 
1261
        $this->setUser($this->user);
1262
 
1263
        assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1264
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1265
        accesslib_clear_all_caches_for_unit_testing();
1266
 
1267
        $this->setUser($this->user);
1268
 
1269
        $plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1270
 
1271
        $result = external::complete_plan($plan->id);
1272
        $this->assertTrue($result);
1273
    }
1274
 
1275
    /**
1276
     * Test reopen plan.
1277
     */
11 efrain 1278
    public function test_reopen_plan(): void {
1 efrain 1279
        $syscontext = \context_system::instance();
1280
 
1281
        $this->setUser($this->creator);
1282
 
1283
        $this->setUser($this->user);
1284
 
1285
        assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
1286
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1287
        accesslib_clear_all_caches_for_unit_testing();
1288
 
1289
        $this->setUser($this->user);
1290
 
1291
        $plan = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1292
        external::complete_plan($plan->id);
1293
 
1294
        $result = external::reopen_plan($plan->id);
1295
        $this->assertTrue($result);
1296
    }
1297
 
1298
    /**
1299
     * Test that we can read plans.
1300
     */
11 efrain 1301
    public function test_read_plans(): void {
1 efrain 1302
        global $OUTPUT;
1303
        $this->setUser($this->creator);
1304
 
1305
        $syscontext = \context_system::instance();
1306
 
1307
        $plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_DRAFT, 0);
1308
        $plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1309
        $plan3 = $this->create_plan(3, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1310
        external::complete_plan($plan3->id);
1311
        $plan3 = (object) external::read_plan($plan3->id);
1312
 
1313
        $data = external::read_plan($plan1->id);
1314
        $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1315
        $data = external::read_plan($plan2->id);
1316
        $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1317
        $data = external::read_plan($plan3->id);
1318
        $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1319
 
1320
        $this->setUser($this->user);
1321
 
1322
        // The normal user can not edit these plans.
1323
        $plan1->canmanage = false;
1324
        $plan2->canmanage = false;
1325
        $plan3->canmanage = false;
1326
        $plan1->canbeedited = false;
1327
        $plan2->canbeedited = false;
1328
        $plan3->canbeedited = false;
1329
        $plan1->canrequestreview = true;
1330
        $plan2->canrequestreview = true;
1331
        $plan3->canrequestreview = true;
1332
        $plan1->canreview = false;
1333
        $plan2->canreview = false;
1334
        $plan3->canreview = false;
1335
        $plan1->iscompleteallowed = false;
1336
        $plan2->iscompleteallowed = false;
1337
        $plan3->iscompleteallowed = false;
1338
        $plan1->isrequestreviewallowed = true;
1339
        $plan2->isrequestreviewallowed = true;
1340
        $plan3->isrequestreviewallowed = true;
1341
        $plan1->isapproveallowed = false;
1342
        $plan2->isapproveallowed = false;
1343
        $plan3->isapproveallowed = false;
1344
        $plan1->isunapproveallowed = false;
1345
        $plan2->isunapproveallowed = false;
1346
        $plan3->isunapproveallowed = false;
1347
        $plan3->isreopenallowed = false;
1348
        $plan1->commentarea['canpost'] = false;
1349
        $plan1->commentarea['canview'] = true;
1350
 
1351
        // Prevent the user from seeing their own non-draft plans.
1352
        assign_capability('moodle/competency:plancommentown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1353
        assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1354
        assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1355
        accesslib_clear_all_caches_for_unit_testing();
1356
 
1357
        $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1358
 
1359
        try {
1360
            external::read_plan($plan2->id);
1361
            $this->fail('Exception expected due to not permissions to read plan');
1362
        } catch (\moodle_exception $e) {
1363
            $this->assertEquals('nopermissions', $e->errorcode);
1364
        }
1365
        try {
1366
            external::read_plan($plan3->id);
1367
            $this->fail('Exception expected due to not permissions to read plan');
1368
        } catch (\moodle_exception $e) {
1369
            $this->assertEquals('nopermissions', $e->errorcode);
1370
        }
1371
 
1372
        // Allow user to see their plan.
1373
        assign_capability('moodle/competency:plancommentown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1374
        assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1375
        assign_capability('moodle/competency:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1376
        accesslib_clear_all_caches_for_unit_testing();
1377
 
1378
        $plan1->commentarea['canpost'] = true;
1379
        $plan1->commentarea['canview'] = true;
1380
        $plan2->commentarea['canpost'] = true;
1381
        $plan2->isrequestreviewallowed = false;
1382
        $plan3->commentarea['canpost'] = true;
1383
        $plan3->isrequestreviewallowed = false;
1384
        $plan1->commentarea['canpostorhascomments'] = true;
1385
        $plan2->commentarea['canpostorhascomments'] = true;
1386
        $plan3->commentarea['canpostorhascomments'] = true;
1387
 
1388
        $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1389
        $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1390
        $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1391
 
1392
        // Allow use to manage their own draft plan.
1393
        assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1394
        assign_capability('moodle/competency:planmanageown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1395
        assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1396
        accesslib_clear_all_caches_for_unit_testing();
1397
 
1398
        $plan1->canmanage = true;
1399
        $plan1->canbeedited = true;
1400
        $plan1->canrequestreview = true;
1401
        $plan1->isrequestreviewallowed = true;
1402
        $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1403
        try {
1404
            external::read_plan($plan2->id);
1405
            $this->fail('Exception expected due to not permissions to read plan');
1406
        } catch (\moodle_exception $e) {
1407
            $this->assertEquals('nopermissions', $e->errorcode);
1408
        }
1409
        try {
1410
            external::read_plan($plan3->id);
1411
            $this->fail('Exception expected due to not permissions to read plan');
1412
        } catch (\moodle_exception $e) {
1413
            $this->assertEquals('nopermissions', $e->errorcode);
1414
        }
1415
 
1416
        // Allow use to manage their plan.
1417
        assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1418
        assign_capability('moodle/competency:planmanageowndraft', CAP_PROHIBIT, $this->userrole, $syscontext->id, true);
1419
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id, true);
1420
        accesslib_clear_all_caches_for_unit_testing();
1421
 
1422
        $plan1->canmanage = false;
1423
        $plan1->canbeedited = false;
1424
        $plan1->canrequestreview = true;
1425
        $plan1->canreview = true;
1426
        $plan1->isrequestreviewallowed = true;
1427
        $plan1->isapproveallowed = true;
1428
        $plan1->iscompleteallowed = false;
1429
 
1430
        $plan2->canmanage = true;
1431
        $plan2->canbeedited = true;
1432
        $plan2->canreview = true;
1433
        $plan2->iscompleteallowed = true;
1434
        $plan2->isunapproveallowed = true;
1435
 
1436
        $plan3->canmanage = true;
1437
        $plan3->canreview = true;
1438
        $plan3->isreopenallowed = true;
1439
 
1440
        $this->assertEquals((array)$plan1, external::read_plan($plan1->id));
1441
        $this->assertEquals((array)$plan2, external::read_plan($plan2->id));
1442
        $this->assertEquals((array)$plan3, external::read_plan($plan3->id));
1443
    }
1444
 
11 efrain 1445
    public function test_delete_plans(): void {
1 efrain 1446
        $this->setUser($this->creator);
1447
 
1448
        $syscontext = \context_system::instance();
1449
 
1450
        $plan1 = $this->create_plan(1, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1451
        $plan2 = $this->create_plan(2, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1452
        $plan3 = $this->create_plan(3, $this->creator->id, 0, plan::STATUS_ACTIVE, 0);
1453
 
1454
        $this->assertTrue(external::delete_plan($plan1->id));
1455
 
1456
        unassign_capability('moodle/competency:planmanage', $this->creatorrole, $syscontext->id);
1457
        accesslib_clear_all_caches_for_unit_testing();
1458
 
1459
        try {
1460
            external::delete_plan($plan2->id);
1461
            $this->fail('Exception expected due to not permissions to manage plans');
1462
        } catch (\moodle_exception $e) {
1463
            $this->assertEquals('nopermissions', $e->errorcode);
1464
        }
1465
 
1466
        $this->setUser($this->user);
1467
 
1468
        // Can not delete plans created by other users.
1469
        try {
1470
            external::delete_plan($plan2->id);
1471
            $this->fail('Exception expected due to not permissions to manage plans');
1472
        } catch (\moodle_exception $e) {
1473
            $this->assertEquals('nopermissions', $e->errorcode);
1474
        }
1475
 
1476
        assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->userrole, $syscontext->id);
1477
        accesslib_clear_all_caches_for_unit_testing();
1478
 
1479
        $this->assertTrue(external::delete_plan($plan2->id));
1480
 
1481
        // Can not delete plans created for other users.
1482
        try {
1483
            external::delete_plan($plan3->id);
1484
            $this->fail('Exception expected due to not permissions to manage plans');
1485
        } catch (\moodle_exception $e) {
1486
            $this->assertEquals('nopermissions', $e->errorcode);
1487
        }
1488
 
1489
        $plan4 = $this->create_plan(4, $this->user->id, 0, plan::STATUS_ACTIVE, 0);
1490
        $this->assertTrue(external::delete_plan($plan4->id));
1491
    }
1492
 
11 efrain 1493
    public function test_delete_plan_removes_relations(): void {
1 efrain 1494
        $this->setAdminUser();
1495
        $dg = $this->getDataGenerator();
1496
        $lpg = $dg->get_plugin_generator('core_competency');
1497
 
1498
        $user = $dg->create_user();
1499
        $plan = $lpg->create_plan(array('userid' => $user->id));
1500
        $framework = $lpg->create_framework();
1501
        $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
1502
        $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
1503
        $comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
1504
        $pc1 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp1->get('id')));
1505
        $pc2 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp2->get('id')));
1506
        $pc3 = $lpg->create_plan_competency(array('planid' => $plan->get('id'), 'competencyid' => $comp3->get('id')));
1507
 
1508
        // Complete the plan to generate user_competency_plan entries.
1509
        api::complete_plan($plan);
1510
 
1511
        // Confirm the data we have.
1512
        $this->assertEquals(3, plan_competency::count_records(array('planid' => $plan->get('id'))));
1513
        $this->assertEquals(3, user_competency_plan::count_records(array('planid' => $plan->get('id'), 'userid' => $user->id)));
1514
 
1515
        // Delete the plan now.
1516
        api::delete_plan($plan->get('id'));
1517
        $this->assertEquals(0, plan_competency::count_records(array('planid' => $plan->get('id'))));
1518
        $this->assertEquals(0, user_competency_plan::count_records(array('planid' => $plan->get('id'), 'userid' => $user->id)));
1519
    }
1520
 
11 efrain 1521
    public function test_list_plan_competencies(): void {
1 efrain 1522
        $this->setUser($this->creator);
1523
 
1524
        $dg = $this->getDataGenerator();
1525
        $lpg = $dg->get_plugin_generator('core_competency');
1526
 
1527
        $f1 = $lpg->create_framework();
1528
        $f2 = $lpg->create_framework();
1529
 
1530
        $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
1531
        $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
1532
        $c1c = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
1533
        $c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));
1534
        $c2b = $lpg->create_competency(array('competencyframeworkid' => $f2->get('id')));
1535
 
1536
        $tpl = $lpg->create_template();
1537
        $lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1a->get('id')));
1538
        $lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1c->get('id')));
1539
        $lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c2b->get('id')));
1540
 
1541
        $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id')));
1542
 
1543
        $uc1a = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1a->get('id'),
1544
            'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $this->creator->id));
1545
        $uc1b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1b->get('id')));
1546
        $uc2b = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c2b->get('id'),
1547
            'grade' => 2, 'proficiency' => 1));
1548
        $ux1a = $lpg->create_user_competency(array('userid' => $this->creator->id, 'competencyid' => $c1a->get('id')));
1549
 
1550
        $result = external::list_plan_competencies($plan->get('id'));
1551
        $result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);
1552
 
1553
        $this->assertCount(3, $result);
1554
        $this->assertEquals($c1a->get('id'), $result[0]['competency']['id']);
1555
        $this->assertEquals($this->user->id, $result[0]['usercompetency']['userid']);
1556
        $this->assertArrayNotHasKey('usercompetencyplan', $result[0]);
1557
        $this->assertEquals($c1c->get('id'), $result[1]['competency']['id']);
1558
        $this->assertEquals($this->user->id, $result[1]['usercompetency']['userid']);
1559
        $this->assertArrayNotHasKey('usercompetencyplan', $result[1]);
1560
        $this->assertEquals($c2b->get('id'), $result[2]['competency']['id']);
1561
        $this->assertEquals($this->user->id, $result[2]['usercompetency']['userid']);
1562
        $this->assertArrayNotHasKey('usercompetencyplan', $result[2]);
1563
        $this->assertEquals(user_competency::STATUS_IN_REVIEW, $result[0]['usercompetency']['status']);
1564
        $this->assertEquals(null, $result[1]['usercompetency']['grade']);
1565
        $this->assertEquals(2, $result[2]['usercompetency']['grade']);
1566
        $this->assertEquals(1, $result[2]['usercompetency']['proficiency']);
1567
 
1568
        // Check the return values when the plan status is complete.
1569
        $completedplan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'),
1570
                'status' => plan::STATUS_COMPLETE));
1571
 
1572
        $uc1a = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1a->get('id'),
1573
                'planid' => $completedplan->get('id')));
1574
        $uc1b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c1c->get('id'),
1575
                'planid' => $completedplan->get('id')));
1576
        $uc2b = $lpg->create_user_competency_plan(array('userid' => $this->user->id, 'competencyid' => $c2b->get('id'),
1577
                'planid' => $completedplan->get('id'), 'grade' => 2, 'proficiency' => 1));
1578
        $ux1a = $lpg->create_user_competency_plan(array('userid' => $this->creator->id, 'competencyid' => $c1a->get('id'),
1579
                'planid' => $completedplan->get('id')));
1580
 
1581
        $result = external::list_plan_competencies($completedplan->get('id'));
1582
        $result = external::clean_returnvalue(external::list_plan_competencies_returns(), $result);
1583
 
1584
        $this->assertCount(3, $result);
1585
        $this->assertEquals($c1a->get('id'), $result[0]['competency']['id']);
1586
        $this->assertEquals($this->user->id, $result[0]['usercompetencyplan']['userid']);
1587
        $this->assertArrayNotHasKey('usercompetency', $result[0]);
1588
        $this->assertEquals($c1c->get('id'), $result[1]['competency']['id']);
1589
        $this->assertEquals($this->user->id, $result[1]['usercompetencyplan']['userid']);
1590
        $this->assertArrayNotHasKey('usercompetency', $result[1]);
1591
        $this->assertEquals($c2b->get('id'), $result[2]['competency']['id']);
1592
        $this->assertEquals($this->user->id, $result[2]['usercompetencyplan']['userid']);
1593
        $this->assertArrayNotHasKey('usercompetency', $result[2]);
1594
        $this->assertEquals(null, $result[1]['usercompetencyplan']['grade']);
1595
        $this->assertEquals(2, $result[2]['usercompetencyplan']['grade']);
1596
        $this->assertEquals(1, $result[2]['usercompetencyplan']['proficiency']);
1597
    }
1598
 
11 efrain 1599
    public function test_add_competency_to_template(): void {
1 efrain 1600
        $this->setUser($this->creator);
1601
 
1602
        $syscontext = \context_system::instance();
1603
 
1604
        // Create a template.
1605
        $template = $this->create_template(1, true);
1606
 
1607
        // Create a competency.
1608
        $framework = $this->create_competency_framework(1, true);
1609
        $competency = $this->create_competency(1, $framework->id);
1610
 
1611
        // Add the competency.
1612
        external::add_competency_to_template($template->id, $competency->id);
1613
 
1614
        // Check that it was added.
1615
        $this->assertEquals(1, external::count_competencies_in_template($template->id));
1616
 
1617
        // Unassign capability.
1618
        unassign_capability('moodle/competency:templatemanage', $this->creatorrole, $syscontext->id);
1619
        accesslib_clear_all_caches_for_unit_testing();
1620
 
1621
        // Check we can not add the competency now.
1622
        try {
1623
            external::add_competency_to_template($template->id, $competency->id);
1624
            $this->fail('Exception expected due to not permissions to manage template competencies');
1625
        } catch (\moodle_exception $e) {
1626
            $this->assertEquals('nopermissions', $e->errorcode);
1627
        }
1628
    }
1629
 
11 efrain 1630
    public function test_remove_competency_from_template(): void {
1 efrain 1631
        $syscontext = \context_system::instance();
1632
        $this->setUser($this->creator);
1633
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
1634
 
1635
        // Create a template.
1636
        $template = $this->create_template(1, true);
1637
 
1638
        // Create a competency.
1639
        $framework = $lpg->create_framework();
1640
        $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
1641
 
1642
        // Add the competency.
1643
        external::add_competency_to_template($template->id, $competency->get('id'));
1644
 
1645
        // Check that it was added.
1646
        $this->assertEquals(1, external::count_competencies_in_template($template->id));
1647
 
1648
        // Check that we can remove the competency.
1649
        external::remove_competency_from_template($template->id, $competency->get('id'));
1650
 
1651
        // Check that it was removed.
1652
        $this->assertEquals(0, external::count_competencies_in_template($template->id));
1653
 
1654
        // Unassign capability.
1655
        unassign_capability('moodle/competency:templatemanage', $this->creatorrole, $syscontext->id);
1656
        accesslib_clear_all_caches_for_unit_testing();
1657
 
1658
        // Check we can not remove the competency now.
1659
        try {
1660
            external::add_competency_to_template($template->id, $competency->get('id'));
1661
            $this->fail('Exception expected due to not permissions to manage template competencies');
1662
        } catch (\moodle_exception $e) {
1663
            $this->assertEquals('nopermissions', $e->errorcode);
1664
        }
1665
    }
1666
 
1667
    /**
1668
     * Test we can re-order competency frameworks.
1669
     */
11 efrain 1670
    public function test_reorder_template_competencies(): void {
1 efrain 1671
        $this->setUser($this->creator);
1672
 
1673
        $syscontext = \context_system::instance();
1674
        $onehour = time() + 60 * 60;
1675
 
1676
        // Create a template.
1677
        $template = $this->create_template(1, true);
1678
 
1679
        // Create a competency framework.
1680
        $framework = $this->create_competency_framework(1, true);
1681
 
1682
        // Create multiple competencies.
1683
        $competency1 = $this->create_competency(1, $framework->id);
1684
        $competency2 = $this->create_competency(2, $framework->id);
1685
        $competency3 = $this->create_competency(3, $framework->id);
1686
        $competency4 = $this->create_competency(4, $framework->id);
1687
 
1688
        // Add the competencies.
1689
        external::add_competency_to_template($template->id, $competency1->id);
1690
        external::add_competency_to_template($template->id, $competency2->id);
1691
        external::add_competency_to_template($template->id, $competency3->id);
1692
        external::add_competency_to_template($template->id, $competency4->id);
1693
 
1694
        // Test if removing competency from template don't create sortorder holes.
1695
        external::remove_competency_from_template($template->id, $competency3->id);
1696
        $templcomp4 = template_competency::get_record(array(
1697
            'templateid' => $template->id,
1698
            'competencyid' => $competency4->id
1699
        ));
1700
 
1701
        $this->assertEquals(2, $templcomp4->get('sortorder'));
1702
 
1703
        // This is a move up.
1704
        external::reorder_template_competency($template->id, $competency4->id, $competency2->id);
1705
        $result = external::list_competencies_in_template($template->id);
1706
        $result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);
1707
 
1708
        $r1 = (object) $result[0];
1709
        $r2 = (object) $result[1];
1710
        $r3 = (object) $result[2];
1711
 
1712
        $this->assertEquals($competency1->id, $r1->id);
1713
        $this->assertEquals($competency4->id, $r2->id);
1714
        $this->assertEquals($competency2->id, $r3->id);
1715
 
1716
        // This is a move down.
1717
        external::reorder_template_competency($template->id, $competency1->id, $competency4->id);
1718
        $result = external::list_competencies_in_template($template->id);
1719
        $result = external_api::clean_returnvalue(external::list_competencies_in_template_returns(), $result);
1720
 
1721
        $r1 = (object) $result[0];
1722
        $r2 = (object) $result[1];
1723
        $r3 = (object) $result[2];
1724
 
1725
        $this->assertEquals($competency4->id, $r1->id);
1726
        $this->assertEquals($competency1->id, $r2->id);
1727
        $this->assertEquals($competency2->id, $r3->id);
1728
 
1729
        $this->expectException('\required_capability_exception');
1730
        $this->setUser($this->user);
1731
        external::reorder_template_competency($template->id, $competency1->id, $competency2->id);
1732
    }
1733
 
1734
    /**
1735
     * Test we can duplicate learning plan template.
1736
     */
11 efrain 1737
    public function test_duplicate_learning_plan_template(): void {
1 efrain 1738
        $this->setUser($this->creator);
1739
 
1740
        $syscontext = \context_system::instance();
1741
        $onehour = time() + 60 * 60;
1742
 
1743
        // Create a template.
1744
        $template = $this->create_template(1, true);
1745
 
1746
        // Create a competency framework.
1747
        $framework = $this->create_competency_framework(1, true);
1748
 
1749
        // Create multiple competencies.
1750
        $competency1 = $this->create_competency(1, $framework->id);
1751
        $competency2 = $this->create_competency(2, $framework->id);
1752
        $competency3 = $this->create_competency(3, $framework->id);
1753
 
1754
        // Add the competencies.
1755
        external::add_competency_to_template($template->id, $competency1->id);
1756
        external::add_competency_to_template($template->id, $competency2->id);
1757
        external::add_competency_to_template($template->id, $competency3->id);
1758
 
1759
        // Duplicate the learning plan template.
1760
        $duplicatedtemplate = external::duplicate_template($template->id);
1761
 
1762
        $result = external::list_competencies_in_template($template->id);
1763
        $resultduplicated = external::list_competencies_in_template($duplicatedtemplate->id);
1764
 
1765
        $this->assertEquals(count($result), count($resultduplicated));
1766
        $this->assertStringContainsString($template->shortname, $duplicatedtemplate->shortname);
1767
        $this->assertEquals($duplicatedtemplate->description, $template->description);
1768
        $this->assertEquals($duplicatedtemplate->descriptionformat, $template->descriptionformat);
1769
        $this->assertEquals($duplicatedtemplate->visible, $template->visible);
1770
    }
1771
 
1772
    /**
1773
     * Test that we can return scale values for a scale with the scale ID.
1774
     */
11 efrain 1775
    public function test_get_scale_values(): void {
1 efrain 1776
        global $DB;
1777
 
1778
        $this->setUser($this->creator);
1779
 
1780
        // Create a scale.
1781
        $record = new \stdClass();
1782
        $record->courseid = 0;
1783
        $record->userid = $this->creator->id;
1784
        $record->name = 'Test scale';
1785
        $record->scale = 'Poor, Not good, Okay, Fine, Excellent';
1786
        $record->description = '<p>Test scale description.</p>';
1787
        $record->descriptionformat = 1;
1788
        $record->timemodified = time();
1789
        $scaleid = $DB->insert_record('scale', $record);
1790
        // Expected return value.
1791
        $expected = array(array(
1792
                'id' => 1,
1793
                'name' => 'Poor'
1794
            ), array(
1795
                'id' => 2,
1796
                'name' => 'Not good'
1797
            ), array(
1798
                'id' => 3,
1799
                'name' => 'Okay'
1800
            ), array(
1801
                'id' => 4,
1802
                'name' => 'Fine'
1803
            ), array(
1804
                'id' => 5,
1805
                'name' => 'Excellent'
1806
            )
1807
        );
1808
        // Call the webservice.
1809
        $result = external::get_scale_values($scaleid);
1810
        $this->assertEquals($expected, $result);
1811
    }
1812
 
1813
    /**
1814
     * Create a template.
1815
     */
11 efrain 1816
    public function test_create_template(): void {
1 efrain 1817
        $syscontextid = \context_system::instance()->id;
1818
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
1819
 
1820
        // A user without permission.
1821
        $this->setUser($this->user);
1822
        try {
1823
            $result = $this->create_template(1, true);
1824
            $this->fail('Invalid permissions');
1825
        } catch (\required_capability_exception $e) {
1826
            // All good.
1827
        }
1828
 
1829
        // A user without permission in a category.
1830
        $this->setUser($this->catuser);
1831
        try {
1832
            $result = $this->create_template(1, false);
1833
            $this->fail('Invalid permissions');
1834
        } catch (\required_capability_exception $e) {
1835
            // All good.
1836
        }
1837
 
1838
        // A user with permissions in the system.
1839
        $this->setUser($this->creator);
1840
        $result = $this->create_template(1, true);
1841
        $this->assertEquals('shortname1', $result->shortname);
1842
        $this->assertEquals($syscontextid, $result->contextid);
1843
        $this->assertNotEmpty($result->id);
1844
 
1845
        $result = $this->create_template(2, false);
1846
        $this->assertEquals('shortname2', $result->shortname);
1847
        $this->assertEquals($catcontextid, $result->contextid);
1848
        $this->assertNotEmpty($result->id);
1849
 
1850
        // A user with permissions in the category.
1851
        $this->setUser($this->catcreator);
1852
        try {
1853
            $result = $this->create_template(3, true);
1854
            $this->fail('Invalid permissions');
1855
        } catch (\required_capability_exception $e) {
1856
            // All good.
1857
        }
1858
 
1859
        $result = $this->create_template(3, false);
1860
        $this->assertEquals('shortname3', $result->shortname);
1861
        $this->assertEquals($catcontextid, $result->contextid);
1862
        $this->assertNotEmpty($result->id);
1863
    }
1864
 
1865
    /**
1866
     * Read a template.
1867
     */
11 efrain 1868
    public function test_read_template(): void {
1 efrain 1869
        $syscontextid = \context_system::instance()->id;
1870
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
1871
 
1872
        // Set a due date for the next year.
1873
        $date = new \DateTime('now');
1874
        $date->modify('+1 year');
1875
        $duedate = $date->getTimestamp();
1876
 
1877
        // Creating two templates.
1878
        $this->setUser($this->creator);
1879
        $systemplate = $this->create_template(1, true);
1880
        $cattemplate = $this->create_template(2, false);
1881
 
1882
        // User without permissions to read in system.
1883
        assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
1884
        accesslib_clear_all_caches_for_unit_testing();
1885
        $this->setUser($this->user);
1886
        $this->assertFalse(has_capability('moodle/competency:templateview', \context_system::instance()));
1887
        try {
1888
            external::read_template($systemplate->id);
1889
            $this->fail('Invalid permissions');
1890
        } catch (\required_capability_exception $e) {
1891
            // All good.
1892
        }
1893
        try {
1894
            external::read_template($cattemplate->id);
1895
            $this->fail('Invalid permissions');
1896
        } catch (\required_capability_exception $e) {
1897
            // All good.
1898
        }
1899
 
1900
        // User with permissions to read in a category.
1901
        assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
1902
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
1903
        accesslib_clear_all_caches_for_unit_testing();
1904
        $this->assertFalse(has_capability('moodle/competency:templateview', \context_system::instance()));
1905
        $this->assertTrue(has_capability('moodle/competency:templateview', \context_coursecat::instance($this->category->id)));
1906
        try {
1907
            external::read_template($systemplate->id);
1908
            $this->fail('Invalid permissions');
1909
        } catch (\required_capability_exception $e) {
1910
            // All good.
1911
        }
1912
 
1913
        $result = external::read_template($cattemplate->id);
1914
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1915
        $this->assertEquals($cattemplate->id, $result['id']);
1916
        $this->assertEquals('shortname2', $result['shortname']);
1917
        $this->assertEquals('description2', $result['description']);
1918
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1919
        $this->assertEquals(1, $result['visible']);
1920
        $this->assertEquals(0, $result['duedate']);
1921
        $this->assertEquals(userdate(0), $result['duedateformatted']);
1922
 
1923
        // User with permissions to read in the system.
1924
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
1925
        accesslib_clear_all_caches_for_unit_testing();
1926
        $this->assertTrue(has_capability('moodle/competency:templateview', \context_system::instance()));
1927
        $result = external::read_template($systemplate->id);
1928
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1929
        $this->assertEquals($systemplate->id, $result['id']);
1930
        $this->assertEquals('shortname1', $result['shortname']);
1931
        $this->assertEquals('description1', $result['description']);
1932
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1933
        $this->assertEquals(true, $result['visible']);
1934
        $this->assertEquals(0, $result['duedate']);
1935
        $this->assertEquals(userdate(0), $result['duedateformatted']);
1936
 
1937
        $result = external::read_template($cattemplate->id);
1938
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1939
        $this->assertEquals($cattemplate->id, $result['id']);
1940
        $this->assertEquals('shortname2', $result['shortname']);
1941
        $this->assertEquals('description2', $result['description']);
1942
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1943
        $this->assertEquals(true, $result['visible']);
1944
        $this->assertEquals(0, $result['duedate']);
1945
        $this->assertEquals(userdate(0), $result['duedateformatted']);
1946
    }
1947
 
1948
    /**
1949
     * Update a template.
1950
     */
11 efrain 1951
    public function test_update_template(): void {
1 efrain 1952
        $syscontextid = \context_system::instance()->id;
1953
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
1954
 
1955
        // Set a due date for the next year.
1956
        $date = new \DateTime('now');
1957
        $date->modify('+1 year');
1958
        $duedate = $date->getTimestamp();
1959
 
1960
        // Creating two templates.
1961
        $this->setUser($this->creator);
1962
        $systemplate = $this->create_template(1, true);
1963
        $cattemplate = $this->create_template(2, false);
1964
 
1965
        // Trying to update in a without permissions.
1966
        $this->setUser($this->user);
1967
        try {
1968
            $this->update_template($systemplate->id, 3);
1969
            $this->fail('Invalid permissions');
1970
        } catch (\required_capability_exception $e) {
1971
            // All good.
1972
        }
1973
 
1974
        try {
1975
            $this->update_template($cattemplate->id, 3);
1976
            $this->fail('Invalid permissions');
1977
        } catch (\required_capability_exception $e) {
1978
            // All good.
1979
        }
1980
 
1981
        // User with permissions to update in category.
1982
        $this->setUser($this->catcreator);
1983
        try {
1984
            $this->update_template($systemplate->id, 3);
1985
            $this->fail('Invalid permissions');
1986
        } catch (\required_capability_exception $e) {
1987
            // All good.
1988
        }
1989
 
1990
        $result = $this->update_template($cattemplate->id, 3);
1991
        $this->assertTrue($result);
1992
        $result = external::read_template($cattemplate->id);
1993
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
1994
        $this->assertEquals($cattemplate->id, $result['id']);
1995
        $this->assertEquals('shortname3', $result['shortname']);
1996
        $this->assertEquals("description3", $result['description']);
1997
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
1998
        $this->assertEquals(true, $result['visible']);
1999
        $this->assertEquals(0, $result['duedate']);
2000
        $this->assertEquals(userdate(0), $result['duedateformatted']);
2001
 
2002
        // User with permissions to update in the system.
2003
        $this->setUser($this->creator);
2004
        $result = $this->update_template($systemplate->id, 4);
2005
        $this->assertTrue($result);
2006
        $result = external::read_template($systemplate->id);
2007
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
2008
        $this->assertEquals($systemplate->id, $result['id']);
2009
        $this->assertEquals('shortname4', $result['shortname']);
2010
        $this->assertEquals('description4', $result['description']);
2011
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
2012
        $this->assertEquals(true, $result['visible']);
2013
        $this->assertEquals(0, $result['duedate']);
2014
        $this->assertEquals(userdate(0), $result['duedateformatted']);
2015
 
2016
        $result = $this->update_template($cattemplate->id, 5);
2017
        $this->assertTrue($result);
2018
        $result = external::read_template($cattemplate->id);
2019
        $result = external_api::clean_returnvalue(external::read_template_returns(), $result);
2020
        $this->assertEquals($cattemplate->id, $result['id']);
2021
        $this->assertEquals('shortname5', $result['shortname']);
2022
        $this->assertEquals('description5', $result['description']);
2023
        $this->assertEquals(FORMAT_HTML, $result['descriptionformat']);
2024
        $this->assertEquals(1, $result['visible']);
2025
        $this->assertEquals(0, $result['duedate']);
2026
        $this->assertEquals(userdate(0), $result['duedateformatted']);
2027
    }
2028
 
2029
    /**
2030
     * Delete a template.
2031
     */
11 efrain 2032
    public function test_delete_template(): void {
1 efrain 2033
        global $DB;
2034
        $syscontextid = \context_system::instance()->id;
2035
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
2036
 
2037
        // Creating a few templates.
2038
        $this->setUser($this->creator);
2039
        $sys1 = $this->create_template(1, true);
2040
        $cat1 = $this->create_template(2, false);
2041
        $cat2 = $this->create_template(3, false);
2042
        $this->assertTrue($DB->record_exists(template::TABLE, array('id' => $sys1->id)));
2043
        $this->assertTrue($DB->record_exists(template::TABLE, array('id' => $cat1->id)));
2044
        $this->assertTrue($DB->record_exists(template::TABLE, array('id' => $cat2->id)));
2045
 
2046
        // User without permissions.
2047
        $this->setUser($this->user);
2048
        try {
2049
            external::delete_template($sys1->id);
2050
            $this->fail('Invalid permissions');
2051
        } catch (\required_capability_exception $e) {
2052
            // All good.
2053
        }
2054
        try {
2055
            external::delete_template($cat1->id);
2056
            $this->fail('Invalid permissions');
2057
        } catch (\required_capability_exception $e) {
2058
            // All good.
2059
        }
2060
 
2061
        // User with category permissions.
2062
        $this->setUser($this->catcreator);
2063
        try {
2064
            external::delete_template($sys1->id);
2065
            $this->fail('Invalid permissions');
2066
        } catch (\required_capability_exception $e) {
2067
            // All good.
2068
        }
2069
 
2070
        $result = external::delete_template($cat1->id);
2071
        $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2072
        $this->assertTrue($result);
2073
        $this->assertFalse($DB->record_exists(template::TABLE, array('id' => $cat1->id)));
2074
 
2075
        // User with system permissions.
2076
        $this->setUser($this->creator);
2077
        $result = external::delete_template($sys1->id);
2078
        $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2079
        $this->assertTrue($result);
2080
        $result = external::delete_template($cat2->id);
2081
        $result = external_api::clean_returnvalue(external::delete_template_returns(), $result);
2082
        $this->assertTrue($result);
2083
        $this->assertFalse($DB->record_exists(template::TABLE, array('id' => $sys1->id)));
2084
        $this->assertFalse($DB->record_exists(template::TABLE, array('id' => $cat2->id)));
2085
    }
2086
 
2087
    /**
2088
     * List templates.
2089
     */
11 efrain 2090
    public function test_list_templates(): void {
1 efrain 2091
        $syscontextid = \context_system::instance()->id;
2092
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
2093
 
2094
        // Creating a few templates.
2095
        $this->setUser($this->creator);
2096
        $sys1 = $this->create_template(1, true);
2097
        $sys2 = $this->create_template(2, true);
2098
        $cat1 = $this->create_template(3, false);
2099
        $cat2 = $this->create_template(4, false);
2100
 
2101
        // User without permission.
2102
        $this->setUser($this->user);
2103
        assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
2104
        accesslib_clear_all_caches_for_unit_testing();
2105
        try {
2106
            external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);
2107
            $this->fail('Invalid permissions');
2108
        } catch (\required_capability_exception $e) {
2109
            // All good.
2110
        }
2111
 
2112
        // User with category permissions.
2113
        assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
2114
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
2115
        accesslib_clear_all_caches_for_unit_testing();
2116
        $result = external::list_templates('id', 'ASC', 0, 10, array('contextid' => $syscontextid), 'children', false);
2117
        $result = external_api::clean_returnvalue(external::list_templates_returns(), $result);
2118
        $this->assertCount(2, $result);
2119
        $this->assertEquals($cat1->id, $result[0]['id']);
2120
        $this->assertEquals($cat2->id, $result[1]['id']);
2121
 
2122
        // User with system permissions.
2123
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
2124
        accesslib_clear_all_caches_for_unit_testing();
2125
        $result = external::list_templates('id', 'DESC', 0, 3, array('contextid' => $catcontextid), 'parents', false);
2126
        $result = external_api::clean_returnvalue(external::list_templates_returns(), $result);
2127
        $this->assertCount(3, $result);
2128
        $this->assertEquals($cat2->id, $result[0]['id']);
2129
        $this->assertEquals($cat1->id, $result[1]['id']);
2130
        $this->assertEquals($sys2->id, $result[2]['id']);
2131
    }
2132
 
2133
    /**
2134
     * List templates using competency.
2135
     */
11 efrain 2136
    public function test_list_templates_using_competency(): void {
1 efrain 2137
        $this->setUser($this->creator);
2138
 
2139
        // Create a template.
2140
        $template1 = $this->create_template(1, true);
2141
        $template2 = $this->create_template(2, true);
2142
        $template3 = $this->create_template(3, true);
2143
        $template4 = $this->create_template(4, true);
2144
 
2145
        // Create a competency.
2146
        $framework = $this->create_competency_framework(1, true);
2147
        $competency1 = $this->create_competency(1, $framework->id);
2148
        $competency2 = $this->create_competency(2, $framework->id);
2149
 
2150
        // Add the competency.
2151
        external::add_competency_to_template($template1->id, $competency1->id);
2152
        external::add_competency_to_template($template2->id, $competency1->id);
2153
        external::add_competency_to_template($template3->id, $competency1->id);
2154
 
2155
        external::add_competency_to_template($template4->id, $competency2->id);
2156
 
2157
        $listcomp1 = external::list_templates_using_competency($competency1->id);
2158
        $listcomp2 = external::list_templates_using_competency($competency2->id);
2159
 
2160
        // Test count_templates_using_competency.
2161
        $counttempcomp1 = external::count_templates_using_competency($competency1->id);
2162
        $counttempcomp2 = external::count_templates_using_competency($competency2->id);
2163
 
2164
        $comptemp1 = $listcomp1[0];
2165
        $comptemp2 = $listcomp1[1];
2166
        $comptemp3 = $listcomp1[2];
2167
 
2168
        $comptemp4 = $listcomp2[0];
2169
 
2170
        $this->assertCount(3, $listcomp1);
2171
        $this->assertCount(1, $listcomp2);
2172
        $this->assertEquals(3, $counttempcomp1);
2173
        $this->assertEquals(1, $counttempcomp2);
2174
        $this->assertEquals($template1->id, $comptemp1->id);
2175
        $this->assertEquals($template2->id, $comptemp2->id);
2176
        $this->assertEquals($template3->id, $comptemp3->id);
2177
        $this->assertEquals($template4->id, $comptemp4->id);
2178
    }
2179
 
11 efrain 2180
    public function test_count_templates(): void {
1 efrain 2181
        $syscontextid = \context_system::instance()->id;
2182
        $catcontextid = \context_coursecat::instance($this->category->id)->id;
2183
 
2184
        // Creating a few templates.
2185
        $this->setUser($this->creator);
2186
        $sys1 = $this->create_template(1, true);
2187
        $sys2 = $this->create_template(2, true);
2188
        $cat1 = $this->create_template(3, false);
2189
        $cat2 = $this->create_template(4, false);
2190
        $cat3 = $this->create_template(5, false);
2191
 
2192
        // User without permission.
2193
        $this->setUser($this->user);
2194
        assign_capability('moodle/competency:templateview', CAP_PROHIBIT, $this->userrole, $syscontextid, true);
2195
        accesslib_clear_all_caches_for_unit_testing();
2196
        try {
2197
            external::count_templates(array('contextid' => $syscontextid), 'children');
2198
            $this->fail('Invalid permissions');
2199
        } catch (\required_capability_exception $e) {
2200
            // All good.
2201
        }
2202
 
2203
        // User with category permissions.
2204
        assign_capability('moodle/competency:templateview', CAP_PREVENT, $this->userrole, $syscontextid, true);
2205
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $catcontextid, true);
2206
        accesslib_clear_all_caches_for_unit_testing();
2207
        $result = external::count_templates(array('contextid' => $syscontextid), 'children');
2208
        $result = external_api::clean_returnvalue(external::count_templates_returns(), $result);
2209
        $this->assertEquals(3, $result);
2210
 
2211
        // User with system permissions.
2212
        assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontextid, true);
2213
        accesslib_clear_all_caches_for_unit_testing();
2214
        $result = external::count_templates(array('contextid' => $catcontextid), 'parents');
2215
        $result = external_api::clean_returnvalue(external::count_templates_returns(), $result);
2216
        $this->assertEquals(5, $result);
2217
    }
2218
 
2219
    /**
2220
     * Test that we can add related competencies.
2221
     *
2222
     * @return void
2223
     */
11 efrain 2224
    public function test_add_related_competency(): void {
1 efrain 2225
        global $DB;
2226
        $this->setUser($this->creator);
2227
 
2228
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2229
        $framework = $lpg->create_framework();
2230
        $framework2 = $lpg->create_framework();
2231
        $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2232
        $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2233
        $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2234
        $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework2->get('id')));
2235
 
2236
        // The lower one always as competencyid.
2237
        $result = external::add_related_competency($competency1->get('id'), $competency2->get('id'));
2238
        $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2239
        $this->assertTrue($result);
2240
        $this->assertTrue($DB->record_exists_select(
2241
            related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2242
            array(
2243
                'cid' => $competency1->get('id'),
2244
                'rid' => $competency2->get('id')
2245
            )
2246
        ));
2247
        $this->assertFalse($DB->record_exists_select(
2248
            related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2249
            array(
2250
                'cid' => $competency2->get('id'),
2251
                'rid' => $competency1->get('id')
2252
            )
2253
        ));
2254
 
2255
        $result = external::add_related_competency($competency3->get('id'), $competency1->get('id'));
2256
        $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2257
        $this->assertTrue($result);
2258
        $this->assertTrue($DB->record_exists_select(
2259
            related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2260
            array(
2261
                'cid' => $competency1->get('id'),
2262
                'rid' => $competency3->get('id')
2263
            )
2264
        ));
2265
        $this->assertFalse($DB->record_exists_select(
2266
            related_competency::TABLE, 'competencyid = :cid AND relatedcompetencyid = :rid',
2267
            array(
2268
                'cid' => $competency3->get('id'),
2269
                'rid' => $competency1->get('id')
2270
            )
2271
        ));
2272
 
2273
        // We can not allow a duplicate relation, not even in the other direction.
2274
        $this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,
2275
            'competencyid = :cid AND relatedcompetencyid = :rid',
2276
            array('cid' => $competency1->get('id'), 'rid' => $competency2->get('id'))));
2277
        $this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,
2278
            'competencyid = :cid AND relatedcompetencyid = :rid',
2279
            array('rid' => $competency1->get('id'), 'cid' => $competency2->get('id'))));
2280
        $result = external::add_related_competency($competency2->get('id'), $competency1->get('id'));
2281
        $result = external_api::clean_returnvalue(external::add_related_competency_returns(), $result);
2282
        $this->assertTrue($result);
2283
        $this->assertEquals(1, $DB->count_records_select(related_competency::TABLE,
2284
            'competencyid = :cid AND relatedcompetencyid = :rid',
2285
            array('cid' => $competency1->get('id'), 'rid' => $competency2->get('id'))));
2286
        $this->assertEquals(0, $DB->count_records_select(related_competency::TABLE,
2287
            'competencyid = :cid AND relatedcompetencyid = :rid',
2288
            array('rid' => $competency1->get('id'), 'cid' => $competency2->get('id'))));
2289
 
2290
        // Check that we cannot create links across frameworks.
2291
        try {
2292
            external::add_related_competency($competency1->get('id'), $competency4->get('id'));
2293
            $this->fail('Exception expected due mis-use of shared competencies');
2294
        } catch (invalid_persistent_exception $e) {
2295
            // Yay!
2296
        }
2297
 
2298
        // User without permission.
2299
        $this->setUser($this->user);
2300
 
2301
        // Check we can not add the related competency now.
2302
        try {
2303
            external::add_related_competency($competency1->get('id'), $competency3->get('id'));
2304
            $this->fail('Exception expected due to not permissions to manage template competencies');
2305
        } catch (\moodle_exception $e) {
2306
            $this->assertEquals('nopermissions', $e->errorcode);
2307
        }
2308
 
2309
    }
2310
 
2311
    /**
2312
     * Test that we can remove related competencies.
2313
     *
2314
     * @return void
2315
     */
11 efrain 2316
    public function test_remove_related_competency(): void {
1 efrain 2317
        $this->setUser($this->creator);
2318
 
2319
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2320
        $framework = $lpg->create_framework();
2321
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2322
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2323
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2324
        $rc1 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c2->get('id')));
2325
        $rc2 = $lpg->create_related_competency(array('competencyid' => $c2->get('id'), 'relatedcompetencyid' => $c3->get('id')));
2326
 
2327
        $this->assertEquals(2, related_competency::count_records());
2328
 
2329
        // Returns false when the relation does not exist.
2330
        $result = external::remove_related_competency($c1->get('id'), $c3->get('id'));
2331
        $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2332
        $this->assertFalse($result);
2333
 
2334
        // Returns true on success.
2335
        $result = external::remove_related_competency($c2->get('id'), $c3->get('id'));
2336
        $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2337
        $this->assertTrue($result);
2338
        $this->assertEquals(1, related_competency::count_records());
2339
 
2340
        // We don't need to specify competencyid and relatedcompetencyid in the right order.
2341
        $result = external::remove_related_competency($c2->get('id'), $c1->get('id'));
2342
        $result = external_api::clean_returnvalue(external::remove_related_competency_returns(), $result);
2343
        $this->assertTrue($result);
2344
        $this->assertEquals(0, related_competency::count_records());
2345
    }
2346
 
2347
    /**
2348
     * Test that we can search and include related competencies.
2349
     *
2350
     * @return void
2351
     */
11 efrain 2352
    public function test_search_competencies_including_related(): void {
1 efrain 2353
        $this->setUser($this->creator);
2354
 
2355
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2356
        $framework = $lpg->create_framework();
2357
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2358
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2359
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2360
        $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2361
        $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2362
 
2363
        // We have 1-2, 1-3, 2-4, and no relation between 2-3 nor 1-4 nor 5.
2364
        $rc12 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c2->get('id')));
2365
        $rc13 = $lpg->create_related_competency(array('competencyid' => $c1->get('id'), 'relatedcompetencyid' => $c3->get('id')));
2366
        $rc24 = $lpg->create_related_competency(array('competencyid' => $c2->get('id'), 'relatedcompetencyid' => $c4->get('id')));
2367
 
2368
        $result = external::search_competencies('comp', $framework->get('id'), true);
2369
        $result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);
2370
 
2371
        $this->assertCount(5, $result);
2372
 
2373
    }
2374
 
2375
    /**
2376
     * Test that we can add competency to plan if we have the right capability.
2377
     *
2378
     * @return void
2379
     */
11 efrain 2380
    public function test_add_competency_to_plan(): void {
1 efrain 2381
        $this->resetAfterTest(true);
2382
        $dg = $this->getDataGenerator();
2383
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2384
        $usermanage = $dg->create_user();
2385
        $user = $dg->create_user();
2386
 
2387
        $syscontext = \context_system::instance();
2388
 
2389
        // Creating specific roles.
2390
        $managerole = $dg->create_role(array(
2391
            'name' => 'User manage',
2392
            'shortname' => 'manage'
2393
        ));
2394
 
2395
        assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2396
        assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);
2397
 
2398
        $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2399
 
2400
        $this->setUser($usermanage);
2401
        $plan = array (
2402
            'userid' => $usermanage->id,
2403
            'status' => \core_competency\plan::STATUS_ACTIVE
2404
        );
2405
        $pl1 = $lpg->create_plan($plan);
2406
        $framework = $lpg->create_framework();
2407
        $competency = $lpg->create_competency(
2408
                array('competencyframeworkid' => $framework->get('id'))
2409
                );
2410
        $this->assertTrue(external::add_competency_to_plan($pl1->get('id'), $competency->get('id')));
2411
 
2412
        // A competency cannot be added to plan based on template.
2413
        $template = $lpg->create_template();
2414
        $plan = array (
2415
            'userid' => $usermanage->id,
2416
            'status' => \core_competency\plan::STATUS_ACTIVE,
2417
            'templateid' => $template->get('id')
2418
        );
2419
        $pl2 = $lpg->create_plan($plan);
2420
        try {
2421
            external::add_competency_to_plan($pl2->get('id'), $competency->get('id'));
2422
            $this->fail('A competency cannot be added to plan based on template');
2423
        } catch (\coding_exception $ex) {
2424
            $this->assertTrue(true);
2425
        }
2426
 
2427
        // User without capability cannot add competency to a plan.
2428
        $this->setUser($user);
2429
        try {
2430
            external::add_competency_to_plan($pl1->get('id'), $competency->get('id'));
2431
            $this->fail('User without capability cannot add competency to a plan');
2432
        } catch (\required_capability_exception $ex) {
2433
            $this->assertTrue(true);
2434
        }
2435
    }
2436
 
2437
    /**
2438
     * Test that we can add competency to plan if we have the right capability.
2439
     *
2440
     * @return void
2441
     */
11 efrain 2442
    public function test_remove_competency_from_plan(): void {
1 efrain 2443
        $this->resetAfterTest(true);
2444
        $dg = $this->getDataGenerator();
2445
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2446
        $usermanage = $dg->create_user();
2447
        $user = $dg->create_user();
2448
 
2449
        $syscontext = \context_system::instance();
2450
 
2451
        // Creating specific roles.
2452
        $managerole = $dg->create_role(array(
2453
            'name' => 'User manage',
2454
            'shortname' => 'manage'
2455
        ));
2456
 
2457
        assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2458
        assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);
2459
 
2460
        $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2461
 
2462
        $this->setUser($usermanage);
2463
        $plan = array (
2464
            'userid' => $usermanage->id,
2465
            'status' => \core_competency\plan::STATUS_ACTIVE
2466
        );
2467
        $pl1 = $lpg->create_plan($plan);
2468
        $framework = $lpg->create_framework();
2469
        $competency = $lpg->create_competency(
2470
                array('competencyframeworkid' => $framework->get('id'))
2471
                );
2472
        $lpg->create_plan_competency(
2473
                array(
2474
                    'planid' => $pl1->get('id'),
2475
                    'competencyid' => $competency->get('id')
2476
                    )
2477
                );
2478
        $this->assertTrue(external::remove_competency_from_plan($pl1->get('id'), $competency->get('id')));
2479
        $this->assertCount(0, $pl1->get_competencies());
2480
    }
2481
 
2482
    /**
2483
     * Test that we can add competency to plan if we have the right capability.
2484
     *
2485
     * @return void
2486
     */
11 efrain 2487
    public function test_reorder_plan_competency(): void {
1 efrain 2488
        $this->resetAfterTest(true);
2489
        $dg = $this->getDataGenerator();
2490
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2491
        $usermanage = $dg->create_user();
2492
        $user = $dg->create_user();
2493
 
2494
        $syscontext = \context_system::instance();
2495
 
2496
        // Creating specific roles.
2497
        $managerole = $dg->create_role(array(
2498
            'name' => 'User manage',
2499
            'shortname' => 'manage'
2500
        ));
2501
 
2502
        assign_capability('moodle/competency:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
2503
        assign_capability('moodle/competency:planview', CAP_ALLOW, $managerole, $syscontext->id);
2504
 
2505
        $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
2506
 
2507
        $this->setUser($usermanage);
2508
        $plan = array (
2509
            'userid' => $usermanage->id,
2510
            'status' => \core_competency\plan::STATUS_ACTIVE
2511
        );
2512
        $pl1 = $lpg->create_plan($plan);
2513
        $framework = $lpg->create_framework();
2514
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2515
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2516
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2517
        $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2518
        $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2519
 
2520
        $lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c1->get('id'), 'sortorder' => 1));
2521
        $lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c2->get('id'), 'sortorder' => 2));
2522
        $lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c3->get('id'), 'sortorder' => 3));
2523
        $lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c4->get('id'), 'sortorder' => 4));
2524
        $lpg->create_plan_competency(array('planid' => $pl1->get('id'), 'competencyid' => $c5->get('id'), 'sortorder' => 5));
2525
 
2526
        // Test if removing competency from plan don't create sortorder holes.
2527
        external::remove_competency_from_plan($pl1->get('id'), $c4->get('id'));
2528
        $plancomp5 = plan_competency::get_record(array(
2529
            'planid' => $pl1->get('id'),
2530
            'competencyid' => $c5->get('id')
2531
        ));
2532
 
2533
        $this->assertEquals(3, $plancomp5->get('sortorder'));
2534
 
2535
        $this->assertTrue(external::reorder_plan_competency($pl1->get('id'), $c2->get('id'), $c5->get('id')));
2536
        $this->assertTrue(external::reorder_plan_competency($pl1->get('id'), $c3->get('id'), $c1->get('id')));
2537
        $plancompetencies = plan_competency::get_records(array('planid' => $pl1->get('id')), 'sortorder', 'ASC');
2538
        $plcmp1 = $plancompetencies[0];
2539
        $plcmp2 = $plancompetencies[1];
2540
        $plcmp3 = $plancompetencies[2];
2541
        $plcmp4 = $plancompetencies[3];
2542
 
2543
        $this->assertEquals($plcmp1->get('competencyid'), $c3->get('id'));
2544
        $this->assertEquals($plcmp2->get('competencyid'), $c1->get('id'));
2545
        $this->assertEquals($plcmp3->get('competencyid'), $c5->get('id'));
2546
        $this->assertEquals($plcmp4->get('competencyid'), $c2->get('id'));
2547
    }
2548
 
2549
    /**
2550
     * Test resolving sortorder when we creating competency.
2551
     */
11 efrain 2552
    public function test_fix_sortorder_when_creating_competency(): void {
1 efrain 2553
        $this->resetAfterTest(true);
2554
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2555
        $framework = $lpg->create_framework();
2556
 
2557
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2558
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'sortorder' => 20));
2559
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'sortorder' => 1));
2560
 
2561
        $this->assertEquals(0, $c1->get('sortorder'));
2562
        $this->assertEquals(1, $c2->get('sortorder'));
2563
        $this->assertEquals(2, $c3->get('sortorder'));
2564
    }
2565
 
2566
    /**
2567
     * Test resolving sortorder when we delete competency.
2568
     */
11 efrain 2569
    public function test_fix_sortorder_when_delete_competency(): void {
1 efrain 2570
        $this->resetAfterTest(true);
2571
        $this->setUser($this->creator);
2572
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2573
 
2574
        $framework = $lpg->create_framework();
2575
 
2576
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2577
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2578
        $c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2579
        $c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2580
        $c2c = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2581
        $c2d = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2582
 
2583
        $this->assertEquals(0, $c1->get('sortorder'));
2584
        $this->assertEquals(1, $c2->get('sortorder'));
2585
        $this->assertEquals(0, $c2a->get('sortorder'));
2586
        $this->assertEquals(1, $c2b->get('sortorder'));
2587
        $this->assertEquals(2, $c2c->get('sortorder'));
2588
        $this->assertEquals(3, $c2d->get('sortorder'));
2589
 
2590
        $result = external::delete_competency($c1->get('id'));
2591
        $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
2592
 
2593
        $c2->read();
2594
        $c2a->read();
2595
        $c2b->read();
2596
        $c2c->read();
2597
        $c2d->read();
2598
 
2599
        $this->assertEquals(0, $c2->get('sortorder'));
2600
        $this->assertEquals(0, $c2a->get('sortorder'));
2601
        $this->assertEquals(1, $c2b->get('sortorder'));
2602
        $this->assertEquals(2, $c2c->get('sortorder'));
2603
        $this->assertEquals(3, $c2d->get('sortorder'));
2604
 
2605
        $result = external::delete_competency($c2b->get('id'));
2606
        $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
2607
 
2608
        $c2->read();
2609
        $c2a->read();
2610
        $c2c->read();
2611
        $c2d->read();
2612
 
2613
        $this->assertEquals(0, $c2->get('sortorder'));
2614
        $this->assertEquals(0, $c2a->get('sortorder'));
2615
        $this->assertEquals(1, $c2c->get('sortorder'));
2616
        $this->assertEquals(2, $c2d->get('sortorder'));
2617
    }
2618
 
2619
    /**
2620
     * Test resolving sortorder when moving a competency.
2621
     */
11 efrain 2622
    public function test_fix_sortorder_when_moving_competency(): void {
1 efrain 2623
        $this->resetAfterTest(true);
2624
        $this->setUser($this->creator);
2625
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2626
 
2627
        $framework = $lpg->create_framework();
2628
 
2629
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2630
        $c1a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
2631
        $c1b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c1->get('id')));
2632
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2633
        $c2a = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2634
        $c2b = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id'), 'parentid' => $c2->get('id')));
2635
 
2636
        $this->assertEquals(0, $c1->get('sortorder'));
2637
        $this->assertEquals(0, $c1a->get('sortorder'));
2638
        $this->assertEquals(1, $c1b->get('sortorder'));
2639
        $this->assertEquals(1, $c2->get('sortorder'));
2640
        $this->assertEquals(0, $c2a->get('sortorder'));
2641
        $this->assertEquals(1, $c2b->get('sortorder'));
2642
 
2643
        $result = external::set_parent_competency($c2a->get('id'), $c1->get('id'));
2644
        $result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);
2645
 
2646
        $c1->read();
2647
        $c1a->read();
2648
        $c1b->read();
2649
        $c2->read();
2650
        $c2a->read();
2651
        $c2b->read();
2652
 
2653
        $this->assertEquals(0, $c1->get('sortorder'));
2654
        $this->assertEquals(0, $c1a->get('sortorder'));
2655
        $this->assertEquals(1, $c1b->get('sortorder'));
2656
        $this->assertEquals(2, $c2a->get('sortorder'));
2657
        $this->assertEquals(1, $c2->get('sortorder'));
2658
        $this->assertEquals(0, $c2b->get('sortorder'));
2659
 
2660
        // Move a root node.
2661
        $result = external::set_parent_competency($c2->get('id'), $c1b->get('id'));
2662
        $result = external_api::clean_returnvalue(external::set_parent_competency_returns(), $result);
2663
 
2664
        $c1->read();
2665
        $c1a->read();
2666
        $c1b->read();
2667
        $c2->read();
2668
        $c2a->read();
2669
        $c2b->read();
2670
 
2671
        $this->assertEquals(0, $c1->get('sortorder'));
2672
        $this->assertEquals(0, $c1a->get('sortorder'));
2673
        $this->assertEquals(1, $c1b->get('sortorder'));
2674
        $this->assertEquals(0, $c2->get('sortorder'));
2675
        $this->assertEquals(0, $c2b->get('sortorder'));
2676
        $this->assertEquals(2, $c2a->get('sortorder'));
2677
    }
2678
 
11 efrain 2679
    public function test_grade_competency(): void {
1 efrain 2680
        global $CFG;
2681
 
2682
        $this->setUser($this->creator);
2683
        $dg = $this->getDataGenerator();
2684
        $lpg = $dg->get_plugin_generator('core_competency');
2685
 
2686
        $f1 = $lpg->create_framework();
2687
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
2688
        $evidence = external::grade_competency($this->user->id, $c1->get('id'), 1, 'Evil note');
2689
 
2690
        $this->assertEquals('The competency rating was manually set.', $evidence->description);
2691
        $this->assertEquals('A', $evidence->gradename);
2692
        $this->assertEquals('Evil note', $evidence->note);
2693
 
2694
        $this->setUser($this->user);
2695
 
2696
        $this->expectException('\required_capability_exception');
2697
        $evidence = external::grade_competency($this->user->id, $c1->get('id'), 1);
2698
    }
2699
 
11 efrain 2700
    public function test_grade_competency_in_course(): void {
1 efrain 2701
        global $CFG;
2702
 
2703
        $this->setUser($this->creator);
2704
        $dg = $this->getDataGenerator();
2705
        $lpg = $dg->get_plugin_generator('core_competency');
2706
 
2707
        $course = $dg->create_course(['fullname' => 'Evil course']);
2708
        $dg->enrol_user($this->creator->id, $course->id, 'editingteacher');
2709
        $dg->enrol_user($this->user->id, $course->id, 'student');
2710
        $f1 = $lpg->create_framework();
2711
        $c1 = $lpg->create_competency(['competencyframeworkid' => $f1->get('id')]);
2712
        $lpg->create_course_competency(['courseid' => $course->id, 'competencyid' => $c1->get('id')]);
2713
 
2714
        $evidence = external::grade_competency_in_course($course->id, $this->user->id, $c1->get('id'), 1, 'Evil note');
2715
 
2716
        $this->assertEquals('The competency rating was manually set in the course \'Course: Evil course\'.', $evidence->description);
2717
        $this->assertEquals('A', $evidence->gradename);
2718
        $this->assertEquals('Evil note', $evidence->note);
2719
 
2720
        $this->setUser($this->user);
2721
 
2722
        $this->expectException('\required_capability_exception');
2723
        $evidence = external::grade_competency_in_course($course->id, $this->user->id, $c1->get('id'), 1);
2724
    }
2725
 
11 efrain 2726
    public function test_grade_competency_in_plan(): void {
1 efrain 2727
        global $CFG;
2728
 
2729
        $this->setUser($this->creator);
2730
 
2731
        $dg = $this->getDataGenerator();
2732
        $lpg = $dg->get_plugin_generator('core_competency');
2733
 
2734
        $f1 = $lpg->create_framework();
2735
 
2736
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
2737
 
2738
        $tpl = $lpg->create_template();
2739
        $lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1->get('id')));
2740
 
2741
        $plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'), 'name' => 'Evil'));
2742
 
2743
        $uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get('id')));
2744
 
2745
        $evidence = external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1, 'Evil note');
2746
 
2747
        $this->assertEquals('The competency rating was manually set in the learning plan \'Evil\'.', $evidence->description);
2748
        $this->assertEquals('A', $evidence->gradename);
2749
        $this->assertEquals('Evil note', $evidence->note);
2750
 
2751
        $this->setUser($this->user);
2752
 
2753
        $this->expectException('\required_capability_exception');
2754
        $evidence = external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1);
2755
    }
2756
 
2757
    /**
2758
     * Test update course competency settings.
2759
     */
11 efrain 2760
    public function test_update_course_competency_settings(): void {
1 efrain 2761
        $this->resetAfterTest(true);
2762
 
2763
        $dg = $this->getDataGenerator();
2764
 
2765
        $course = $dg->create_course();
2766
        $roleid = $dg->create_role();
2767
        $noobroleid = $dg->create_role();
2768
        $context = \context_course::instance($course->id);
2769
        $compmanager = $this->getDataGenerator()->create_user();
2770
        $compnoob = $this->getDataGenerator()->create_user();
2771
 
2772
        assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $roleid, $context->id, true);
2773
        assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $roleid, $context->id, true);
2774
        assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $noobroleid, $context->id, true);
2775
 
2776
        role_assign($roleid, $compmanager->id, $context->id);
2777
        role_assign($noobroleid, $compnoob->id, $context->id);
2778
        $dg->enrol_user($compmanager->id, $course->id, $roleid);
2779
        $dg->enrol_user($compnoob->id, $course->id, $noobroleid);
2780
 
2781
        $this->setUser($compmanager);
2782
 
2783
        // Start the test.
2784
        $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));
2785
 
2786
        $settings = course_competency_settings::get_by_courseid($course->id);
2787
 
2788
        $this->assertTrue((bool)$settings->get('pushratingstouserplans'));
2789
 
2790
        $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => false));
2791
 
2792
        $settings = course_competency_settings::get_by_courseid($course->id);
2793
 
2794
        $this->assertFalse((bool)$settings->get('pushratingstouserplans'));
2795
        $this->setUser($compnoob);
2796
 
2797
        $this->expectException('\required_capability_exception');
2798
        $result = external::update_course_competency_settings($course->id, array('pushratingstouserplans' => true));
2799
    }
2800
 
2801
    /**
2802
     * Test that we can list competencies with a filter.
2803
     *
2804
     * @return void
2805
     */
11 efrain 2806
    public function test_list_competencies_with_filter(): void {
1 efrain 2807
        $this->resetAfterTest(true);
2808
        $this->setAdminUser();
2809
        $dg = $this->getDataGenerator();
2810
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2811
 
2812
        $framework = $lpg->create_framework();
2813
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2814
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2815
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2816
        $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2817
        $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2818
 
2819
        // Test if removing competency from plan don't create sortorder holes.
2820
        $filters = [];
2821
        $sort = 'id';
2822
        $order = 'ASC';
2823
        $skip = 0;
2824
        $limit = 0;
2825
        $result = external::list_competencies($filters, $sort, $order, $skip, $limit);
2826
        $this->assertCount(5, $result);
2827
 
2828
        $result = external::list_competencies($filters, $sort, $order, 2, $limit);
2829
        $this->assertCount(3, $result);
2830
        $result = external::list_competencies($filters, $sort, $order, 2, 2);
2831
        $this->assertCount(2, $result);
2832
 
2833
        $filter = $result[0]->shortname;
2834
        $filters[0] = ['column' => 'shortname', 'value' => $filter];
2835
        $result = external::list_competencies($filters, $sort, $order, $skip, $limit);
2836
        $this->assertCount(1, $result);
2837
        $this->assertEquals($filter, $result[0]->shortname);
2838
    }
2839
 
2840
    /**
2841
     * Test that we can list competencies with a course module.
2842
     *
2843
     * @return void
2844
     */
11 efrain 2845
    public function test_list_competencies_with_course_module(): void {
1 efrain 2846
        $this->resetAfterTest(true);
2847
        $this->setAdminUser();
2848
        $dg = $this->getDataGenerator();
2849
        $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
2850
        $course = $dg->create_course();
2851
 
2852
        $framework = $lpg->create_framework();
2853
        $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2854
        $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2855
        $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2856
        $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2857
        $c5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get('id')));
2858
 
2859
        $cc1 = api::add_competency_to_course($course->id, $c1->get('id'));
2860
        $cc2 = api::add_competency_to_course($course->id, $c2->get('id'));
2861
        $cc3 = api::add_competency_to_course($course->id, $c3->get('id'));
2862
 
2863
        $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
2864
        $page = $pagegenerator->create_instance(array('course' => $course->id));
2865
 
2866
        $cm = get_coursemodule_from_instance('page', $page->id);
2867
        // Add a link and list again.
2868
        $ccm1 = api::add_competency_to_course_module($cm, $c1->get('id'));
2869
        $ccm2 = api::add_competency_to_course_module($cm, $c2->get('id'));
2870
 
2871
        // Test list competencies for this course module.
2872
        $total = external::count_course_module_competencies($cm->id);
2873
        $result = external::list_course_module_competencies($cm->id);
2874
        $this->assertCount($total, $result);
2875
 
2876
        // Now we should have an array and each element of the array should have a competency and
2877
        // a coursemodulecompetency.
2878
        foreach ($result as $instance) {
2879
            $cmc = $instance['coursemodulecompetency'];
2880
            $c = $instance['competency'];
2881
            $this->assertEquals($cmc->competencyid, $c->id);
2882
        }
2883
 
2884
    }
2885
 
2886
}