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