MDL-52242 tool_lp: Competencies listed in a completed plan must never change
[moodle.git] / admin / tool / lp / tests / api_test.php
CommitLineData
f610a957
FM
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * API tests.
19 *
20 * @package tool_lp
21 * @copyright 2015 Frédéric Massart - FMCorz.net
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26global $CFG;
27
28use tool_lp\api;
4de456cd 29use tool_lp\user_competency;
f610a957
FM
30
31/**
32 * API tests.
33 *
34 * @package tool_lp
35 * @copyright 2015 Frédéric Massart - FMCorz.net
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 */
38class tool_lp_api_testcase extends advanced_testcase {
39
40 public function test_get_framework_related_contexts() {
41 $this->resetAfterTest(true);
42 $dg = $this->getDataGenerator();
43 $cat1 = $dg->create_category();
44 $cat2 = $dg->create_category(array('parent' => $cat1->id));
45 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 46 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
47
48 $cat1ctx = context_coursecat::instance($cat1->id);
49 $cat2ctx = context_coursecat::instance($cat2->id);
50 $cat3ctx = context_coursecat::instance($cat3->id);
51 $sysctx = context_system::instance();
52
53 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 54 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
f610a957
FM
55
56 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
f0da26a4 57 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
f610a957
FM
58
59 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
f0da26a4 60 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
f610a957
FM
61 }
62
63 public function test_get_framework_related_contexts_with_capabilities() {
64 $this->resetAfterTest(true);
65 $dg = $this->getDataGenerator();
66 $user = $dg->create_user();
67 $cat1 = $dg->create_category();
68 $cat2 = $dg->create_category(array('parent' => $cat1->id));
69 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 70 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
71
72 $cat1ctx = context_coursecat::instance($cat1->id);
73 $cat2ctx = context_coursecat::instance($cat2->id);
74 $cat3ctx = context_coursecat::instance($cat3->id);
75 $sysctx = context_system::instance();
76
77 $roleallow = create_role('Allow', 'allow', 'Allow read');
78 assign_capability('tool/lp:competencyread', CAP_ALLOW, $roleallow, $sysctx->id);
79 role_assign($roleallow, $user->id, $sysctx->id);
80
81 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
82 assign_capability('tool/lp:competencyread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
83 role_assign($roleprevent, $user->id, $cat2ctx->id);
84
85 accesslib_clear_all_caches_for_unit_testing();
86 $this->setUser($user);
87 $this->assertFalse(has_capability('tool/lp:competencyread', $cat2ctx));
88
89 $requiredcap = array('tool/lp:competencyread');
90
91 $expected = array();
f0da26a4 92 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
f610a957
FM
93
94 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 95 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
f610a957
FM
96
97 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
f0da26a4 98 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
f610a957 99 }
f0da26a4
FM
100
101 public function test_get_template_related_contexts() {
102 $this->resetAfterTest(true);
103 $dg = $this->getDataGenerator();
104 $cat1 = $dg->create_category();
105 $cat2 = $dg->create_category(array('parent' => $cat1->id));
106 $cat3 = $dg->create_category(array('parent' => $cat2->id));
107 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
108
109 $cat1ctx = context_coursecat::instance($cat1->id);
110 $cat2ctx = context_coursecat::instance($cat2->id);
111 $cat3ctx = context_coursecat::instance($cat3->id);
112 $sysctx = context_system::instance();
113
114 $expected = array($cat1ctx->id => $cat1ctx);
115 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
116
117 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
118 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
119
120 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
121 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
122 }
123
124 public function test_get_template_related_contexts_with_capabilities() {
125 $this->resetAfterTest(true);
126 $dg = $this->getDataGenerator();
127 $user = $dg->create_user();
128 $cat1 = $dg->create_category();
129 $cat2 = $dg->create_category(array('parent' => $cat1->id));
130 $cat3 = $dg->create_category(array('parent' => $cat2->id));
131 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
132
133 $cat1ctx = context_coursecat::instance($cat1->id);
134 $cat2ctx = context_coursecat::instance($cat2->id);
135 $cat3ctx = context_coursecat::instance($cat3->id);
136 $sysctx = context_system::instance();
137
138 $roleallow = create_role('Allow', 'allow', 'Allow read');
139 assign_capability('tool/lp:templateread', CAP_ALLOW, $roleallow, $sysctx->id);
140 role_assign($roleallow, $user->id, $sysctx->id);
141
142 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
143 assign_capability('tool/lp:templateread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
144 role_assign($roleprevent, $user->id, $cat2ctx->id);
145
146 accesslib_clear_all_caches_for_unit_testing();
147 $this->setUser($user);
148 $this->assertFalse(has_capability('tool/lp:templateread', $cat2ctx));
149
150 $requiredcap = array('tool/lp:templateread');
151
152 $expected = array();
153 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
154
155 $expected = array($cat1ctx->id => $cat1ctx);
156 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
157
158 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
159 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
160 }
161
ec324dc6
FM
162 /**
163 * Test updating a template.
164 */
165 public function test_update_template() {
166 $cat = $this->getDataGenerator()->create_category();
167 $this->resetAfterTest(true);
168 $this->setAdminUser();
169
170 $syscontext = context_system::instance();
171 $template = api::create_template((object) array('shortname' => 'testing', 'contextid' => $syscontext->id));
172
173 $this->assertEquals('testing', $template->get_shortname());
174 $this->assertEquals($syscontext->id, $template->get_contextid());
175
176 // Simple update.
177 api::update_template((object) array('id' => $template->get_id(), 'shortname' => 'success'));
178 $template = api::read_template($template->get_id());
179 $this->assertEquals('success', $template->get_shortname());
180
181 // Trying to change the context.
182 $this->setExpectedException('coding_exception');
183 api::update_template((object) array('id' => $template->get_id(), 'contextid' => context_coursecat::instance($cat->id)));
184 }
185
b3979696
IT
186 /**
187 * Test listing framework with order param.
188 */
189 public function test_list_frameworks() {
190 $this->resetAfterTest(true);
191 $this->setAdminUser();
bf61cd0c 192 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
b3979696
IT
193
194 // Create a list of frameworks.
bf61cd0c
FM
195 $framework1 = $lpg->create_framework(array(
196 'shortname' => 'shortname_a',
197 'idnumber' => 'idnumber_c',
198 'description' => 'description',
199 'descriptionformat' => FORMAT_HTML,
200 'visible' => true,
201 'contextid' => context_system::instance()->id
202 ));
203
204 $framework2 = $lpg->create_framework(array(
205 'shortname' => 'shortname_b',
206 'idnumber' => 'idnumber_a',
207 'description' => 'description',
208 'descriptionformat' => FORMAT_HTML,
209 'visible' => true,
210 'contextid' => context_system::instance()->id
211 ));
212
213 $framework3 = $lpg->create_framework(array(
214 'shortname' => 'shortname_c',
215 'idnumber' => 'idnumber_b',
216 'description' => 'description',
217 'descriptionformat' => FORMAT_HTML,
218 'visible' => true,
219 'contextid' => context_system::instance()->id
220 ));
b3979696
IT
221
222 // Get frameworks list order by shortname desc.
223 $result = api::list_frameworks('shortname', 'DESC', null, 3, context_system::instance());
224
1896274f
FM
225 $f = (object) array_shift($result);
226 $this->assertEquals($framework3->get_id(), $f->get_id());
227 $f = (object) array_shift($result);
228 $this->assertEquals($framework2->get_id(), $f->get_id());
229 $f = (object) array_shift($result);
230 $this->assertEquals($framework1->get_id(), $f->get_id());
b3979696
IT
231
232 // Get frameworks list order by idnumber asc.
233 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance());
234
1896274f
FM
235 $f = (object) array_shift($result);
236 $this->assertEquals($framework2->get_id(), $f->get_id());
237 $f = (object) array_shift($result);
238 $this->assertEquals($framework3->get_id(), $f->get_id());
239 $f = (object) array_shift($result);
240 $this->assertEquals($framework1->get_id(), $f->get_id());
b3979696
IT
241 }
242
c61db7bb
IT
243 /**
244 * Test duplicate a framework.
245 */
246 public function test_duplicate_framework() {
247 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
248 $this->resetAfterTest(true);
249 $this->setAdminUser();
250
251 $syscontext = context_system::instance();
252 $params = array(
253 'shortname' => 'shortname_a',
254 'idnumber' => 'idnumber_c',
255 'description' => 'description',
256 'descriptionformat' => FORMAT_HTML,
257 'visible' => true,
258 'contextid' => $syscontext->id
259 );
260 $framework = $lpg->create_framework($params);
261 $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
262 $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
263 $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
264 $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
265 $competencyidnumbers = array($competency1->get_idnumber(),
266 $competency2->get_idnumber(),
267 $competency3->get_idnumber(),
268 $competency4->get_idnumber()
269 );
270
271 api::add_related_competency($competency1->get_id(), $competency2->get_id());
272 api::add_related_competency($competency3->get_id(), $competency4->get_id());
273
274 $frameworkduplicated1 = api::duplicate_framework($framework->get_id());
275 $frameworkduplicated2 = api::duplicate_framework($framework->get_id());
276
277 $this->assertEquals($framework->get_idnumber().'_1', $frameworkduplicated1->get_idnumber());
278 $this->assertEquals($framework->get_idnumber().'_2', $frameworkduplicated2->get_idnumber());
279
280 $competenciesfr1 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated1->get_id()));
281 $competenciesfr2 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated2->get_id()));
282
283 $competencyidsfr1 = array();
284 $competencyidsfr2 = array();
285
286 foreach ($competenciesfr1 as $cmp) {
287 $competencyidsfr1[] = $cmp->get_idnumber();
288 }
289 foreach ($competenciesfr2 as $cmp) {
290 $competencyidsfr2[] = $cmp->get_idnumber();
291 }
292
293 $this->assertEmpty(array_diff($competencyidsfr1, $competencyidnumbers));
294 $this->assertEmpty(array_diff($competencyidsfr2, $competencyidnumbers));
295 $this->assertCount(4, $competenciesfr1);
296 $this->assertCount(4, $competenciesfr2);
297
298 // Test the related competencies.
299 reset($competenciesfr1);
300 $compduplicated1 = current($competenciesfr1);
301 $relatedcompetencies = $compduplicated1->get_related_competencies();
302 $comprelated = current($relatedcompetencies);
303 $this->assertEquals($comprelated->get_idnumber(), $competency2->get_idnumber());
304 }
305
58405003
IT
306 /**
307 * Test update plan.
308 */
309 public function test_update_plan() {
310 $this->resetAfterTest(true);
311 $dg = $this->getDataGenerator();
312 $usermanageowndraft = $dg->create_user();
313 $usermanageown = $dg->create_user();
314 $usermanagedraft = $dg->create_user();
315 $usermanage = $dg->create_user();
316
317 $syscontext = context_system::instance();
318
319 // Creating specific roles.
320 $manageowndraftrole = $dg->create_role(array(
321 'name' => 'User manage own draft',
322 'shortname' => 'manage-own-draft'
323 ));
324 $manageownrole = $dg->create_role(array(
325 'name' => 'User manage own',
326 'shortname' => 'manage-own'
327 ));
328 $managedraftrole = $dg->create_role(array(
329 'name' => 'User manage draft',
330 'shortname' => 'manage-draft'
331 ));
332 $managerole = $dg->create_role(array(
333 'name' => 'User manage',
334 'shortname' => 'manage'
335 ));
336
337 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
338 assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
339
340 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id);
341 assign_capability('tool/lp:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id);
342
343 assign_capability('tool/lp:planmanagedraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
344 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
345
346 assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
347 assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
348
349 $dg->role_assign($manageowndraftrole, $usermanageowndraft->id, $syscontext->id);
350 $dg->role_assign($manageownrole, $usermanageown->id, $syscontext->id);
351 $dg->role_assign($managedraftrole, $usermanagedraft->id, $syscontext->id);
352 $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
353
354 // Create first learning plan with user create draft.
355 $this->setUser($usermanageowndraft);
356 $plan = array (
357 'name' => 'plan own draft',
358 'description' => 'plan own draft',
359 'userid' => $usermanageowndraft->id
360 );
361 $plan = api::create_plan((object)$plan);
362 $record = $plan->to_record();
363 $record->name = 'plan own draft modified';
364
365 // Check if user create draft can edit the plan name.
366 $plan = api::update_plan($record);
367 $this->assertInstanceOf('\tool_lp\plan', $plan);
368
369 // Thrown exception when manageowndraft user try to change the status.
370 $record->status = \tool_lp\plan::STATUS_ACTIVE;
371 try {
372 $plan = api::update_plan($record);
373 $this->fail('User with manage own draft capability cannot edit the plan status.');
374 } catch (required_capability_exception $e) {
375 $this->assertTrue(true);
376 }
377
378 // Test when user with manage own plan capability try to edit other user plan.
379 $record->status = \tool_lp\plan::STATUS_DRAFT;
380 $record->name = 'plan create draft modified 2';
381 $this->setUser($usermanageown);
382 try {
383 $plan = api::update_plan($record);
384 $this->fail('User with manage own plan capability can only edit his own plan.');
385 } catch (required_capability_exception $e) {
386 $this->assertTrue(true);
387 }
388
389 // User with manage plan capability cannot edit the other user plans with status draft.
390 $this->setUser($usermanage);
391 $record->status = \tool_lp\plan::STATUS_COMPLETE;
392 try {
393 $plan = api::update_plan($record);
394 $this->fail('User with manage plan capability cannot edit the other user plans with status draft');
395 } catch (required_capability_exception $e) {
396 $this->assertTrue(true);
397 }
398
399 // User with manage draft capability can edit other user's learning plan if the status is draft.
400 $this->setUser($usermanagedraft);
401 $record->status = \tool_lp\plan::STATUS_DRAFT;
402 $record->name = 'plan manage draft modified 3';
403 $plan = api::update_plan($record);
404 $this->assertInstanceOf('\tool_lp\plan', $plan);
405
406 // User with manage plan capability can create/edit learning plan if status is active/complete.
407 $this->setUser($usermanage);
408 $plan = array (
409 'name' => 'plan create',
410 'description' => 'plan create',
411 'userid' => $usermanage->id,
412 'status' => \tool_lp\plan::STATUS_ACTIVE
413 );
414 $plan = api::create_plan((object)$plan);
5bfab685
FM
415
416 // Silently transition to complete status to avoid errors about transitioning to complete.
417 $plan->set_status(\tool_lp\plan::STATUS_COMPLETE);
418 $plan->update();
419
58405003
IT
420 $record = $plan->to_record();
421 $record->name = 'plan create own modified';
d805cc37
IT
422 try {
423 api::update_plan($record);
424 $this->fail('Completed plan can not be edited');
425 } catch (coding_exception $e) {
426 $this->assertTrue(true);
427 }
58405003
IT
428 }
429
2388d46d
FM
430 public function test_create_plan_from_template() {
431 $this->resetAfterTest(true);
432 $this->setAdminUser();
433
434 $u1 = $this->getDataGenerator()->create_user();
435 $tpl = $this->getDataGenerator()->get_plugin_generator('tool_lp')->create_template();
436
437 // Creating a new plan.
438 $plan = api::create_plan_from_template($tpl, $u1->id);
439 $record = $plan->to_record();
440 $this->assertInstanceOf('\tool_lp\plan', $plan);
441 $this->assertTrue(\tool_lp\plan::record_exists($plan->get_id()));
442 $this->assertEquals($tpl->get_id(), $plan->get_templateid());
443 $this->assertEquals($u1->id, $plan->get_userid());
444 $this->assertTrue($plan->is_based_on_template());
445
446 // Creating a plan that already exists.
447 $plan = api::create_plan_from_template($tpl, $u1->id);
448 $this->assertFalse($plan);
449
450 // Check that api::create_plan cannot be used.
451 $this->setExpectedException('coding_exception');
452 unset($record->id);
453 $plan = api::create_plan($record);
454 }
455
4de877eb
FM
456 public function test_update_plan_based_on_template() {
457 $this->resetAfterTest(true);
458 $dg = $this->getDataGenerator();
459 $lpg = $dg->get_plugin_generator('tool_lp');
460 $u1 = $dg->create_user();
461 $u2 = $dg->create_user();
462
463 $this->setAdminUser();
464 $tpl1 = $lpg->create_template();
465 $tpl2 = $lpg->create_template();
466 $up1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id()));
467 $up2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => null));
468
469 try {
470 // Trying to remove the template dependency.
471 $record = $up1->to_record();
472 $record->templateid = null;
473 api::update_plan($record);
474 $this->fail('A plan cannot be unlinked using api::update_plan()');
475 } catch (coding_exception $e) {
476 }
477
478 try {
479 // Trying to switch to another template.
480 $record = $up1->to_record();
481 $record->templateid = $tpl2->get_id();
482 api::update_plan($record);
483 $this->fail('A plan cannot be moved to another template.');
484 } catch (coding_exception $e) {
485 }
486
487 try {
488 // Trying to switch to using a template.
489 $record = $up2->to_record();
490 $record->templateid = $tpl1->get_id();
491 api::update_plan($record);
492 $this->fail('A plan cannot be update to use a template.');
493 } catch (coding_exception $e) {
494 }
495 }
496
6d2c2e86
FM
497 public function test_unlink_plan_from_template() {
498 $this->resetAfterTest(true);
499 $dg = $this->getDataGenerator();
500 $lpg = $dg->get_plugin_generator('tool_lp');
501 $u1 = $dg->create_user();
502 $u2 = $dg->create_user();
503
504 $this->setAdminUser();
505 $f1 = $lpg->create_framework();
506 $f2 = $lpg->create_framework();
507 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
508 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
509 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
510
511 $tpl1 = $lpg->create_template();
512 $tpl2 = $lpg->create_template();
513
514 $tplc1a = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1a->get_id(),
515 'sortorder' => 9));
516 $tplc1b = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1b->get_id(),
517 'sortorder' => 8));
518 $tplc2a = $lpg->create_template_competency(array('templateid' => $tpl2->get_id(), 'competencyid' => $c2a->get_id()));
519
520 $plan1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id()));
521 $plan2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => $tpl2->get_id()));
522
523 // Check that we have what we expect at this stage.
524 $this->assertEquals(2, \tool_lp\template_competency::count_records(array('templateid' => $tpl1->get_id())));
525 $this->assertEquals(1, \tool_lp\template_competency::count_records(array('templateid' => $tpl2->get_id())));
526 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan1->get_id())));
527 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan2->get_id())));
528 $this->assertTrue($plan1->is_based_on_template());
529 $this->assertTrue($plan2->is_based_on_template());
530
531 // Let's do this!
532 $tpl1comps = \tool_lp\template_competency::list_competencies($tpl1->get_id(), true);
533 $tpl2comps = \tool_lp\template_competency::list_competencies($tpl2->get_id(), true);
534
535 api::unlink_plan_from_template($plan1);
536
537 $plan1->read();
538 $plan2->read();
539 $this->assertCount(2, $tpl1comps);
540 $this->assertCount(1, $tpl2comps);
541 $this->assertEquals(2, \tool_lp\template_competency::count_records(array('templateid' => $tpl1->get_id())));
542 $this->assertEquals(1, \tool_lp\template_competency::count_records(array('templateid' => $tpl2->get_id())));
543 $this->assertEquals(2, \tool_lp\plan_competency::count_records(array('planid' => $plan1->get_id())));
544 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan2->get_id())));
545 $this->assertFalse($plan1->is_based_on_template());
546 $this->assertEquals($tpl1->get_id(), $plan1->get_origtemplateid());
547 $this->assertTrue($plan2->is_based_on_template());
548 $this->assertEquals(null, $plan2->get_origtemplateid());
549
550 // Even the order remains.
551 $plan1comps = \tool_lp\plan_competency::list_competencies($plan1->get_id());
552 $before = reset($tpl1comps);
553 $after = reset($plan1comps);
554 $this->assertEquals($before->get_id(), $after->get_id());
555 $this->assertEquals($before->get_sortorder(), $after->get_sortorder());
556 $before = next($tpl1comps);
557 $after = next($plan1comps);
558 $this->assertEquals($before->get_id(), $after->get_id());
559 $this->assertEquals($before->get_sortorder(), $after->get_sortorder());
560 }
561
c7999f6d
FM
562 public function test_update_template_updates_plans() {
563 $this->resetAfterTest(true);
564 $this->setAdminUser();
565
566 $dg = $this->getDataGenerator();
567 $u1 = $dg->create_user();
568 $u2 = $dg->create_user();
569 $lpg = $dg->get_plugin_generator('tool_lp');
570 $tpl1 = $lpg->create_template();
571 $tpl2 = $lpg->create_template();
572
573
574 // Create plans with data not matching templates.
575 $time = time();
576 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u1->id,
577 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_MARKDOWN));
578 $plan2 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u2->id,
579 'name' => 'Not right name', 'duedate' => $time + 3601, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
580 $plan3 = $lpg->create_plan(array('templateid' => $tpl2->get_id(), 'userid' => $u1->id,
581 'name' => 'Not sweet name', 'duedate' => $time + 3602, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
582
583 // Prepare our expectations.
584 $plan1->read();
585 $plan2->read();
586 $plan3->read();
587
588 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid());
589 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid());
590 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid());
591 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name());
592 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name());
593 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
594 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description());
595 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description());
596 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
597 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
598 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
599 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
600 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate());
601 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate());
602 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
603
604 // Update the template without changing critical fields does not update the plans.
605 $data = $tpl1->to_record();
606 $data->visible = 0;
607 api::update_template($data);
608 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name());
609 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name());
610 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
611 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description());
612 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description());
613 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
614 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
615 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
616 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
617 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate());
618 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate());
619 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
620
621 // Now really update the template.
622 $data = $tpl1->to_record();
623 $data->shortname = 'Awesome!';
624 $data->description = 'This is too awesome!';
625 $data->descriptionformat = FORMAT_HTML;
626 $data->duedate = $time + 7200;
627 api::update_template($data);
628 $tpl1->read();
629
630 // Now confirm that the right plans were updated.
631 $plan1->read();
632 $plan2->read();
633 $plan3->read();
634
635 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid());
636 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid());
637 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid());
638
639 $this->assertEquals($tpl1->get_shortname(), $plan1->get_name());
640 $this->assertEquals($tpl1->get_shortname(), $plan2->get_name());
641 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
642 $this->assertEquals($tpl1->get_description(), $plan1->get_description());
643 $this->assertEquals($tpl1->get_description(), $plan2->get_description());
644 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
645 $this->assertEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
646 $this->assertEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
647 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
648 $this->assertEquals($tpl1->get_duedate(), $plan1->get_duedate());
649 $this->assertEquals($tpl1->get_duedate(), $plan2->get_duedate());
650 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
651 }
652
5bfab685
FM
653 /**
654 * Test that the method to complete a plan.
655 */
656 public function test_complete_plan() {
657 global $DB;
658
659 $this->resetAfterTest(true);
660 $this->setAdminUser();
661 $dg = $this->getDataGenerator();
662 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
663 $user = $dg->create_user();
664
665 // Create a framework and assign competencies.
666 $framework = $lpg->create_framework();
667 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
668 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
669 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
d3275795 670 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
5bfab685
FM
671
672 // Create two plans and assign competencies.
673 $plan = $lpg->create_plan(array('userid' => $user->id));
674 $otherplan = $lpg->create_plan(array('userid' => $user->id));
675
676 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id()));
677 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id()));
678 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id()));
679 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id()));
680
681 $uclist = array(
682 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
683 'proficiency' => true, 'grade' => 1 )),
684 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
685 'proficiency' => false, 'grade' => 2 ))
686 );
687
688 $this->assertEquals(2, \tool_lp\user_competency::count_records());
689 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
690
691 // Change status of the plan to complete.
692 api::complete_plan($plan);
693
694 // Check that user competencies are now in user_competency_plan objects and still in user_competency.
695 $this->assertEquals(2, \tool_lp\user_competency::count_records());
696 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
697
698 $usercompetenciesplan = \tool_lp\user_competency_plan::get_records();
699
700 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid());
701 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid());
702 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency());
703 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade());
704 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid());
705
706 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid());
707 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid());
708 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency());
709 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade());
710 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid());
711
712 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid());
713 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid());
714 $this->assertNull($usercompetenciesplan[2]->get_proficiency());
715 $this->assertNull($usercompetenciesplan[2]->get_grade());
716 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid());
717
d3275795
SG
718 // Check we can not add competency to completed plan.
719 try {
720 api::add_competency_to_plan($plan->get_id(), $c4->get_id());
721 $this->fail('We can not add competency to completed plan.');
722 } catch (coding_exception $e) {
723 }
724
725 // Check we can not remove competency to completed plan.
726 try {
727 api::remove_competency_from_plan($plan->get_id(), $c3->get_id());
728 $this->fail('We can not remove competency to completed plan.');
729 } catch (coding_exception $e) {
730 }
731
5bfab685
FM
732 // Completing a plan that is completed throws an exception.
733 $this->setExpectedException('coding_exception');
734 api::complete_plan($plan);
735 }
736
192569ed
JPG
737 /**
738 * Test update plan and the managing of archived user competencies.
739 */
740 public function test_update_plan_manage_archived_competencies() {
741 global $DB;
742
743 $this->resetAfterTest(true);
744 $dg = $this->getDataGenerator();
745 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
746
747 $syscontext = context_system::instance();
748
749 // Create users and roles for the test.
750 $user = $dg->create_user();
751 $manageownrole = $dg->create_role(array(
752 'name' => 'User manage own',
753 'shortname' => 'manageown'
754 ));
755 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $manageownrole, $syscontext->id);
756 assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $manageownrole, $syscontext->id);
757 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id);
758 assign_capability('tool/lp:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id);
759 $dg->role_assign($manageownrole, $user->id, $syscontext->id);
760 $this->setUser($user);
761
762 // Create a framework and assign competencies.
763 $framework = $lpg->create_framework();
764 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
765 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
766 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
767
768 // Create two plans and assign competencies.
769 $plan = $lpg->create_plan(array('userid' => $user->id));
770 $otherplan = $lpg->create_plan(array('userid' => $user->id));
771
772 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id()));
773 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id()));
774 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id()));
775 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id()));
776
777 $uclist = array(
778 $lpg->create_user_competency(array(
779 'userid' => $user->id,
780 'competencyid' => $c1->get_id(),
781 'proficiency' => true,
782 'grade' => 1
783 )),
784 $lpg->create_user_competency(array(
785 'userid' => $user->id,
786 'competencyid' => $c2->get_id(),
787 'proficiency' => false,
788 'grade' => 2
789 ))
790 );
791
792 // Change status of the plan to complete.
793 $record = $plan->to_record();
794 $record->status = \tool_lp\plan::STATUS_COMPLETE;
795
5bfab685
FM
796 try {
797 $plan = api::update_plan($record);
798 $this->fail('We cannot complete a plan using api::update_plan().');
799 } catch (coding_exception $e) {
800 }
801 api::complete_plan($plan);
192569ed
JPG
802
803 // Check that user compretencies are now in user_competency_plan objects and still in user_competency.
804 $this->assertEquals(2, \tool_lp\user_competency::count_records());
805 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
806
807 $usercompetenciesplan = \tool_lp\user_competency_plan::get_records();
808
809 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid());
810 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid());
811 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency());
812 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade());
813 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid());
814
815 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid());
816 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid());
817 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency());
818 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade());
819 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid());
820
821 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid());
822 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid());
823 $this->assertNull($usercompetenciesplan[2]->get_proficiency());
824 $this->assertNull($usercompetenciesplan[2]->get_grade());
825 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid());
826
192569ed
JPG
827 // Change status of the plan to active.
828 $record = $plan->to_record();
829 $record->status = \tool_lp\plan::STATUS_ACTIVE;
830
d805cc37
IT
831 try {
832 api::update_plan($record);
833 $this->fail('Completed plan can not be edited');
834 } catch (coding_exception $e) {
835 }
192569ed 836
d805cc37 837 api::reopen_plan($record->id);
192569ed
JPG
838 // Check that user_competency_plan objects are deleted if the plan status is changed to another status.
839 $this->assertEquals(2, \tool_lp\user_competency::count_records());
840 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
841 }
842
843 /**
844 * Test remove plan and the managing of archived user competencies.
845 */
846 public function test_delete_plan_manage_archived_competencies() {
847 $this->resetAfterTest(true);
848 $dg = $this->getDataGenerator();
849 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
850
851 $syscontext = context_system::instance();
852
853 // Create user and role for the test.
854 $user = $dg->create_user();
855 $managerole = $dg->create_role(array(
856 'name' => 'User manage own',
857 'shortname' => 'manageown'
858 ));
859 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $managerole, $syscontext->id);
860 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $managerole, $syscontext->id);
861 $dg->role_assign($managerole, $user->id, $syscontext->id);
862 $this->setUser($user);
863
864 // Create a framework and assign competencies.
865 $framework = $lpg->create_framework();
866 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
867 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
868 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
869
870 // Create completed plan with records in user_competency.
871 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
872
873 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
874 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
875
876 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
877 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
878
879 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
880 'planid' => $completedplan->get_id()));
881 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
882 'planid' => $completedplan->get_id()));
883
884 api::delete_plan($completedplan->get_id());
885
886 // Check that achived user competencies are deleted.
887 $this->assertEquals(0, \tool_lp\plan::count_records());
888 $this->assertEquals(2, \tool_lp\user_competency::count_records());
889 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
890 }
891
892 /**
893 * Test listing of plan competencies.
894 */
895 public function test_list_plan_competencies_manage_archived_competencies() {
896 $this->resetAfterTest(true);
897 $dg = $this->getDataGenerator();
898 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
899
900 $syscontext = context_system::instance();
901
902 // Create user and role for the test.
903 $user = $dg->create_user();
904 $viewrole = $dg->create_role(array(
905 'name' => 'User view',
906 'shortname' => 'view'
907 ));
908 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $viewrole, $syscontext->id);
909 assign_capability('tool/lp:planview', CAP_ALLOW, $viewrole, $syscontext->id);
910 $dg->role_assign($viewrole, $user->id, $syscontext->id);
911 $this->setUser($user);
912
913 // Create a framework and assign competencies.
914 $framework = $lpg->create_framework();
915 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
916 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
917 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
918
919 // Create draft plan with records in user_competency.
920 $draftplan = $lpg->create_plan(array('userid' => $user->id));
921
922 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c1->get_id()));
923 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c2->get_id()));
924 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c3->get_id()));
925
926 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
927 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
928
929 // Check that user_competency objects are returned when plan status is not complete.
930 $plancompetencies = api::list_plan_competencies($draftplan);
931
932 $this->assertCount(3, $plancompetencies);
933 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[0]->usercompetency);
934 $this->assertEquals($uc1->get_id(), $plancompetencies[0]->usercompetency->get_id());
935 $this->assertNull($plancompetencies[0]->usercompetencyplan);
936
937 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[1]->usercompetency);
938 $this->assertEquals($uc2->get_id(), $plancompetencies[1]->usercompetency->get_id());
939 $this->assertNull($plancompetencies[1]->usercompetencyplan);
940
941 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[2]->usercompetency);
942 $this->assertEquals(0, $plancompetencies[2]->usercompetency->get_id());
943 $this->assertNull($plancompetencies[2]->usercompetencyplan);
944
945 // Create completed plan with records in user_competency_plan.
946 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
947
948 $pc1 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
949 $pc2 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
950 $pc3 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c3->get_id()));
951
952 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
953 'planid' => $completedplan->get_id()));
954 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
955 'planid' => $completedplan->get_id()));
192569ed
JPG
956 $ucp3 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c3->get_id(),
957 'planid' => $completedplan->get_id()));
958
959 // Check that user_competency_plan objects are returned when plan status is complete.
960 $plancompetencies = api::list_plan_competencies($completedplan);
961
962 $this->assertCount(3, $plancompetencies);
963 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[0]->usercompetencyplan);
964 $this->assertEquals($ucp1->get_id(), $plancompetencies[0]->usercompetencyplan->get_id());
965 $this->assertNull($plancompetencies[0]->usercompetency);
966 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[1]->usercompetencyplan);
967 $this->assertEquals($ucp2->get_id(), $plancompetencies[1]->usercompetencyplan->get_id());
968 $this->assertNull($plancompetencies[1]->usercompetency);
969 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[2]->usercompetencyplan);
970 $this->assertEquals($ucp3->get_id(), $plancompetencies[2]->usercompetencyplan->get_id());
971 $this->assertNull($plancompetencies[2]->usercompetency);
972 }
973
bee480a4
FM
974 public function test_create_template_cohort() {
975 $this->resetAfterTest(true);
976 $this->setAdminUser();
977
978 $dg = $this->getDataGenerator();
979 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
980
981 $c1 = $dg->create_cohort();
982 $c2 = $dg->create_cohort();
983 $t1 = $lpg->create_template();
984 $t2 = $lpg->create_template();
985
986 $this->assertEquals(0, \tool_lp\template_cohort::count_records());
987
988 // Create two relations with mixed parameters.
989 $result = api::create_template_cohort($t1->get_id(), $c1->id);
990 $result = api::create_template_cohort($t1, $c2);
991
992 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
993 $this->assertInstanceOf('tool_lp\template_cohort', $result);
994 $this->assertEquals($c2->id, $result->get_cohortid());
995 $this->assertEquals($t1->get_id(), $result->get_templateid());
996 $this->assertEquals(2, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
997 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
998 }
999
1000 public function test_delete_template_cohort() {
1001 $this->resetAfterTest(true);
1002 $this->setAdminUser();
1003
1004 $dg = $this->getDataGenerator();
1005 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1006
1007 $c1 = $dg->create_cohort();
1008 $c2 = $dg->create_cohort();
1009 $t1 = $lpg->create_template();
1010 $t2 = $lpg->create_template();
1011 $tc1 = $lpg->create_template_cohort(array('templateid' => $t1->get_id(), 'cohortid' => $c1->id));
1012 $tc1 = $lpg->create_template_cohort(array('templateid' => $t2->get_id(), 'cohortid' => $c2->id));
1013
1014 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
1015 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1016 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1017
1018 // Delete existing.
1019 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1020 $this->assertTrue($result);
1021 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1022 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1023 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1024
1025 // Delete non-existant.
1026 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1027 $this->assertTrue($result);
1028 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1029 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1030 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1031 }
4c0e8167 1032
914b580e
FM
1033 public function test_add_evidence_log() {
1034 $this->resetAfterTest(true);
1035 $dg = $this->getDataGenerator();
1036 $lpg = $dg->get_plugin_generator('tool_lp');
1037
1038 $u1 = $dg->create_user();
1039 $u1ctx = context_user::instance($u1->id);
1040 $f1 = $lpg->create_framework();
1041 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1042 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1043
1044 // Creating a standard evidence with minimal information.
1045 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error');
1046 $evidence->read();
1047 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1048 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1049 $this->assertSame(null, $uc->get_grade());
1050 $this->assertSame(null, $uc->get_proficiency());
1051 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1052 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1053 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1054 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1055 $this->assertEquals('error', $evidence->get_desccomponent());
1056 $this->assertSame(null, $evidence->get_desca());
1057 $this->assertSame(null, $evidence->get_url());
1058 $this->assertSame(null, $evidence->get_grade());
1059 $this->assertSame(null, $evidence->get_actionuserid());
1060
1061 // Creating a standard evidence with more information.
1062 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
1063 '$a', false, 'http://moodle.org', null, 2);
1064 $evidence->read();
1065 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1066 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1067 $this->assertSame(null, $uc->get_grade());
1068 $this->assertSame(null, $uc->get_proficiency());
1069 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1070 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1071 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1072 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1073 $this->assertEquals('error', $evidence->get_desccomponent());
1074 $this->assertEquals('$a', $evidence->get_desca());
1075 $this->assertEquals('http://moodle.org', $evidence->get_url());
1076 $this->assertSame(null, $evidence->get_grade());
1077 $this->assertEquals(2, $evidence->get_actionuserid());
1078
1079 // Creating a standard evidence and send for review.
1080 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1081 'error', null, true);
1082 $evidence->read();
1083 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1084 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1085
1086 // Trying to pass a grade should fail.
1087 try {
1088 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
1089 null, false, null, 1);
1090 $this->fail('A grade can not be set');
1091 } catch (coding_exception $e) {
1092 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
1093 }
1094 }
1095
1096 public function test_add_evidence_suggest() {
1097 $this->resetAfterTest(true);
1098 $dg = $this->getDataGenerator();
1099 $lpg = $dg->get_plugin_generator('tool_lp');
1100
1101 $u1 = $dg->create_user();
1102 $u1ctx = context_user::instance($u1->id);
1103 $f1 = $lpg->create_framework();
1104 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1105 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1106
1107 // Creating an evidence with minimal information.
1108 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1109 'error', null, false, null, 1, 2);
1110 $evidence->read();
1111 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1112 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1113 $this->assertSame(null, $uc->get_grade()); // We don't grade, we just suggest.
1114 $this->assertSame(null, $uc->get_proficiency());
1115 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1116 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1117 $this->assertEquals(\tool_lp\evidence::ACTION_SUGGEST, $evidence->get_action());
1118 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1119 $this->assertEquals('error', $evidence->get_desccomponent());
1120 $this->assertSame(null, $evidence->get_desca());
1121 $this->assertSame(null, $evidence->get_url());
1122 $this->assertEquals(1, $evidence->get_grade());
1123 $this->assertEquals(2, $evidence->get_actionuserid());
1124
1125 // Creating a standard evidence and send for review.
1126 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1127 'error', null, true, null, 1, 2);
1128 $evidence->read();
1129 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1130 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1131
1132 // Trying not to pass a grade should fail.
1133 try {
1134 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata', 'error',
1135 false, null);
1136 $this->fail('A grade must be set');
1137 } catch (coding_exception $e) {
1138 $this->assertRegExp('/grade MUST be set/', $e->getMessage());
1139 }
1140 }
1141
1142 public function test_add_evidence_complete() {
1143 $this->resetAfterTest(true);
1144 $dg = $this->getDataGenerator();
1145 $lpg = $dg->get_plugin_generator('tool_lp');
1146
1147 $u1 = $dg->create_user();
1148 $u1ctx = context_user::instance($u1->id);
1149 $scale = $dg->create_scale(array('scale' => 'A,B,C,D'));
1150 $scaleconfig = array(array('scaleid' => $scale->id));
1151 $scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1152 $scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 1, 'proficient' => 0);
1153 $scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 1);
1154 $scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 0, 'proficient' => 1);
1155 $c2scaleconfig = array(array('scaleid' => $scale->id));
1156 $c2scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1157 $c2scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 0, 'proficient' => 1);
1158 $c2scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 0);
1159 $c2scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 1, 'proficient' => 1);
1160 $f1 = $lpg->create_framework(array('scaleid' => $scale->id, 'scaleconfiguration' => $scaleconfig));
1161 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1162 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'scaleid' => $scale->id,
1163 'scaleconfiguration' => $c2scaleconfig));
1164 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1165
1166 // Creating an evidence with minimal information.
1167 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1168 'error');
1169 $evidence->read();
1170 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1171 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1172 $this->assertEquals(2, $uc->get_grade()); // The grade has been set automatically to the framework default.
1173 $this->assertEquals(0, $uc->get_proficiency());
1174 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1175 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1176 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1177 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1178 $this->assertEquals('error', $evidence->get_desccomponent());
1179 $this->assertSame(null, $evidence->get_desca());
1180 $this->assertSame(null, $evidence->get_url());
1181 $this->assertEquals(2, $evidence->get_grade());
1182 $this->assertSame(null, $evidence->get_actionuserid());
1183
1184 // Creating an evidence complete on competency with custom scale.
1185 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1186 'error');
1187 $evidence->read();
1188 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1189 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1190 $this->assertEquals(4, $uc->get_grade()); // The grade has been set automatically to the competency default.
1191 $this->assertEquals(true, $uc->get_proficiency());
1192 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1193 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1194 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1195 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1196 $this->assertEquals('error', $evidence->get_desccomponent());
1197 $this->assertSame(null, $evidence->get_desca());
1198 $this->assertSame(null, $evidence->get_url());
1199 $this->assertEquals(4, $evidence->get_grade());
1200 $this->assertSame(null, $evidence->get_actionuserid());
1201
1202 // Creating an evidence complete on a user competency with an existing grade.
1203 $uc = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get_id(), 'grade' => 1,
1204 'proficiency' => 0));
1205 $this->assertEquals(1, $uc->get_grade());
1206 $this->assertEquals(0, $uc->get_proficiency());
1207 $evidence = api::add_evidence($u1->id, $c3->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1208 'error');
1209 $evidence->read();
1210 $uc->read();
1211 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1212 $this->assertEquals(1, $uc->get_grade()); // The grade has not been changed.
1213 $this->assertEquals(0, $uc->get_proficiency());
1214 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1215 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1216 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1217 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1218 $this->assertEquals('error', $evidence->get_desccomponent());
1219 $this->assertSame(null, $evidence->get_desca());
1220 $this->assertSame(null, $evidence->get_url());
1221 $this->assertEquals(2, $evidence->get_grade()); // The complete grade has been set.
1222 $this->assertSame(null, $evidence->get_actionuserid());
1223
1224 // Creating a standard evidence and send for review.
1225 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1226 'error', null, true);
1227 $evidence->read();
1228 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1229 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1230
1231 // Trying to pass a grade should throw an exception.
1232 try {
1233 api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1234 'error', null, false, null, 1);
1235 } catch (coding_exception $e) {
1236 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
1237 }
1238 }
1239
1240 public function test_add_evidence_override() {
1241 $this->resetAfterTest(true);
1242 $dg = $this->getDataGenerator();
1243 $lpg = $dg->get_plugin_generator('tool_lp');
1244
1245 $u1 = $dg->create_user();
1246 $u1ctx = context_user::instance($u1->id);
1247 $f1 = $lpg->create_framework();
1248 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1249
1250 // Creating an evidence with minimal information.
1251 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1252 'error');
1253 $evidence->read();
1254 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1255 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1256 $this->assertSame(null, $uc->get_grade()); // We overrode with 'null'.
1257 $this->assertSame(null, $uc->get_proficiency());
1258 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1259 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1260 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1261 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1262 $this->assertEquals('error', $evidence->get_desccomponent());
1263 $this->assertSame(null, $evidence->get_desca());
1264 $this->assertSame(null, $evidence->get_url());
1265 $this->assertSame(null, $evidence->get_grade()); // We overrode with 'null'.
1266 $this->assertSame(null, $evidence->get_actionuserid());
1267
1268 // Creating an evidence with a grade information.
1269 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1270 'error', null, false, null, 3);
1271 $evidence->read();
1272 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1273 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1274 $this->assertEquals(3, $uc->get_grade());
1275 $this->assertEquals(true, $uc->get_proficiency());
1276 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1277 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1278 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1279 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1280 $this->assertEquals('error', $evidence->get_desccomponent());
1281 $this->assertSame(null, $evidence->get_desca());
1282 $this->assertSame(null, $evidence->get_url());
1283 $this->assertEquals(3, $evidence->get_grade());
1284 $this->assertSame(null, $evidence->get_actionuserid());
1285
1286 // Creating an evidence with another grade information.
1287 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1288 'error', null, false, null, 1);
1289 $evidence->read();
1290 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1291 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1292 $this->assertEquals(1, $uc->get_grade());
1293 $this->assertEquals(0, $uc->get_proficiency());
1294 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1295 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1296 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1297 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1298 $this->assertEquals('error', $evidence->get_desccomponent());
1299 $this->assertSame(null, $evidence->get_desca());
1300 $this->assertSame(null, $evidence->get_url());
1301 $this->assertEquals(1, $evidence->get_grade());
1302 $this->assertSame(null, $evidence->get_actionuserid());
1303
1304 // Creating reverting the grade and send for review.
1305 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1306 'error', null, true);
1307 $evidence->read();
1308 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1309 $this->assertSame(null, $uc->get_grade());
1310 $this->assertSame(null, $uc->get_proficiency());
1311 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1312 $this->assertSame(null, $evidence->get_grade());
1313 }
1314
1315 public function test_add_evidence_and_send_for_review() {
1316 $this->resetAfterTest(true);
1317 $dg = $this->getDataGenerator();
1318 $lpg = $dg->get_plugin_generator('tool_lp');
1319
1320 $u1 = $dg->create_user();
1321 $u1ctx = context_user::instance($u1->id);
1322 $f1 = $lpg->create_framework();
1323 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1324
1325 // Non-existing user competencies are created up for review.
1326 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1327 'error', null, true);
1328 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1329 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1330
1331 // Existing user competencies sent for review don't change.
1332 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1333 'error', null, true);
1334 $uc->read();
1335 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1336
1337 // A user competency with a status non-idle won't change.
1338 $uc->set_status(\tool_lp\user_competency::STATUS_IN_REVIEW);
1339 $uc->update();
1340 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1341 'error', null, true);
1342 $uc->read();
1343 $this->assertEquals(\tool_lp\user_competency::STATUS_IN_REVIEW, $uc->get_status());
1344 }
1345
4c0e8167
SG
1346 /**
1347 * Test add evidence for existing user_competency.
1348 */
1349 public function test_add_evidence_existing_user_competency() {
1350 $this->resetAfterTest(true);
1351 $dg = $this->getDataGenerator();
1352 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1353
1354 $syscontext = context_system::instance();
1355
1356 // Create users.
1357 $user = $dg->create_user();
1358 $this->setUser($user);
1359
1360 // Create a framework and assign competencies.
1361 $framework = $lpg->create_framework();
1362 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1363 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1364 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1365 $uc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
914b580e
FM
1366 $this->assertSame(null, $uc->get_grade());
1367 $this->assertSame(null, $uc->get_proficiency());
4c0e8167
SG
1368
1369 // Create an evidence and check it was created with the right usercomptencyid and information.
914b580e
FM
1370 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
1371 'invalidevidencedesc', 'tool_lp', array('a' => 'b'), false, 'http://moodle.org', 1, 2);
4c0e8167
SG
1372 $this->assertEquals(1, \tool_lp\evidence::count_records());
1373
1374 $evidence->read();
914b580e 1375 $uc->read();
4c0e8167
SG
1376 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1377 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
1378 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
1379 $this->assertEquals((object) array('a' => 'b'), $evidence->get_desca());
914b580e
FM
1380 $this->assertEquals('http://moodle.org', $evidence->get_url());
1381 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1382 $this->assertEquals(2, $evidence->get_actionuserid());
4c0e8167 1383 $this->assertEquals(1, $evidence->get_grade());
914b580e
FM
1384 $this->assertEquals(1, $uc->get_grade());
1385 $this->assertEquals(0, $uc->get_proficiency());
4c0e8167
SG
1386 }
1387
1388 /**
914b580e 1389 * Test add evidence for non-existing user_competency.
4c0e8167
SG
1390 */
1391 public function test_add_evidence_no_existing_user_competency() {
1392 $this->resetAfterTest(true);
1393 $dg = $this->getDataGenerator();
1394 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1395
1396 $syscontext = context_system::instance();
1397
1398 // Create users.
1399 $user = $dg->create_user();
1400 $this->setUser($user);
1401
1402 // Create a framework and assign competencies.
1403 $framework = $lpg->create_framework();
1404 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1405 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
914b580e 1406 $this->assertEquals(0, \tool_lp\user_competency::count_records());
4c0e8167 1407
914b580e
FM
1408 // Create an evidence without a user competency record.
1409 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
1410 'invalidevidencedesc', 'tool_lp', 'Hello world!', false, 'http://moodle.org', 1, 2);
4c0e8167 1411 $this->assertEquals(1, \tool_lp\evidence::count_records());
914b580e 1412 $this->assertEquals(1, \tool_lp\user_competency::count_records());
4c0e8167 1413
914b580e
FM
1414 $uc = \tool_lp\user_competency::get_record(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
1415 $evidence->read();
1416 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1417 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
1418 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
1419 $this->assertEquals('Hello world!', $evidence->get_desca());
1420 $this->assertEquals('http://moodle.org', $evidence->get_url());
1421 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1422 $this->assertEquals(2, $evidence->get_actionuserid());
1423 $this->assertEquals(1, $evidence->get_grade());
1424 $this->assertEquals(1, $uc->get_grade());
1425 $this->assertEquals(0, $uc->get_proficiency());
1426 }
1427
1428 public function test_observe_course_completed() {
1429 $this->resetAfterTest(true);
1430 $dg = $this->getDataGenerator();
1431 $lpg = $dg->get_plugin_generator('tool_lp');
1432
1433 // Set-up users, framework, competencies and course competencies.
1434 $course = $dg->create_course();
1435 $coursectx = context_course::instance($course->id);
1436 $u1 = $dg->create_user();
1437 $f1 = $lpg->create_framework();
1438 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1439 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1440 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1441 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1442 $cc1 = $lpg->create_course_competency(array('competencyid' => $c1->get_id(), 'courseid' => $course->id,
1443 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_NONE));
1444 $cc2 = $lpg->create_course_competency(array('competencyid' => $c2->get_id(), 'courseid' => $course->id,
1445 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_EVIDENCE));
1446 $cc3 = $lpg->create_course_competency(array('competencyid' => $c3->get_id(), 'courseid' => $course->id,
1447 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_RECOMMEND));
1448 $cc4 = $lpg->create_course_competency(array('competencyid' => $c4->get_id(), 'courseid' => $course->id,
1449 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_COMPLETE));
1450
1451 $event = \core\event\course_completed::create(array(
1452 'objectid' => 1,
1453 'relateduserid' => $u1->id,
1454 'context' => $coursectx,
1455 'courseid' => $course->id,
1456 'other' => array('relateduserid' => $u1->id)
1457 ));
1458 $this->assertEquals(0, \tool_lp\user_competency::count_records());
1459 $this->assertEquals(0, \tool_lp\evidence::count_records());
1460
1461 // Let's go!
1462 api::observe_course_completed($event);
1463 $this->assertEquals(3, \tool_lp\user_competency::count_records());
1464 $this->assertEquals(3, \tool_lp\evidence::count_records());
1465
1466 // Outcome NONE did nothing.
1467 $this->assertFalse(\tool_lp\user_competency::record_exists_select('userid = :uid AND competencyid = :cid', array(
1468 'uid' => $u1->id, 'cid' => $c1->get_id()
1469 )));
1470
1471 // Outcome evidence.
1472 $uc2 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1473 $ev2 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc2->get_id()));
1474
1475 $this->assertEquals(null, $uc2->get_grade());
1476 $this->assertEquals(null, $uc2->get_proficiency());
1477 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc2->get_status());
1478
1479 $this->assertEquals('evidence_coursecompleted', $ev2->get_descidentifier());
1480 $this->assertEquals('tool_lp', $ev2->get_desccomponent());
1481 $this->assertEquals($course->shortname, $ev2->get_desca());
1482 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev2->get_url());
1483 $this->assertEquals(null, $ev2->get_grade());
1484 $this->assertEquals($coursectx->id, $ev2->get_contextid());
1485 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev2->get_action());
1486 $this->assertEquals(null, $ev2->get_actionuserid());
1487
1488 // Outcome recommend.
1489 $uc3 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id()));
1490 $ev3 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc3->get_id()));
1491
1492 $this->assertEquals(null, $uc3->get_grade());
1493 $this->assertEquals(null, $uc3->get_proficiency());
1494 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc3->get_status());
1495
1496 $this->assertEquals('evidence_coursecompleted', $ev3->get_descidentifier());
1497 $this->assertEquals('tool_lp', $ev3->get_desccomponent());
1498 $this->assertEquals($course->shortname, $ev3->get_desca());
1499 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev3->get_url());
1500 $this->assertEquals(null, $ev3->get_grade());
1501 $this->assertEquals($coursectx->id, $ev3->get_contextid());
1502 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev3->get_action());
1503 $this->assertEquals(null, $ev3->get_actionuserid());
1504
1505 // Outcome complete.
1506 $uc4 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4->get_id()));
1507 $ev4 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc4->get_id()));
1508
1509 $this->assertEquals(3, $uc4->get_grade());
1510 $this->assertEquals(1, $uc4->get_proficiency());
1511 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc4->get_status());
1512
1513 $this->assertEquals('evidence_coursecompleted', $ev4->get_descidentifier());
1514 $this->assertEquals('tool_lp', $ev4->get_desccomponent());
1515 $this->assertEquals($course->shortname, $ev4->get_desca());
1516 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev4->get_url());
1517 $this->assertEquals(3, $ev4->get_grade());
1518 $this->assertEquals($coursectx->id, $ev4->get_contextid());
1519 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $ev4->get_action());
1520 $this->assertEquals(null, $ev4->get_actionuserid());
4c0e8167 1521 }
d4c0a2f6
SG
1522
1523 /**
1524 * Test update ruleoutcome for course_competency.
1525 */
d660824b 1526 public function test_set_ruleoutcome_course_competency() {
d4c0a2f6
SG
1527 $this->resetAfterTest(true);
1528 $dg = $this->getDataGenerator();
1529 $lpg = $dg->get_plugin_generator('tool_lp');
1530 $u1 = $dg->create_user();
1531 $u2 = $dg->create_user();
d660824b 1532 $course = $dg->create_course();
d4c0a2f6
SG
1533
1534 $this->setAdminUser();
1535 $f = $lpg->create_framework();
1536 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
d660824b 1537 $cc = api::add_competency_to_course($course->id, $c->get_id());
d4c0a2f6
SG
1538
1539 // Check record was created with default rule value Evidence.
1540 $this->assertEquals(1, \tool_lp\course_competency::count_records());
d660824b
FM
1541 $recordscc = api::list_course_competencies($course->id);
1542 $this->assertEquals(\tool_lp\course_competency::OUTCOME_EVIDENCE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
1543
1544 // Check ruleoutcome value is updated to None.
d660824b
FM
1545 $this->assertTrue(api::set_course_competency_ruleoutcome($recordscc[0]['coursecompetency']->get_id(),
1546 \tool_lp\course_competency::OUTCOME_NONE));
1547 $recordscc = api::list_course_competencies($course->id);
1548 $this->assertEquals(\tool_lp\course_competency::OUTCOME_NONE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
1549 }
1550
4de456cd
SG
1551 /**
1552 * Test validation on grade on user_competency.
1553 */
1554 public function test_validate_grade_in_user_competency() {
1555 global $DB;
1556
1557 $this->resetAfterTest(true);
1558 $this->setAdminUser();
1559 $dg = $this->getDataGenerator();
1560 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1561 $user = $dg->create_user();
1562
1563 $dg->create_scale(array("id" => "1", "scale" => "value1, value2"));
1564 $dg->create_scale(array("id" => "2", "scale" => "value3, value4, value5, value6"));
1565
1566 $scaleconfiguration1 = '[{"scaleid":"1"},{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .
1567 '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';
1568 $scaleconfiguration2 = '[{"scaleid":"2"},{"name":"value3","id":1,"scaledefault":1,"proficient":0},'
1569 . '{"name":"value4","id":2,"scaledefault":0,"proficient":1},'
1570 . '{"name":"value5","id":3,"scaledefault":0,"proficient":0},'
1571 . '{"name":"value6","id":4,"scaledefault":0,"proficient":0}]';
1572
1573 // Create a framework with scale configuration1.
1574 $frm = array(
1575 'scaleid' => 1,
1576 'scaleconfiguration' => $scaleconfiguration1
1577 );
1578 $framework = $lpg->create_framework($frm);
1579 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1580
1581 // Create competency with its own scale configuration.
1582 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
1583 'scaleid' => 2,
1584 'scaleconfiguration' => $scaleconfiguration2
1585 ));
1586
1587 // Detecte invalid grade in competency using its framework competency scale.
1588 try {
1589 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1590 'proficiency' => true, 'grade' => 3 ));
1591 $usercompetency->create();
1592 $this->fail('Invalid grade not detected in framework scale');
1593 } catch (\tool_lp\invalid_persistent_exception $e) {
1594 $this->assertTrue(true);
1595 }
1596
1597 // Detecte invalid grade in competency using its own scale.
1598 try {
1599 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1600 'proficiency' => true, 'grade' => 5 ));
1601 $usercompetency->create();
1602 $this->fail('Invalid grade not detected in competency scale');
1603 } catch (\tool_lp\invalid_persistent_exception $e) {
1604 $this->assertTrue(true);
1605 }
1606
1607 // Accept valid grade in competency using its framework competency scale.
1608 try {
1609 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1610 'proficiency' => true, 'grade' => 1 ));
1611 $usercompetency->create();
1612 $this->assertTrue(true);
1613 } catch (\tool_lp\invalid_persistent_exception $e) {
1614 $this->fail('Valide grade rejected in framework scale');
1615 }
1616
1617 // Accept valid grade in competency using its framework competency scale.
1618 try {
1619 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1620 'proficiency' => true, 'grade' => 4 ));
1621 $usercompetency->create();
1622 $this->assertTrue(true);
1623 } catch (\tool_lp\invalid_persistent_exception $e) {
1624 var_dump($e);
1625 $this->fail('Valide grade rejected in competency scale');
1626 }
1627 }
1628
964afa98
IT
1629 /**
1630 * Test when adding competency that belong to hidden framework to plan/template/course.
1631 */
1632 public function test_hidden_framework() {
1633 $this->resetAfterTest(true);
1634 $this->setAdminUser();
1635 $dg = $this->getDataGenerator();
1636 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1637 $user = $dg->create_user();
1638
1639 // Create a course.
1640 $cat1 = $dg->create_category();
1641 $course = $dg->create_course(array('category' => $cat1->id));
1642 // Create a template.
1643 $template = $lpg->create_template();
1644 // Create a plan.
1645 $plan = $lpg->create_plan(array('userid' => $user->id));
1646
1647 // Create a hidden framework.
1648 $frm = array(
1649 'visible' => false
1650 );
1651 $framework = $lpg->create_framework($frm);
1652 $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1653
1654 // Linking competency that belong to hidden framework to course.
1655 try {
1656 api::add_competency_to_course($course->id, $competency->get_id());
1657 $this->fail('A competency belonging to hidden framework can not be linked to course');
1658 } catch (coding_exception $e) {
1659 $this->assertTrue(true);
1660 }
1661
1662 // Adding competency that belong to hidden framework to template.
1663 try {
1664 api::add_competency_to_template($template->get_id(), $competency->get_id());
1665 $this->fail('A competency belonging to hidden framework can not be added to template');
1666 } catch (coding_exception $e) {
1667 $this->assertTrue(true);
1668 }
1669
1670 // Adding competency that belong to hidden framework to plan.
1671 try {
1672 api::add_competency_to_plan($plan->get_id(), $competency->get_id());
1673 $this->fail('A competency belonging to hidden framework can not be added to plan');
1674 } catch (coding_exception $e) {
1675 $this->assertTrue(true);
1676 }
1677 }
1678
1679 /**
1680 * Test when using hidden template in plan/cohort.
1681 */
1682 public function test_hidden_template() {
1683 $this->resetAfterTest(true);
1684 $this->setAdminUser();
1685 $dg = $this->getDataGenerator();
1686 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1687 $user = $dg->create_user();
1688
1689 // Create a cohort.
1690 $cohort = $dg->create_cohort();
1691 // Create a hidden template.
1692 $template = $lpg->create_template(array('visible' => false));
1693
1694 // Can not link hidden template to plan.
1695 try {
1696 api::create_plan_from_template($template->get_id(), $user->id);
1697 $this->fail('Can not link a hidden template to plan');
1698 } catch (coding_exception $e) {
1699 $this->assertTrue(true);
1700 }
1701
1702 // Can associate hidden template to cohort.
1703 $templatecohort = api::create_template_cohort($template->get_id(), $cohort->id);
1704 $this->assertInstanceOf('\tool_lp\template_cohort', $templatecohort);
1705 }
1706
d3275795
SG
1707 /**
1708 * Test that completed plan created form a template does not change when template is modified.
1709 */
1710 public function test_completed_plan_doesnot_change() {
1711 global $DB;
1712
1713 $this->resetAfterTest(true);
1714 $this->setAdminUser();
1715 $dg = $this->getDataGenerator();
1716 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1717 $user = $dg->create_user();
1718
1719 // Create a framework and assign competencies.
1720 $framework = $lpg->create_framework();
1721 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1722 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1723 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1724 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1725
1726 // Create template and assign competencies.
1727 $tp = $lpg->create_template();
1728 $tpc1 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c1->get_id()));
1729 $tpc2 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c2->get_id()));
1730 $tpc3 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c3->get_id()));
1731
1732 // Create a plan form template and change it status to complete.
1733 $plan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tp->get_id()));
1734 api::complete_plan($plan);
1735
1736 // Check user competency plan created correctly.
1737 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
1738 $ucp = \tool_lp\user_competency_plan::get_records();
1739 $this->assertEquals($ucp[0]->get_competencyid(), $c1->get_id());
1740 $this->assertEquals($ucp[1]->get_competencyid(), $c2->get_id());
1741 $this->assertEquals($ucp[2]->get_competencyid(), $c3->get_id());
1742
1743 // Add and remove a competency from the template.
1744 api::add_competency_to_template($tp->get_id(), $c4->get_id());
1745 api::remove_competency_from_template($tp->get_id(), $c1->get_id());
1746
1747 // Check that user competency plan did not change.
1748 $competencies = $plan->get_competencies();
1749 $this->assertEquals(3, count($competencies));
1750 $ucp1 = array($c1->get_id(), $c2->get_id(), $c3->get_id());
1751 $ucp2 = array();
1752 foreach ($competencies as $id => $cmp) {
1753 $ucp2[] = $id;
1754 }
1755 $this->assertEquals(0, count(array_diff($ucp1, $ucp2)));
1756 }
f610a957 1757}