Proyectos de Subversion Moodle

Rev

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