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