MDL-53070 tool_lp: Fix missing capabilities
[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;
90c7bdaf 30use tool_lp\competency_framework;
9373acf6 31use tool_lp\evidence;
4de456cd 32use tool_lp\user_competency;
a8902ee2 33use tool_lp\plan;
f610a957
FM
34
35/**
36 * API tests.
37 *
38 * @package tool_lp
39 * @copyright 2015 Frédéric Massart - FMCorz.net
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 */
42class tool_lp_api_testcase extends advanced_testcase {
43
44 public function test_get_framework_related_contexts() {
45 $this->resetAfterTest(true);
46 $dg = $this->getDataGenerator();
47 $cat1 = $dg->create_category();
48 $cat2 = $dg->create_category(array('parent' => $cat1->id));
49 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 50 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
51
52 $cat1ctx = context_coursecat::instance($cat1->id);
53 $cat2ctx = context_coursecat::instance($cat2->id);
54 $cat3ctx = context_coursecat::instance($cat3->id);
55 $sysctx = context_system::instance();
56
57 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 58 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
f610a957
FM
59
60 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
f0da26a4 61 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
f610a957
FM
62
63 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
f0da26a4 64 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
f610a957
FM
65 }
66
67 public function test_get_framework_related_contexts_with_capabilities() {
68 $this->resetAfterTest(true);
69 $dg = $this->getDataGenerator();
70 $user = $dg->create_user();
71 $cat1 = $dg->create_category();
72 $cat2 = $dg->create_category(array('parent' => $cat1->id));
73 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 74 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
75
76 $cat1ctx = context_coursecat::instance($cat1->id);
77 $cat2ctx = context_coursecat::instance($cat2->id);
78 $cat3ctx = context_coursecat::instance($cat3->id);
79 $sysctx = context_system::instance();
80
81 $roleallow = create_role('Allow', 'allow', 'Allow read');
82 assign_capability('tool/lp:competencyread', CAP_ALLOW, $roleallow, $sysctx->id);
83 role_assign($roleallow, $user->id, $sysctx->id);
84
85 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
86 assign_capability('tool/lp:competencyread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
87 role_assign($roleprevent, $user->id, $cat2ctx->id);
88
89 accesslib_clear_all_caches_for_unit_testing();
90 $this->setUser($user);
91 $this->assertFalse(has_capability('tool/lp:competencyread', $cat2ctx));
92
93 $requiredcap = array('tool/lp:competencyread');
94
95 $expected = array();
f0da26a4 96 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
f610a957
FM
97
98 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 99 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
f610a957
FM
100
101 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
f0da26a4 102 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
f610a957 103 }
f0da26a4
FM
104
105 public function test_get_template_related_contexts() {
106 $this->resetAfterTest(true);
107 $dg = $this->getDataGenerator();
108 $cat1 = $dg->create_category();
109 $cat2 = $dg->create_category(array('parent' => $cat1->id));
110 $cat3 = $dg->create_category(array('parent' => $cat2->id));
111 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
112
113 $cat1ctx = context_coursecat::instance($cat1->id);
114 $cat2ctx = context_coursecat::instance($cat2->id);
115 $cat3ctx = context_coursecat::instance($cat3->id);
116 $sysctx = context_system::instance();
117
118 $expected = array($cat1ctx->id => $cat1ctx);
119 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
120
121 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
122 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
123
124 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
125 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
126 }
127
128 public function test_get_template_related_contexts_with_capabilities() {
129 $this->resetAfterTest(true);
130 $dg = $this->getDataGenerator();
131 $user = $dg->create_user();
132 $cat1 = $dg->create_category();
133 $cat2 = $dg->create_category(array('parent' => $cat1->id));
134 $cat3 = $dg->create_category(array('parent' => $cat2->id));
135 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
136
137 $cat1ctx = context_coursecat::instance($cat1->id);
138 $cat2ctx = context_coursecat::instance($cat2->id);
139 $cat3ctx = context_coursecat::instance($cat3->id);
140 $sysctx = context_system::instance();
141
142 $roleallow = create_role('Allow', 'allow', 'Allow read');
143 assign_capability('tool/lp:templateread', CAP_ALLOW, $roleallow, $sysctx->id);
144 role_assign($roleallow, $user->id, $sysctx->id);
145
146 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
147 assign_capability('tool/lp:templateread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
148 role_assign($roleprevent, $user->id, $cat2ctx->id);
149
150 accesslib_clear_all_caches_for_unit_testing();
151 $this->setUser($user);
152 $this->assertFalse(has_capability('tool/lp:templateread', $cat2ctx));
153
154 $requiredcap = array('tool/lp:templateread');
155
156 $expected = array();
157 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
158
159 $expected = array($cat1ctx->id => $cat1ctx);
160 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
161
162 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
163 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
164 }
165
ec324dc6
FM
166 /**
167 * Test updating a template.
168 */
169 public function test_update_template() {
170 $cat = $this->getDataGenerator()->create_category();
171 $this->resetAfterTest(true);
172 $this->setAdminUser();
173
174 $syscontext = context_system::instance();
175 $template = api::create_template((object) array('shortname' => 'testing', 'contextid' => $syscontext->id));
176
177 $this->assertEquals('testing', $template->get_shortname());
178 $this->assertEquals($syscontext->id, $template->get_contextid());
179
180 // Simple update.
181 api::update_template((object) array('id' => $template->get_id(), 'shortname' => 'success'));
182 $template = api::read_template($template->get_id());
183 $this->assertEquals('success', $template->get_shortname());
184
185 // Trying to change the context.
186 $this->setExpectedException('coding_exception');
187 api::update_template((object) array('id' => $template->get_id(), 'contextid' => context_coursecat::instance($cat->id)));
188 }
189
b3979696
IT
190 /**
191 * Test listing framework with order param.
192 */
193 public function test_list_frameworks() {
194 $this->resetAfterTest(true);
195 $this->setAdminUser();
bf61cd0c 196 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
b3979696
IT
197
198 // Create a list of frameworks.
bf61cd0c
FM
199 $framework1 = $lpg->create_framework(array(
200 'shortname' => 'shortname_a',
201 'idnumber' => 'idnumber_c',
202 'description' => 'description',
203 'descriptionformat' => FORMAT_HTML,
204 'visible' => true,
205 'contextid' => context_system::instance()->id
206 ));
207
208 $framework2 = $lpg->create_framework(array(
209 'shortname' => 'shortname_b',
210 'idnumber' => 'idnumber_a',
211 'description' => 'description',
212 'descriptionformat' => FORMAT_HTML,
213 'visible' => true,
214 'contextid' => context_system::instance()->id
215 ));
216
217 $framework3 = $lpg->create_framework(array(
218 'shortname' => 'shortname_c',
219 'idnumber' => 'idnumber_b',
220 'description' => 'description',
221 'descriptionformat' => FORMAT_HTML,
222 'visible' => true,
223 'contextid' => context_system::instance()->id
224 ));
b3979696
IT
225
226 // Get frameworks list order by shortname desc.
227 $result = api::list_frameworks('shortname', 'DESC', null, 3, context_system::instance());
228
1896274f
FM
229 $f = (object) array_shift($result);
230 $this->assertEquals($framework3->get_id(), $f->get_id());
231 $f = (object) array_shift($result);
232 $this->assertEquals($framework2->get_id(), $f->get_id());
233 $f = (object) array_shift($result);
234 $this->assertEquals($framework1->get_id(), $f->get_id());
b3979696
IT
235
236 // Get frameworks list order by idnumber asc.
237 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance());
238
1896274f
FM
239 $f = (object) array_shift($result);
240 $this->assertEquals($framework2->get_id(), $f->get_id());
241 $f = (object) array_shift($result);
242 $this->assertEquals($framework3->get_id(), $f->get_id());
243 $f = (object) array_shift($result);
244 $this->assertEquals($framework1->get_id(), $f->get_id());
b3979696
IT
245 }
246
c61db7bb
IT
247 /**
248 * Test duplicate a framework.
249 */
250 public function test_duplicate_framework() {
251 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
252 $this->resetAfterTest(true);
253 $this->setAdminUser();
254
255 $syscontext = context_system::instance();
256 $params = array(
257 'shortname' => 'shortname_a',
258 'idnumber' => 'idnumber_c',
259 'description' => 'description',
260 'descriptionformat' => FORMAT_HTML,
261 'visible' => true,
262 'contextid' => $syscontext->id
263 );
264 $framework = $lpg->create_framework($params);
265 $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
266 $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
267 $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
268 $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
4c4a8d41
IT
269 $competency41 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
270 'parentid' => $competency4->get_id())
271 );
272 $competency42 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
273 'parentid' => $competency4->get_id())
274 );
c61db7bb
IT
275 $competencyidnumbers = array($competency1->get_idnumber(),
276 $competency2->get_idnumber(),
277 $competency3->get_idnumber(),
4c4a8d41
IT
278 $competency4->get_idnumber(),
279 $competency41->get_idnumber(),
280 $competency42->get_idnumber()
c61db7bb
IT
281 );
282
4c4a8d41
IT
283 $config = json_encode(array(
284 'base' => array('points' => 4),
285 'competencies' => array(
286 array('id' => $competency41->get_id(), 'points' => 3, 'required' => 0),
287 array('id' => $competency42->get_id(), 'points' => 2, 'required' => 1),
288 )
289 ));
290 $competency4->set_ruletype('tool_lp\competency_rule_points');
291 $competency4->set_ruleoutcome(\tool_lp\competency::OUTCOME_EVIDENCE);
292 $competency4->set_ruleconfig($config);
293 $competency4->update();
294
c61db7bb
IT
295 api::add_related_competency($competency1->get_id(), $competency2->get_id());
296 api::add_related_competency($competency3->get_id(), $competency4->get_id());
297
298 $frameworkduplicated1 = api::duplicate_framework($framework->get_id());
299 $frameworkduplicated2 = api::duplicate_framework($framework->get_id());
300
301 $this->assertEquals($framework->get_idnumber().'_1', $frameworkduplicated1->get_idnumber());
302 $this->assertEquals($framework->get_idnumber().'_2', $frameworkduplicated2->get_idnumber());
303
304 $competenciesfr1 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated1->get_id()));
305 $competenciesfr2 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated2->get_id()));
306
307 $competencyidsfr1 = array();
308 $competencyidsfr2 = array();
309
310 foreach ($competenciesfr1 as $cmp) {
311 $competencyidsfr1[] = $cmp->get_idnumber();
312 }
313 foreach ($competenciesfr2 as $cmp) {
314 $competencyidsfr2[] = $cmp->get_idnumber();
315 }
316
317 $this->assertEmpty(array_diff($competencyidsfr1, $competencyidnumbers));
318 $this->assertEmpty(array_diff($competencyidsfr2, $competencyidnumbers));
4c4a8d41
IT
319 $this->assertCount(6, $competenciesfr1);
320 $this->assertCount(6, $competenciesfr2);
c61db7bb
IT
321
322 // Test the related competencies.
323 reset($competenciesfr1);
324 $compduplicated1 = current($competenciesfr1);
325 $relatedcompetencies = $compduplicated1->get_related_competencies();
326 $comprelated = current($relatedcompetencies);
327 $this->assertEquals($comprelated->get_idnumber(), $competency2->get_idnumber());
5a4ee001 328
4c4a8d41
IT
329 // Check if config rule have been ported correctly.
330 $competency4duplicated = competency::get_record(array(
331 'idnumber' => $competency4->get_idnumber(),
332 'competencyframeworkid' => $frameworkduplicated2->get_id()
333 ));
334 $configduplicated = json_decode($competency4duplicated->get_ruleconfig(), true);
335 $configorigin = json_decode($config, true);
336 // Check that the 2 config have the same base.
337 $this->assertEquals($configorigin['base'], $configduplicated['base']);
338 $this->assertEquals(count($configorigin['competencies']), count($configduplicated['competencies']));
9a325eda 339 $competencyidsrules = array();
4c4a8d41
IT
340 foreach ($configduplicated['competencies'] as $key => $value) {
341 // Check that the only difference between the 2 config is id competency.
342 $this->assertEquals(1, count(array_diff($value, $configorigin['competencies'][$key])));
9a325eda 343 $competencyidsrules[] = $value['id'];
4c4a8d41 344 }
9a325eda 345 $this->assertTrue($competency4duplicated->is_parent_of($competencyidsrules));
5a4ee001 346
20e75095
IT
347 // Test duplicate an empty framework.
348 $emptyfrm = $lpg->create_framework();
349 $emptyfrmduplicated = api::duplicate_framework($emptyfrm->get_id());
350 $this->assertEquals($emptyfrm->get_idnumber().'_1', $emptyfrmduplicated->get_idnumber());
351 $nbcomp = api::count_competencies(array('competencyframeworkid' => $emptyfrmduplicated->get_id()));
352 $this->assertEquals(0, $nbcomp);
353
c61db7bb
IT
354 }
355
58405003
IT
356 /**
357 * Test update plan.
358 */
359 public function test_update_plan() {
360 $this->resetAfterTest(true);
361 $dg = $this->getDataGenerator();
362 $usermanageowndraft = $dg->create_user();
363 $usermanageown = $dg->create_user();
364 $usermanagedraft = $dg->create_user();
365 $usermanage = $dg->create_user();
366
367 $syscontext = context_system::instance();
368
369 // Creating specific roles.
370 $manageowndraftrole = $dg->create_role(array(
371 'name' => 'User manage own draft',
372 'shortname' => 'manage-own-draft'
373 ));
374 $manageownrole = $dg->create_role(array(
375 'name' => 'User manage own',
376 'shortname' => 'manage-own'
377 ));
378 $managedraftrole = $dg->create_role(array(
379 'name' => 'User manage draft',
380 'shortname' => 'manage-draft'
381 ));
382 $managerole = $dg->create_role(array(
383 'name' => 'User manage',
384 'shortname' => 'manage'
385 ));
386
387 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
388 assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
389
390 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id);
391 assign_capability('tool/lp:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id);
392
393 assign_capability('tool/lp:planmanagedraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
394 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
395
396 assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
397 assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
398
399 $dg->role_assign($manageowndraftrole, $usermanageowndraft->id, $syscontext->id);
400 $dg->role_assign($manageownrole, $usermanageown->id, $syscontext->id);
401 $dg->role_assign($managedraftrole, $usermanagedraft->id, $syscontext->id);
402 $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
403
404 // Create first learning plan with user create draft.
405 $this->setUser($usermanageowndraft);
406 $plan = array (
407 'name' => 'plan own draft',
408 'description' => 'plan own draft',
409 'userid' => $usermanageowndraft->id
410 );
411 $plan = api::create_plan((object)$plan);
412 $record = $plan->to_record();
413 $record->name = 'plan own draft modified';
414
415 // Check if user create draft can edit the plan name.
416 $plan = api::update_plan($record);
417 $this->assertInstanceOf('\tool_lp\plan', $plan);
418
3c230247 419 // The status cannot be changed in this method.
58405003
IT
420 $record->status = \tool_lp\plan::STATUS_ACTIVE;
421 try {
422 $plan = api::update_plan($record);
3c230247
FM
423 $this->fail('Updating the status is not allowed.');
424 } catch (coding_exception $e) {
425 $this->assertRegExp('/To change the status of a plan use the appropriate methods./', $e->getMessage());
58405003
IT
426 }
427
428 // Test when user with manage own plan capability try to edit other user plan.
429 $record->status = \tool_lp\plan::STATUS_DRAFT;
430 $record->name = 'plan create draft modified 2';
431 $this->setUser($usermanageown);
432 try {
433 $plan = api::update_plan($record);
434 $this->fail('User with manage own plan capability can only edit his own plan.');
435 } catch (required_capability_exception $e) {
436 $this->assertTrue(true);
437 }
438
439 // User with manage plan capability cannot edit the other user plans with status draft.
440 $this->setUser($usermanage);
3c230247 441 $record->name = 'plan create draft modified 3';
58405003
IT
442 try {
443 $plan = api::update_plan($record);
444 $this->fail('User with manage plan capability cannot edit the other user plans with status draft');
445 } catch (required_capability_exception $e) {
446 $this->assertTrue(true);
447 }
448
449 // User with manage draft capability can edit other user's learning plan if the status is draft.
450 $this->setUser($usermanagedraft);
451 $record->status = \tool_lp\plan::STATUS_DRAFT;
452 $record->name = 'plan manage draft modified 3';
453 $plan = api::update_plan($record);
454 $this->assertInstanceOf('\tool_lp\plan', $plan);
455
456 // User with manage plan capability can create/edit learning plan if status is active/complete.
457 $this->setUser($usermanage);
458 $plan = array (
459 'name' => 'plan create',
460 'description' => 'plan create',
461 'userid' => $usermanage->id,
462 'status' => \tool_lp\plan::STATUS_ACTIVE
463 );
464 $plan = api::create_plan((object)$plan);
5bfab685
FM
465
466 // Silently transition to complete status to avoid errors about transitioning to complete.
467 $plan->set_status(\tool_lp\plan::STATUS_COMPLETE);
468 $plan->update();
469
58405003
IT
470 $record = $plan->to_record();
471 $record->name = 'plan create own modified';
d805cc37
IT
472 try {
473 api::update_plan($record);
474 $this->fail('Completed plan can not be edited');
475 } catch (coding_exception $e) {
476 $this->assertTrue(true);
477 }
58405003
IT
478 }
479
2388d46d
FM
480 public function test_create_plan_from_template() {
481 $this->resetAfterTest(true);
482 $this->setAdminUser();
483
484 $u1 = $this->getDataGenerator()->create_user();
485 $tpl = $this->getDataGenerator()->get_plugin_generator('tool_lp')->create_template();
486
487 // Creating a new plan.
488 $plan = api::create_plan_from_template($tpl, $u1->id);
489 $record = $plan->to_record();
490 $this->assertInstanceOf('\tool_lp\plan', $plan);
491 $this->assertTrue(\tool_lp\plan::record_exists($plan->get_id()));
492 $this->assertEquals($tpl->get_id(), $plan->get_templateid());
493 $this->assertEquals($u1->id, $plan->get_userid());
494 $this->assertTrue($plan->is_based_on_template());
495
496 // Creating a plan that already exists.
497 $plan = api::create_plan_from_template($tpl, $u1->id);
498 $this->assertFalse($plan);
499
500 // Check that api::create_plan cannot be used.
501 $this->setExpectedException('coding_exception');
502 unset($record->id);
503 $plan = api::create_plan($record);
504 }
505
4de877eb
FM
506 public function test_update_plan_based_on_template() {
507 $this->resetAfterTest(true);
508 $dg = $this->getDataGenerator();
509 $lpg = $dg->get_plugin_generator('tool_lp');
510 $u1 = $dg->create_user();
511 $u2 = $dg->create_user();
512
513 $this->setAdminUser();
514 $tpl1 = $lpg->create_template();
515 $tpl2 = $lpg->create_template();
516 $up1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id()));
517 $up2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => null));
518
519 try {
520 // Trying to remove the template dependency.
521 $record = $up1->to_record();
522 $record->templateid = null;
523 api::update_plan($record);
524 $this->fail('A plan cannot be unlinked using api::update_plan()');
525 } catch (coding_exception $e) {
526 }
527
528 try {
529 // Trying to switch to another template.
530 $record = $up1->to_record();
531 $record->templateid = $tpl2->get_id();
532 api::update_plan($record);
533 $this->fail('A plan cannot be moved to another template.');
534 } catch (coding_exception $e) {
535 }
536
537 try {
538 // Trying to switch to using a template.
539 $record = $up2->to_record();
540 $record->templateid = $tpl1->get_id();
541 api::update_plan($record);
542 $this->fail('A plan cannot be update to use a template.');
543 } catch (coding_exception $e) {
544 }
545 }
546
6d2c2e86
FM
547 public function test_unlink_plan_from_template() {
548 $this->resetAfterTest(true);
549 $dg = $this->getDataGenerator();
550 $lpg = $dg->get_plugin_generator('tool_lp');
551 $u1 = $dg->create_user();
552 $u2 = $dg->create_user();
553
554 $this->setAdminUser();
555 $f1 = $lpg->create_framework();
556 $f2 = $lpg->create_framework();
557 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
558 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f2->get_id()));
559 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
560
561 $tpl1 = $lpg->create_template();
562 $tpl2 = $lpg->create_template();
563
564 $tplc1a = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1a->get_id(),
565 'sortorder' => 9));
566 $tplc1b = $lpg->create_template_competency(array('templateid' => $tpl1->get_id(), 'competencyid' => $c1b->get_id(),
567 'sortorder' => 8));
568 $tplc2a = $lpg->create_template_competency(array('templateid' => $tpl2->get_id(), 'competencyid' => $c2a->get_id()));
569
a8902ee2 570 $plan1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_ACTIVE));
6d2c2e86 571 $plan2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => $tpl2->get_id()));
a8902ee2 572 $plan3 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_COMPLETE));
6d2c2e86
FM
573
574 // Check that we have what we expect at this stage.
575 $this->assertEquals(2, \tool_lp\template_competency::count_records(array('templateid' => $tpl1->get_id())));
576 $this->assertEquals(1, \tool_lp\template_competency::count_records(array('templateid' => $tpl2->get_id())));
577 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan1->get_id())));
578 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan2->get_id())));
579 $this->assertTrue($plan1->is_based_on_template());
580 $this->assertTrue($plan2->is_based_on_template());
581
582 // Let's do this!
583 $tpl1comps = \tool_lp\template_competency::list_competencies($tpl1->get_id(), true);
584 $tpl2comps = \tool_lp\template_competency::list_competencies($tpl2->get_id(), true);
585
586 api::unlink_plan_from_template($plan1);
587
588 $plan1->read();
589 $plan2->read();
590 $this->assertCount(2, $tpl1comps);
591 $this->assertCount(1, $tpl2comps);
592 $this->assertEquals(2, \tool_lp\template_competency::count_records(array('templateid' => $tpl1->get_id())));
593 $this->assertEquals(1, \tool_lp\template_competency::count_records(array('templateid' => $tpl2->get_id())));
594 $this->assertEquals(2, \tool_lp\plan_competency::count_records(array('planid' => $plan1->get_id())));
595 $this->assertEquals(0, \tool_lp\plan_competency::count_records(array('planid' => $plan2->get_id())));
596 $this->assertFalse($plan1->is_based_on_template());
597 $this->assertEquals($tpl1->get_id(), $plan1->get_origtemplateid());
598 $this->assertTrue($plan2->is_based_on_template());
599 $this->assertEquals(null, $plan2->get_origtemplateid());
600
a8902ee2
SG
601 // Check we can unlink draft plan.
602 try {
603 api::unlink_plan_from_template($plan2);
604 } catch (coding_exception $e) {
605 $this->fail('Fail to unlink draft plan.');
606 }
607
608 // Check we can not unlink completed plan.
609 try {
610 api::unlink_plan_from_template($plan3);
611 $this->fail('We can not unlink completed plan.');
612 } catch (coding_exception $e) {
613 }
614
6d2c2e86
FM
615 // Even the order remains.
616 $plan1comps = \tool_lp\plan_competency::list_competencies($plan1->get_id());
617 $before = reset($tpl1comps);
618 $after = reset($plan1comps);
619 $this->assertEquals($before->get_id(), $after->get_id());
620 $this->assertEquals($before->get_sortorder(), $after->get_sortorder());
621 $before = next($tpl1comps);
622 $after = next($plan1comps);
623 $this->assertEquals($before->get_id(), $after->get_id());
624 $this->assertEquals($before->get_sortorder(), $after->get_sortorder());
625 }
626
c7999f6d
FM
627 public function test_update_template_updates_plans() {
628 $this->resetAfterTest(true);
629 $this->setAdminUser();
630
631 $dg = $this->getDataGenerator();
632 $u1 = $dg->create_user();
633 $u2 = $dg->create_user();
634 $lpg = $dg->get_plugin_generator('tool_lp');
635 $tpl1 = $lpg->create_template();
636 $tpl2 = $lpg->create_template();
637
c7999f6d
FM
638 // Create plans with data not matching templates.
639 $time = time();
640 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u1->id,
641 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_MARKDOWN));
642 $plan2 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $u2->id,
643 'name' => 'Not right name', 'duedate' => $time + 3601, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
644 $plan3 = $lpg->create_plan(array('templateid' => $tpl2->get_id(), 'userid' => $u1->id,
645 'name' => 'Not sweet name', 'duedate' => $time + 3602, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
646
647 // Prepare our expectations.
648 $plan1->read();
649 $plan2->read();
650 $plan3->read();
651
652 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid());
653 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid());
654 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid());
655 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name());
656 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name());
657 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
658 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description());
659 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description());
660 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
661 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
662 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
663 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
664 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate());
665 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate());
666 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
667
668 // Update the template without changing critical fields does not update the plans.
669 $data = $tpl1->to_record();
670 $data->visible = 0;
671 api::update_template($data);
672 $this->assertNotEquals($tpl1->get_shortname(), $plan1->get_name());
673 $this->assertNotEquals($tpl1->get_shortname(), $plan2->get_name());
674 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
675 $this->assertNotEquals($tpl1->get_description(), $plan1->get_description());
676 $this->assertNotEquals($tpl1->get_description(), $plan2->get_description());
677 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
678 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
679 $this->assertNotEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
680 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
681 $this->assertNotEquals($tpl1->get_duedate(), $plan1->get_duedate());
682 $this->assertNotEquals($tpl1->get_duedate(), $plan2->get_duedate());
683 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
684
685 // Now really update the template.
686 $data = $tpl1->to_record();
687 $data->shortname = 'Awesome!';
688 $data->description = 'This is too awesome!';
689 $data->descriptionformat = FORMAT_HTML;
a967d2aa 690 $data->duedate = $time + 200;
c7999f6d
FM
691 api::update_template($data);
692 $tpl1->read();
693
694 // Now confirm that the right plans were updated.
695 $plan1->read();
696 $plan2->read();
697 $plan3->read();
698
699 $this->assertEquals($tpl1->get_id(), $plan1->get_templateid());
700 $this->assertEquals($tpl1->get_id(), $plan2->get_templateid());
701 $this->assertEquals($tpl2->get_id(), $plan3->get_templateid());
702
703 $this->assertEquals($tpl1->get_shortname(), $plan1->get_name());
704 $this->assertEquals($tpl1->get_shortname(), $plan2->get_name());
705 $this->assertNotEquals($tpl2->get_shortname(), $plan3->get_name());
706 $this->assertEquals($tpl1->get_description(), $plan1->get_description());
707 $this->assertEquals($tpl1->get_description(), $plan2->get_description());
708 $this->assertNotEquals($tpl2->get_description(), $plan3->get_description());
709 $this->assertEquals($tpl1->get_descriptionformat(), $plan1->get_descriptionformat());
710 $this->assertEquals($tpl1->get_descriptionformat(), $plan2->get_descriptionformat());
711 $this->assertNotEquals($tpl2->get_descriptionformat(), $plan3->get_descriptionformat());
712 $this->assertEquals($tpl1->get_duedate(), $plan1->get_duedate());
713 $this->assertEquals($tpl1->get_duedate(), $plan2->get_duedate());
714 $this->assertNotEquals($tpl2->get_duedate(), $plan3->get_duedate());
715 }
716
5bfab685
FM
717 /**
718 * Test that the method to complete a plan.
719 */
720 public function test_complete_plan() {
721 global $DB;
722
723 $this->resetAfterTest(true);
724 $this->setAdminUser();
725 $dg = $this->getDataGenerator();
726 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
727 $user = $dg->create_user();
728
729 // Create a framework and assign competencies.
730 $framework = $lpg->create_framework();
731 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
732 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
733 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
d3275795 734 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
5bfab685
FM
735
736 // Create two plans and assign competencies.
737 $plan = $lpg->create_plan(array('userid' => $user->id));
738 $otherplan = $lpg->create_plan(array('userid' => $user->id));
739
740 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id()));
741 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id()));
742 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id()));
743 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id()));
744
745 $uclist = array(
746 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
747 'proficiency' => true, 'grade' => 1 )),
748 $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
749 'proficiency' => false, 'grade' => 2 ))
750 );
751
752 $this->assertEquals(2, \tool_lp\user_competency::count_records());
753 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
754
755 // Change status of the plan to complete.
756 api::complete_plan($plan);
757
758 // Check that user competencies are now in user_competency_plan objects and still in user_competency.
759 $this->assertEquals(2, \tool_lp\user_competency::count_records());
760 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
761
762 $usercompetenciesplan = \tool_lp\user_competency_plan::get_records();
763
764 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid());
765 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid());
766 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency());
767 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade());
768 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid());
769
770 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid());
771 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid());
772 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency());
773 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade());
774 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid());
775
776 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid());
777 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid());
778 $this->assertNull($usercompetenciesplan[2]->get_proficiency());
779 $this->assertNull($usercompetenciesplan[2]->get_grade());
780 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid());
781
d3275795
SG
782 // Check we can not add competency to completed plan.
783 try {
784 api::add_competency_to_plan($plan->get_id(), $c4->get_id());
785 $this->fail('We can not add competency to completed plan.');
786 } catch (coding_exception $e) {
787 }
788
789 // Check we can not remove competency to completed plan.
790 try {
791 api::remove_competency_from_plan($plan->get_id(), $c3->get_id());
792 $this->fail('We can not remove competency to completed plan.');
793 } catch (coding_exception $e) {
794 }
795
5bfab685
FM
796 // Completing a plan that is completed throws an exception.
797 $this->setExpectedException('coding_exception');
798 api::complete_plan($plan);
799 }
800
3c230247
FM
801 /**
802 * Set-up the workflow data (review, active, ...).
803 *
804 * @return array
805 */
806 protected function setup_workflow_data() {
807 $this->resetAfterTest();
808
809 $dg = $this->getDataGenerator();
810 $user = $dg->create_user();
811 $reviewer = $dg->create_user();
812 $otheruser = $dg->create_user();
813
814 $syscontext = context_system::instance();
815 $userrole = $dg->create_role();
816 $reviewerrole = $dg->create_role();
817 $otheruserrole = $dg->create_role();
818
819 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $userrole, $syscontext->id);
820 assign_capability('tool/lp:planmanage', CAP_ALLOW, $reviewerrole, $syscontext->id);
821 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $reviewerrole, $syscontext->id);
822 $dg->role_assign($userrole, $user->id, $syscontext->id);
823 $dg->role_assign($reviewerrole, $reviewer->id, $syscontext->id);
824 accesslib_clear_all_caches_for_unit_testing();
825
826 $lpg = $dg->get_plugin_generator('tool_lp');
827 $tpl = $lpg->create_template();
828 $plan = $lpg->create_plan(array('userid' => $user->id));
829 $tplplan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tpl->get_id()));
830
831 return array(
832 'dg' => $dg,
833 'lpg' => $lpg,
834 'user' => $user,
835 'reviewer' => $reviewer,
836 'otheruser' => $otheruser,
837 'plan' => $plan,
838 'tplplan' => $tplplan,
839 );
840 }
841
842 /**
843 * Testing requesting the review of a plan.
844 */
845 public function test_plan_request_review() {
846 $data = $this->setup_workflow_data();
847 extract($data);
848
849 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
850 $this->assertEquals(plan::STATUS_DRAFT, $tplplan->get_status());
851
852 // Foreign user cannot do anything.
853 $this->setUser($otheruser);
854 try {
855 api::plan_request_review($plan);
856 $this->fail('The user can not read the plan.');
857 } catch (required_capability_exception $e) {
858 $this->assertEquals('nopermissions', $e->errorcode);
859 }
860
861 // Can not change a plan based on a template.
862 $this->setUser($user);
863 try {
864 api::plan_request_review($tplplan);
865 $this->fail('The plan is based on a template.');
866 } catch (coding_exception $e) {
867 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage());
868 }
869
870 // Can not send for review when not draft.
871 $this->setUser($user);
872 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
873 try {
874 api::plan_request_review($plan);
875 $this->fail('The plan cannot be sent for review at this stage.');
876 } catch (coding_exception $e) {
877 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage());
878 }
879
880 // Can not send for review when not draft.
881 $this->setUser($user);
882 $plan->set_status(plan::STATUS_ACTIVE);
883 try {
884 api::plan_request_review($plan);
885 $this->fail('The plan cannot be sent for review at this stage.');
886 } catch (coding_exception $e) {
887 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage());
888 }
889
890 // Can not send for review when not draft.
891 $this->setUser($user);
892 $plan->set_status(plan::STATUS_IN_REVIEW);
893 try {
894 api::plan_request_review($plan);
895 $this->fail('The plan cannot be sent for review at this stage.');
896 } catch (coding_exception $e) {
897 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage());
898 }
899
900 // Can not send for review when not draft.
901 $this->setUser($user);
902 $plan->set_status(plan::STATUS_COMPLETE);
903 try {
904 api::plan_request_review($plan);
905 $this->fail('The plan cannot be sent for review at this stage.');
906 } catch (coding_exception $e) {
907 $this->assertRegExp('/The plan cannot be sent for review at this stage./', $e->getMessage());
908 }
909
910 // Sending for review as a reviewer.
911 $this->setUser($reviewer);
912 $plan->set_status(plan::STATUS_DRAFT);
913 try {
914 api::plan_request_review($plan);
915 $this->fail('The user can not request a review.');
916 } catch (required_capability_exception $e) {
917 $this->assertEquals('nopermissions', $e->errorcode);
918 }
919
920 // Sending for review.
921 $this->setUser($user);
922 api::plan_request_review($plan);
923 $plan->read();
924 $this->assertEquals(plan::STATUS_WAITING_FOR_REVIEW, $plan->get_status());
925
926 // Sending for review by ID.
927 $plan->set_status(plan::STATUS_DRAFT);
928 $plan->update();
929 api::plan_request_review($plan->get_id());
930 $plan->read();
931 $this->assertEquals(plan::STATUS_WAITING_FOR_REVIEW, $plan->get_status());
932 }
933
934 /**
935 * Testing cancelling the review request.
936 */
937 public function test_plan_cancel_review_request() {
938 $data = $this->setup_workflow_data();
939 extract($data);
940
941 // Set waiting for review.
942 $tplplan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
943 $tplplan->update();
944 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
945 $plan->update();
946
947 // Foreign user cannot do anything.
948 $this->setUser($otheruser);
949 try {
950 api::plan_cancel_review_request($plan);
951 $this->fail('The user can not read the plan.');
952 } catch (required_capability_exception $e) {
953 $this->assertEquals('nopermissions', $e->errorcode);
954 }
955
956 // Can not change a plan based on a template.
957 $this->setUser($user);
958 try {
959 api::plan_cancel_review_request($tplplan);
960 $this->fail('The plan is based on a template.');
961 } catch (coding_exception $e) {
962 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage());
963 }
964
965 // Can not cancel review request when not waiting for review.
966 $this->setUser($user);
967 $plan->set_status(plan::STATUS_DRAFT);
968 try {
969 api::plan_cancel_review_request($plan);
970 $this->fail('The plan cannot be sent for review at this stage.');
971 } catch (coding_exception $e) {
972 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage());
973 }
974
975 // Can not cancel review request when not waiting for review.
976 $this->setUser($user);
977 $plan->set_status(plan::STATUS_IN_REVIEW);
978 try {
979 api::plan_cancel_review_request($plan);
980 $this->fail('The plan review cannot be cancelled at this stage.');
981 } catch (coding_exception $e) {
982 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage());
983 }
984
985 // Can not cancel review request when not waiting for review.
986 $this->setUser($user);
987 $plan->set_status(plan::STATUS_ACTIVE);
988 try {
989 api::plan_cancel_review_request($plan);
990 $this->fail('The plan review cannot be cancelled at this stage.');
991 } catch (coding_exception $e) {
992 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage());
993 }
994
995 // Can not cancel review request when not waiting for review.
996 $this->setUser($user);
997 $plan->set_status(plan::STATUS_COMPLETE);
998 try {
999 api::plan_cancel_review_request($plan);
1000 $this->fail('The plan review cannot be cancelled at this stage.');
1001 } catch (coding_exception $e) {
1002 $this->assertRegExp('/The plan review cannot be cancelled at this stage./', $e->getMessage());
1003 }
1004
1005 // Cancelling as a reviewer.
1006 $this->setUser($reviewer);
1007 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1008 try {
1009 api::plan_cancel_review_request($plan);
1010 $this->fail('The user can not cancel a review request.');
1011 } catch (required_capability_exception $e) {
1012 $this->assertEquals('nopermissions', $e->errorcode);
1013 }
1014
1015 // Cancelling review request.
1016 $this->setUser($user);
1017 api::plan_cancel_review_request($plan);
1018 $plan->read();
1019 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1020
1021 // Cancelling review request by ID.
1022 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1023 $plan->update();
1024 api::plan_cancel_review_request($plan->get_id());
1025 $plan->read();
1026 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1027 }
1028
1029 /**
1030 * Testing starting the review.
1031 */
1032 public function test_plan_start_review() {
1033 $data = $this->setup_workflow_data();
1034 extract($data);
1035
1036 // Set waiting for review.
1037 $tplplan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1038 $tplplan->update();
1039 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1040 $plan->update();
1041
1042 // Foreign user cannot do anything.
1043 $this->setUser($otheruser);
1044 try {
1045 api::plan_start_review($plan);
1046 $this->fail('The user can not read the plan.');
1047 } catch (required_capability_exception $e) {
1048 $this->assertEquals('nopermissions', $e->errorcode);
1049 }
1050
1051 // Can not change a plan based on a template.
1052 $this->setUser($reviewer);
1053 try {
1054 api::plan_start_review($tplplan);
1055 $this->fail('The plan is based on a template.');
1056 } catch (coding_exception $e) {
1057 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage());
1058 }
1059
1060 // Can not start a review when not waiting for review.
1061 $this->setUser($reviewer);
1062 $plan->set_status(plan::STATUS_DRAFT);
1063 try {
1064 api::plan_start_review($plan);
1065 $this->fail('The plan review cannot be started at this stage.');
1066 } catch (coding_exception $e) {
1067 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage());
1068 }
1069
1070 // Can not start a review when not waiting for review.
1071 $this->setUser($reviewer);
1072 $plan->set_status(plan::STATUS_IN_REVIEW);
1073 try {
1074 api::plan_start_review($plan);
1075 $this->fail('The plan review cannot be started at this stage.');
1076 } catch (coding_exception $e) {
1077 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage());
1078 }
1079
1080 // Can not start a review when not waiting for review.
1081 $this->setUser($reviewer);
1082 $plan->set_status(plan::STATUS_ACTIVE);
1083 try {
1084 api::plan_start_review($plan);
1085 $this->fail('The plan review cannot be started at this stage.');
1086 } catch (coding_exception $e) {
1087 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage());
1088 }
1089
1090 // Can not start a review when not waiting for review.
1091 $this->setUser($reviewer);
1092 $plan->set_status(plan::STATUS_COMPLETE);
1093 try {
1094 api::plan_start_review($plan);
1095 $this->fail('The plan review cannot be started at this stage.');
1096 } catch (coding_exception $e) {
1097 $this->assertRegExp('/The plan review cannot be started at this stage./', $e->getMessage());
1098 }
1099
1100 // Starting as the owner.
1101 $this->setUser($user);
1102 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1103 try {
1104 api::plan_start_review($plan);
1105 $this->fail('The user can not start a review.');
1106 } catch (required_capability_exception $e) {
1107 $this->assertEquals('nopermissions', $e->errorcode);
1108 }
1109
1110 // Starting review.
1111 $this->setUser($reviewer);
1112 api::plan_start_review($plan);
1113 $plan->read();
1114 $this->assertEquals(plan::STATUS_IN_REVIEW, $plan->get_status());
1115 $this->assertEquals($reviewer->id, $plan->get_reviewerid());
1116
1117 // Starting review by ID.
1118 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1119 $plan->set_reviewerid(null);
1120 $plan->update();
1121 api::plan_start_review($plan->get_id());
1122 $plan->read();
1123 $this->assertEquals(plan::STATUS_IN_REVIEW, $plan->get_status());
1124 $this->assertEquals($reviewer->id, $plan->get_reviewerid());
1125 }
1126
1127 /**
1128 * Testing stopping the review.
1129 */
1130 public function test_plan_stop_review() {
1131 $data = $this->setup_workflow_data();
1132 extract($data);
1133
1134 // Set waiting for review.
1135 $tplplan->set_status(plan::STATUS_IN_REVIEW);
1136 $tplplan->update();
1137 $plan->set_status(plan::STATUS_IN_REVIEW);
1138 $plan->update();
1139
1140 // Foreign user cannot do anything.
1141 $this->setUser($otheruser);
1142 try {
1143 api::plan_stop_review($plan);
1144 $this->fail('The user can not read the plan.');
1145 } catch (required_capability_exception $e) {
1146 $this->assertEquals('nopermissions', $e->errorcode);
1147 }
1148
1149 // Can not change a plan based on a template.
1150 $this->setUser($reviewer);
1151 try {
1152 api::plan_stop_review($tplplan);
1153 $this->fail('The plan is based on a template.');
1154 } catch (coding_exception $e) {
1155 $this->assertRegExp('/Template plans cannot be reviewed./', $e->getMessage());
1156 }
1157
1158 // Can not stop a review whe not in review.
1159 $this->setUser($reviewer);
1160 $plan->set_status(plan::STATUS_DRAFT);
1161 try {
1162 api::plan_stop_review($plan);
1163 $this->fail('The plan review cannot be stopped at this stage.');
1164 } catch (coding_exception $e) {
1165 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage());
1166 }
1167
1168 // Can not stop a review whe not in review.
1169 $this->setUser($reviewer);
1170 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1171 try {
1172 api::plan_stop_review($plan);
1173 $this->fail('The plan review cannot be stopped at this stage.');
1174 } catch (coding_exception $e) {
1175 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage());
1176 }
1177
1178 // Can not stop a review whe not in review.
1179 $this->setUser($reviewer);
1180 $plan->set_status(plan::STATUS_ACTIVE);
1181 try {
1182 api::plan_stop_review($plan);
1183 $this->fail('The plan review cannot be stopped at this stage.');
1184 } catch (coding_exception $e) {
1185 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage());
1186 }
1187
1188 // Can not stop a review whe not in review.
1189 $this->setUser($reviewer);
1190 $plan->set_status(plan::STATUS_COMPLETE);
1191 try {
1192 api::plan_stop_review($plan);
1193 $this->fail('The plan review cannot be stopped at this stage.');
1194 } catch (coding_exception $e) {
1195 $this->assertRegExp('/The plan review cannot be stopped at this stage./', $e->getMessage());
1196 }
1197
1198 // Stopping as the owner.
1199 $this->setUser($user);
1200 $plan->set_status(plan::STATUS_IN_REVIEW);
1201 try {
1202 api::plan_stop_review($plan);
1203 $this->fail('The user can not stop a review.');
1204 } catch (required_capability_exception $e) {
1205 $this->assertEquals('nopermissions', $e->errorcode);
1206 }
1207
1208 // Stopping review.
1209 $this->setUser($reviewer);
1210 api::plan_stop_review($plan);
1211 $plan->read();
1212 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1213
1214 // Stopping review by ID.
1215 $plan->set_status(plan::STATUS_IN_REVIEW);
1216 $plan->update();
1217 api::plan_stop_review($plan->get_id());
1218 $plan->read();
1219 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1220 }
1221
1222 /**
1223 * Testing approving the plan.
1224 */
1225 public function test_approve_plan() {
1226 $data = $this->setup_workflow_data();
1227 extract($data);
1228
1229 // Set waiting for review.
1230 $tplplan->set_status(plan::STATUS_IN_REVIEW);
1231 $tplplan->update();
1232 $plan->set_status(plan::STATUS_IN_REVIEW);
1233 $plan->update();
1234
1235 // Foreign user cannot do anything.
1236 $this->setUser($otheruser);
1237 try {
1238 api::approve_plan($plan);
1239 $this->fail('The user can not read the plan.');
1240 } catch (required_capability_exception $e) {
1241 $this->assertEquals('nopermissions', $e->errorcode);
1242 }
1243
1244 // Can not change a plan based on a template.
1245 $this->setUser($reviewer);
1246 try {
1247 api::approve_plan($tplplan);
1248 $this->fail('The plan is based on a template.');
1249 } catch (coding_exception $e) {
1250 $this->assertRegExp('/Template plans are already approved./', $e->getMessage());
1251 }
1252
1253 // Can not approve a plan already approved.
1254 $this->setUser($reviewer);
1255 $plan->set_status(plan::STATUS_ACTIVE);
1256 try {
1257 api::approve_plan($plan);
1258 $this->fail('The plan cannot be approved at this stage.');
1259 } catch (coding_exception $e) {
1260 $this->assertRegExp('/The plan cannot be approved at this stage./', $e->getMessage());
1261 }
1262
1263 // Can not approve a plan already approved.
1264 $this->setUser($reviewer);
1265 $plan->set_status(plan::STATUS_COMPLETE);
1266 try {
1267 api::approve_plan($plan);
1268 $this->fail('The plan cannot be approved at this stage.');
1269 } catch (coding_exception $e) {
1270 $this->assertRegExp('/The plan cannot be approved at this stage./', $e->getMessage());
1271 }
1272
1273 // Approve as the owner.
1274 $this->setUser($user);
1275 $plan->set_status(plan::STATUS_IN_REVIEW);
1276 try {
1277 api::approve_plan($plan);
1278 $this->fail('The user can not approve the plan.');
1279 } catch (required_capability_exception $e) {
1280 $this->assertEquals('nopermissions', $e->errorcode);
1281 }
1282
1283 // Approve plan from in review.
1284 $this->setUser($reviewer);
1285 api::approve_plan($plan);
1286 $plan->read();
1287 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status());
1288
1289 // Approve plan by ID.
1290 $plan->set_status(plan::STATUS_IN_REVIEW);
1291 $plan->update();
1292 api::approve_plan($plan->get_id());
1293 $plan->read();
1294 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status());
1295
1296 // Approve plan from draft.
1297 $plan->set_status(plan::STATUS_DRAFT);
1298 $plan->update();
1299 api::approve_plan($plan);
1300 $plan->read();
1301 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status());
1302
1303 // Approve plan from waiting for review.
1304 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1305 $plan->update();
1306 api::approve_plan($plan);
1307 $plan->read();
1308 $this->assertEquals(plan::STATUS_ACTIVE, $plan->get_status());
1309 }
1310
1311 /**
1312 * Testing stopping the review.
1313 */
1314 public function test_unapprove_plan() {
1315 $data = $this->setup_workflow_data();
1316 extract($data);
1317
1318 // Set waiting for review.
1319 $tplplan->set_status(plan::STATUS_ACTIVE);
1320 $tplplan->update();
1321 $plan->set_status(plan::STATUS_ACTIVE);
1322 $plan->update();
1323
1324 // Foreign user cannot do anything.
1325 $this->setUser($otheruser);
1326 try {
1327 api::unapprove_plan($plan);
1328 $this->fail('The user can not read the plan.');
1329 } catch (required_capability_exception $e) {
1330 $this->assertEquals('nopermissions', $e->errorcode);
1331 }
1332
1333 // Can not change a plan based on a template.
1334 $this->setUser($reviewer);
1335 try {
1336 api::unapprove_plan($tplplan);
1337 $this->fail('The plan is based on a template.');
1338 } catch (coding_exception $e) {
1339 $this->assertRegExp('/Template plans are always approved./', $e->getMessage());
1340 }
1341
1342 // Can not unapprove a non-draft plan.
1343 $this->setUser($reviewer);
1344 $plan->set_status(plan::STATUS_DRAFT);
1345 try {
1346 api::unapprove_plan($plan);
1347 $this->fail('The plan cannot be sent back to draft at this stage.');
1348 } catch (coding_exception $e) {
1349 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage());
1350 }
1351
1352 // Can not unapprove a non-draft plan.
1353 $this->setUser($reviewer);
1354 $plan->set_status(plan::STATUS_WAITING_FOR_REVIEW);
1355 try {
1356 api::unapprove_plan($plan);
1357 $this->fail('The plan cannot be sent back to draft at this stage.');
1358 } catch (coding_exception $e) {
1359 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage());
1360 }
1361
1362 // Can not unapprove a non-draft plan.
1363 $this->setUser($reviewer);
1364 $plan->set_status(plan::STATUS_IN_REVIEW);
1365 try {
1366 api::unapprove_plan($plan);
1367 $this->fail('The plan cannot be sent back to draft at this stage.');
1368 } catch (coding_exception $e) {
1369 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage());
1370 }
1371
1372 // Can not unapprove a non-draft plan.
1373 $this->setUser($reviewer);
1374 $plan->set_status(plan::STATUS_COMPLETE);
1375 try {
1376 api::unapprove_plan($plan);
1377 $this->fail('The plan cannot be sent back to draft at this stage.');
1378 } catch (coding_exception $e) {
1379 $this->assertRegExp('/The plan cannot be sent back to draft at this stage./', $e->getMessage());
1380 }
1381
1382 // Unapprove as the owner.
1383 $this->setUser($user);
1384 $plan->set_status(plan::STATUS_ACTIVE);
1385 try {
1386 api::unapprove_plan($plan);
1387 $this->fail('The user can not unapprove the plan.');
1388 } catch (required_capability_exception $e) {
1389 $this->assertEquals('nopermissions', $e->errorcode);
1390 }
1391
1392 // Unapprove plan.
1393 $this->setUser($reviewer);
1394 api::unapprove_plan($plan);
1395 $plan->read();
1396 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1397
1398 // Unapprove plan by ID.
1399 $plan->set_status(plan::STATUS_ACTIVE);
1400 $plan->update();
1401 api::unapprove_plan($plan->get_id());
1402 $plan->read();
1403 $this->assertEquals(plan::STATUS_DRAFT, $plan->get_status());
1404 }
1405
192569ed
JPG
1406 /**
1407 * Test update plan and the managing of archived user competencies.
1408 */
1409 public function test_update_plan_manage_archived_competencies() {
1410 global $DB;
1411
1412 $this->resetAfterTest(true);
1413 $dg = $this->getDataGenerator();
1414 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1415
1416 $syscontext = context_system::instance();
1417
1418 // Create users and roles for the test.
1419 $user = $dg->create_user();
1420 $manageownrole = $dg->create_role(array(
1421 'name' => 'User manage own',
1422 'shortname' => 'manageown'
1423 ));
1424 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $manageownrole, $syscontext->id);
1425 assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $manageownrole, $syscontext->id);
1426 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id);
1427 assign_capability('tool/lp:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id);
1428 $dg->role_assign($manageownrole, $user->id, $syscontext->id);
1429 $this->setUser($user);
1430
1431 // Create a framework and assign competencies.
1432 $framework = $lpg->create_framework();
1433 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1434 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1435 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1436
1437 // Create two plans and assign competencies.
1438 $plan = $lpg->create_plan(array('userid' => $user->id));
1439 $otherplan = $lpg->create_plan(array('userid' => $user->id));
1440
1441 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id()));
1442 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id()));
1443 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id()));
1444 $lpg->create_plan_competency(array('planid' => $otherplan->get_id(), 'competencyid' => $c1->get_id()));
1445
1446 $uclist = array(
1447 $lpg->create_user_competency(array(
1448 'userid' => $user->id,
1449 'competencyid' => $c1->get_id(),
1450 'proficiency' => true,
1451 'grade' => 1
1452 )),
1453 $lpg->create_user_competency(array(
1454 'userid' => $user->id,
1455 'competencyid' => $c2->get_id(),
1456 'proficiency' => false,
1457 'grade' => 2
1458 ))
1459 );
1460
1461 // Change status of the plan to complete.
1462 $record = $plan->to_record();
1463 $record->status = \tool_lp\plan::STATUS_COMPLETE;
1464
5bfab685
FM
1465 try {
1466 $plan = api::update_plan($record);
1467 $this->fail('We cannot complete a plan using api::update_plan().');
1468 } catch (coding_exception $e) {
1469 }
1470 api::complete_plan($plan);
192569ed
JPG
1471
1472 // Check that user compretencies are now in user_competency_plan objects and still in user_competency.
1473 $this->assertEquals(2, \tool_lp\user_competency::count_records());
1474 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
1475
1476 $usercompetenciesplan = \tool_lp\user_competency_plan::get_records();
1477
1478 $this->assertEquals($uclist[0]->get_userid(), $usercompetenciesplan[0]->get_userid());
1479 $this->assertEquals($uclist[0]->get_competencyid(), $usercompetenciesplan[0]->get_competencyid());
1480 $this->assertEquals($uclist[0]->get_proficiency(), (bool) $usercompetenciesplan[0]->get_proficiency());
1481 $this->assertEquals($uclist[0]->get_grade(), $usercompetenciesplan[0]->get_grade());
1482 $this->assertEquals($plan->get_id(), $usercompetenciesplan[0]->get_planid());
1483
1484 $this->assertEquals($uclist[1]->get_userid(), $usercompetenciesplan[1]->get_userid());
1485 $this->assertEquals($uclist[1]->get_competencyid(), $usercompetenciesplan[1]->get_competencyid());
1486 $this->assertEquals($uclist[1]->get_proficiency(), (bool) $usercompetenciesplan[1]->get_proficiency());
1487 $this->assertEquals($uclist[1]->get_grade(), $usercompetenciesplan[1]->get_grade());
1488 $this->assertEquals($plan->get_id(), $usercompetenciesplan[1]->get_planid());
1489
1490 $this->assertEquals($user->id, $usercompetenciesplan[2]->get_userid());
1491 $this->assertEquals($c3->get_id(), $usercompetenciesplan[2]->get_competencyid());
1492 $this->assertNull($usercompetenciesplan[2]->get_proficiency());
1493 $this->assertNull($usercompetenciesplan[2]->get_grade());
1494 $this->assertEquals($plan->get_id(), $usercompetenciesplan[2]->get_planid());
1495
192569ed
JPG
1496 // Change status of the plan to active.
1497 $record = $plan->to_record();
1498 $record->status = \tool_lp\plan::STATUS_ACTIVE;
1499
d805cc37
IT
1500 try {
1501 api::update_plan($record);
1502 $this->fail('Completed plan can not be edited');
1503 } catch (coding_exception $e) {
1504 }
192569ed 1505
d805cc37 1506 api::reopen_plan($record->id);
192569ed
JPG
1507 // Check that user_competency_plan objects are deleted if the plan status is changed to another status.
1508 $this->assertEquals(2, \tool_lp\user_competency::count_records());
1509 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
1510 }
1511
af3fa58f
IT
1512 /**
1513 * Test completing plan does not change the order of competencies.
1514 */
1515 public function test_complete_plan_doesnot_change_order() {
1516 global $DB;
1517
1518 $this->resetAfterTest(true);
1519 $this->setAdminUser();
1520 $dg = $this->getDataGenerator();
1521 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1522
1523 $syscontext = context_system::instance();
1524
1525 // Create users and roles for the test.
1526 $user = $dg->create_user();
1527
1528 // Create a framework and assign competencies.
1529 $framework = $lpg->create_framework();
1530 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1531 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1532 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1533
1534 // Create two plans and assign competencies.
1535 $plan = $lpg->create_plan(array('userid' => $user->id));
1536
1537 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c1->get_id()));
1538 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c2->get_id()));
1539 $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c3->get_id()));
1540
1541 // Changing competencies order in plan competency.
1542 api::reorder_plan_competency($plan->get_id(), $c1->get_id(), $c3->get_id());
1543
1544 $competencies = api::list_plan_competencies($plan);
1545 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id());
1546 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id());
1547 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id());
1548
1549 // Completing plan.
1550 api::complete_plan($plan);
1551
1552 $competencies = api::list_plan_competencies($plan);
1553
1554 // Completing plan does not change order.
1555 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id());
1556 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id());
1557 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id());
1558
1559 // Testing plan based on template.
1560 $template = $lpg->create_template();
1561 $framework = $lpg->create_framework();
1562 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1563 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1564 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1565
1566 $lpg->create_template_competency(array(
1567 'templateid' => $template->get_id(),
1568 'competencyid' => $c1->get_id()
1569 ));
1570 $lpg->create_template_competency(array(
1571 'templateid' => $template->get_id(),
1572 'competencyid' => $c2->get_id()
1573 ));
1574 $lpg->create_template_competency(array(
1575 'templateid' => $template->get_id(),
1576 'competencyid' => $c3->get_id()
1577 ));
1578 // Reorder competencies in template.
1579 api::reorder_template_competency($template->get_id(), $c1->get_id(), $c3->get_id());
1580
1581 // Create plan from template.
1582 $plan = api::create_plan_from_template($template->get_id(), $user->id);
1583
1584 $competencies = api::list_plan_competencies($plan);
1585
1586 // Completing plan does not change order.
1587 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id());
1588 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id());
1589 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id());
1590
1591 // Completing plan.
1592 api::complete_plan($plan);
1593
1594 $competencies = api::list_plan_competencies($plan);
1595
1596 // Completing plan does not change order.
1597 $this->assertEquals($c2->get_id(), $competencies[0]->competency->get_id());
1598 $this->assertEquals($c3->get_id(), $competencies[1]->competency->get_id());
1599 $this->assertEquals($c1->get_id(), $competencies[2]->competency->get_id());
1600 }
1601
192569ed
JPG
1602 /**
1603 * Test remove plan and the managing of archived user competencies.
1604 */
1605 public function test_delete_plan_manage_archived_competencies() {
1606 $this->resetAfterTest(true);
1607 $dg = $this->getDataGenerator();
1608 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1609
1610 $syscontext = context_system::instance();
1611
1612 // Create user and role for the test.
1613 $user = $dg->create_user();
1614 $managerole = $dg->create_role(array(
1615 'name' => 'User manage own',
1616 'shortname' => 'manageown'
1617 ));
1618 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $managerole, $syscontext->id);
1619 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $managerole, $syscontext->id);
1620 $dg->role_assign($managerole, $user->id, $syscontext->id);
1621 $this->setUser($user);
1622
1623 // Create a framework and assign competencies.
1624 $framework = $lpg->create_framework();
1625 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1626 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1627 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1628
1629 // Create completed plan with records in user_competency.
1630 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
1631
1632 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
1633 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
1634
1635 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
1636 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
1637
1638 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1639 'planid' => $completedplan->get_id()));
1640 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1641 'planid' => $completedplan->get_id()));
1642
1643 api::delete_plan($completedplan->get_id());
1644
1645 // Check that achived user competencies are deleted.
1646 $this->assertEquals(0, \tool_lp\plan::count_records());
1647 $this->assertEquals(2, \tool_lp\user_competency::count_records());
1648 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
1649 }
1650
1651 /**
1652 * Test listing of plan competencies.
1653 */
1654 public function test_list_plan_competencies_manage_archived_competencies() {
1655 $this->resetAfterTest(true);
1656 $dg = $this->getDataGenerator();
1657 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1658
1659 $syscontext = context_system::instance();
1660
1661 // Create user and role for the test.
1662 $user = $dg->create_user();
1663 $viewrole = $dg->create_role(array(
1664 'name' => 'User view',
1665 'shortname' => 'view'
1666 ));
1667 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $viewrole, $syscontext->id);
1668 assign_capability('tool/lp:planview', CAP_ALLOW, $viewrole, $syscontext->id);
1669 $dg->role_assign($viewrole, $user->id, $syscontext->id);
1670 $this->setUser($user);
1671
1672 // Create a framework and assign competencies.
1673 $framework = $lpg->create_framework();
1674 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1675 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1676 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1677
1678 // Create draft plan with records in user_competency.
1679 $draftplan = $lpg->create_plan(array('userid' => $user->id));
1680
1681 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c1->get_id()));
1682 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c2->get_id()));
1683 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c3->get_id()));
1684
1685 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
1686 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
1687
1688 // Check that user_competency objects are returned when plan status is not complete.
1689 $plancompetencies = api::list_plan_competencies($draftplan);
1690
1691 $this->assertCount(3, $plancompetencies);
1692 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[0]->usercompetency);
1693 $this->assertEquals($uc1->get_id(), $plancompetencies[0]->usercompetency->get_id());
1694 $this->assertNull($plancompetencies[0]->usercompetencyplan);
1695
1696 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[1]->usercompetency);
1697 $this->assertEquals($uc2->get_id(), $plancompetencies[1]->usercompetency->get_id());
1698 $this->assertNull($plancompetencies[1]->usercompetencyplan);
1699
1700 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[2]->usercompetency);
1701 $this->assertEquals(0, $plancompetencies[2]->usercompetency->get_id());
1702 $this->assertNull($plancompetencies[2]->usercompetencyplan);
1703
1704 // Create completed plan with records in user_competency_plan.
1705 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
1706
1707 $pc1 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
1708 $pc2 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
1709 $pc3 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c3->get_id()));
1710
1711 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1712 'planid' => $completedplan->get_id()));
1713 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1714 'planid' => $completedplan->get_id()));
192569ed
JPG
1715 $ucp3 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c3->get_id(),
1716 'planid' => $completedplan->get_id()));
1717
1718 // Check that user_competency_plan objects are returned when plan status is complete.
1719 $plancompetencies = api::list_plan_competencies($completedplan);
1720
1721 $this->assertCount(3, $plancompetencies);
1722 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[0]->usercompetencyplan);
1723 $this->assertEquals($ucp1->get_id(), $plancompetencies[0]->usercompetencyplan->get_id());
1724 $this->assertNull($plancompetencies[0]->usercompetency);
1725 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[1]->usercompetencyplan);
1726 $this->assertEquals($ucp2->get_id(), $plancompetencies[1]->usercompetencyplan->get_id());
1727 $this->assertNull($plancompetencies[1]->usercompetency);
1728 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[2]->usercompetencyplan);
1729 $this->assertEquals($ucp3->get_id(), $plancompetencies[2]->usercompetencyplan->get_id());
1730 $this->assertNull($plancompetencies[2]->usercompetency);
1731 }
1732
bee480a4
FM
1733 public function test_create_template_cohort() {
1734 $this->resetAfterTest(true);
1735 $this->setAdminUser();
1736
1737 $dg = $this->getDataGenerator();
1738 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1739
1740 $c1 = $dg->create_cohort();
1741 $c2 = $dg->create_cohort();
1742 $t1 = $lpg->create_template();
1743 $t2 = $lpg->create_template();
1744
1745 $this->assertEquals(0, \tool_lp\template_cohort::count_records());
1746
1747 // Create two relations with mixed parameters.
1748 $result = api::create_template_cohort($t1->get_id(), $c1->id);
1749 $result = api::create_template_cohort($t1, $c2);
1750
1751 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
1752 $this->assertInstanceOf('tool_lp\template_cohort', $result);
1753 $this->assertEquals($c2->id, $result->get_cohortid());
1754 $this->assertEquals($t1->get_id(), $result->get_templateid());
1755 $this->assertEquals(2, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1756 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1757 }
1758
5a4ee001
IT
1759 public function test_delete_template() {
1760 $this->resetAfterTest(true);
1761 $this->setAdminUser();
1762
1763 $dg = $this->getDataGenerator();
1764 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1765
1766 $c1 = $dg->create_cohort();
1767 $c2 = $dg->create_cohort();
1768 $template = $lpg->create_template();
1769 $id = $template->get_id();
1770
1771 // Create 2 template cohorts.
1772 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c1->id));
1773 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c2->id));
1774
1775 // Check pre-test.
1776 $this->assertTrue(tool_lp\template::record_exists($id));
1777 $this->assertEquals(2, \tool_lp\template_cohort::count_records(array('templateid' => $id)));
1778
1779 $result = api::delete_template($template->get_id());
1780 $this->assertTrue($result);
1781
1782 // Check that the template deos not exist anymore.
1783 $this->assertFalse(tool_lp\template::record_exists($id));
1784
1785 // Test if associated cohorts are also deleted.
1786 $this->assertEquals(0, \tool_lp\template_cohort::count_records(array('templateid' => $id)));
1787 }
1788
bee480a4
FM
1789 public function test_delete_template_cohort() {
1790 $this->resetAfterTest(true);
1791 $this->setAdminUser();
1792
1793 $dg = $this->getDataGenerator();
1794 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1795
1796 $c1 = $dg->create_cohort();
1797 $c2 = $dg->create_cohort();
1798 $t1 = $lpg->create_template();
1799 $t2 = $lpg->create_template();
1800 $tc1 = $lpg->create_template_cohort(array('templateid' => $t1->get_id(), 'cohortid' => $c1->id));
1801 $tc1 = $lpg->create_template_cohort(array('templateid' => $t2->get_id(), 'cohortid' => $c2->id));
1802
1803 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
1804 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1805 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1806
1807 // Delete existing.
1808 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1809 $this->assertTrue($result);
1810 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1811 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1812 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1813
1814 // Delete non-existant.
1815 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1816 $this->assertTrue($result);
1817 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1818 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1819 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1820 }
4c0e8167 1821
914b580e
FM
1822 public function test_add_evidence_log() {
1823 $this->resetAfterTest(true);
1824 $dg = $this->getDataGenerator();
1825 $lpg = $dg->get_plugin_generator('tool_lp');
1826
1827 $u1 = $dg->create_user();
1828 $u1ctx = context_user::instance($u1->id);
1829 $f1 = $lpg->create_framework();
1830 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1831 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1832
1833 // Creating a standard evidence with minimal information.
1834 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error');
1835 $evidence->read();
1836 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1837 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1838 $this->assertSame(null, $uc->get_grade());
1839 $this->assertSame(null, $uc->get_proficiency());
1840 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1841 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1842 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1843 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1844 $this->assertEquals('error', $evidence->get_desccomponent());
1845 $this->assertSame(null, $evidence->get_desca());
1846 $this->assertSame(null, $evidence->get_url());
1847 $this->assertSame(null, $evidence->get_grade());
1848 $this->assertSame(null, $evidence->get_actionuserid());
1849
1850 // Creating a standard evidence with more information.
1851 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
d17cbbfb 1852 '$a', false, 'http://moodle.org', null, 2, 'The evidence of prior learning were reviewed.');
914b580e
FM
1853 $evidence->read();
1854 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1855 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1856 $this->assertSame(null, $uc->get_grade());
1857 $this->assertSame(null, $uc->get_proficiency());
1858 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1859 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1860 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1861 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1862 $this->assertEquals('error', $evidence->get_desccomponent());
1863 $this->assertEquals('$a', $evidence->get_desca());
1864 $this->assertEquals('http://moodle.org', $evidence->get_url());
1865 $this->assertSame(null, $evidence->get_grade());
1866 $this->assertEquals(2, $evidence->get_actionuserid());
d17cbbfb 1867 $this->assertSame('The evidence of prior learning were reviewed.', $evidence->get_note());
914b580e
FM
1868
1869 // Creating a standard evidence and send for review.
1870 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1871 'error', null, true);
1872 $evidence->read();
1873 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1874 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1875
1876 // Trying to pass a grade should fail.
1877 try {
1878 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
1879 null, false, null, 1);
1880 $this->fail('A grade can not be set');
1881 } catch (coding_exception $e) {
1882 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
1883 }
1884 }
1885
1886 public function test_add_evidence_suggest() {
1887 $this->resetAfterTest(true);
1888 $dg = $this->getDataGenerator();
1889 $lpg = $dg->get_plugin_generator('tool_lp');
1890
1891 $u1 = $dg->create_user();
1892 $u1ctx = context_user::instance($u1->id);
1893 $f1 = $lpg->create_framework();
1894 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1895 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1896
1897 // Creating an evidence with minimal information.
1898 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1899 'error', null, false, null, 1, 2);
1900 $evidence->read();
1901 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1902 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1903 $this->assertSame(null, $uc->get_grade()); // We don't grade, we just suggest.
1904 $this->assertSame(null, $uc->get_proficiency());
1905 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1906 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1907 $this->assertEquals(\tool_lp\evidence::ACTION_SUGGEST, $evidence->get_action());
1908 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1909 $this->assertEquals('error', $evidence->get_desccomponent());
1910 $this->assertSame(null, $evidence->get_desca());
1911 $this->assertSame(null, $evidence->get_url());
1912 $this->assertEquals(1, $evidence->get_grade());
1913 $this->assertEquals(2, $evidence->get_actionuserid());
1914
1915 // Creating a standard evidence and send for review.
1916 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1917 'error', null, true, null, 1, 2);
1918 $evidence->read();
1919 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1920 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1921
1922 // Trying not to pass a grade should fail.
1923 try {
1924 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata', 'error',
1925 false, null);
1926 $this->fail('A grade must be set');
1927 } catch (coding_exception $e) {
1928 $this->assertRegExp('/grade MUST be set/', $e->getMessage());
1929 }
1930 }
1931
1932 public function test_add_evidence_complete() {
1933 $this->resetAfterTest(true);
1934 $dg = $this->getDataGenerator();
1935 $lpg = $dg->get_plugin_generator('tool_lp');
1936
1937 $u1 = $dg->create_user();
1938 $u1ctx = context_user::instance($u1->id);
1939 $scale = $dg->create_scale(array('scale' => 'A,B,C,D'));
1940 $scaleconfig = array(array('scaleid' => $scale->id));
1941 $scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1942 $scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 1, 'proficient' => 0);
1943 $scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 1);
1944 $scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 0, 'proficient' => 1);
1945 $c2scaleconfig = array(array('scaleid' => $scale->id));
1946 $c2scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1947 $c2scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 0, 'proficient' => 1);
1948 $c2scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 0);
1949 $c2scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 1, 'proficient' => 1);
1950 $f1 = $lpg->create_framework(array('scaleid' => $scale->id, 'scaleconfiguration' => $scaleconfig));
1951 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1952 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'scaleid' => $scale->id,
1953 'scaleconfiguration' => $c2scaleconfig));
1954 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1955
1956 // Creating an evidence with minimal information.
1957 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1958 'error');
1959 $evidence->read();
1960 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1961 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1962 $this->assertEquals(2, $uc->get_grade()); // The grade has been set automatically to the framework default.
1963 $this->assertEquals(0, $uc->get_proficiency());
1964 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1965 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1966 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1967 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1968 $this->assertEquals('error', $evidence->get_desccomponent());
1969 $this->assertSame(null, $evidence->get_desca());
1970 $this->assertSame(null, $evidence->get_url());
1971 $this->assertEquals(2, $evidence->get_grade());
1972 $this->assertSame(null, $evidence->get_actionuserid());
1973
1974 // Creating an evidence complete on competency with custom scale.
1975 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1976 'error');
1977 $evidence->read();
1978 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1979 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1980 $this->assertEquals(4, $uc->get_grade()); // The grade has been set automatically to the competency default.
1981 $this->assertEquals(true, $uc->get_proficiency());
1982 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1983 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1984 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1985 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1986 $this->assertEquals('error', $evidence->get_desccomponent());
1987 $this->assertSame(null, $evidence->get_desca());
1988 $this->assertSame(null, $evidence->get_url());
1989 $this->assertEquals(4, $evidence->get_grade());
1990 $this->assertSame(null, $evidence->get_actionuserid());
1991
1992 // Creating an evidence complete on a user competency with an existing grade.
1993 $uc = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get_id(), 'grade' => 1,
1994 'proficiency' => 0));
1995 $this->assertEquals(1, $uc->get_grade());
1996 $this->assertEquals(0, $uc->get_proficiency());
1997 $evidence = api::add_evidence($u1->id, $c3->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1998 'error');
1999 $evidence->read();
2000 $uc->read();
2001 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
2002 $this->assertEquals(1, $uc->get_grade()); // The grade has not been changed.
2003 $this->assertEquals(0, $uc->get_proficiency());
2004 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2005 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
2006 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
2007 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
2008 $this->assertEquals('error', $evidence->get_desccomponent());
2009 $this->assertSame(null, $evidence->get_desca());
2010 $this->assertSame(null, $evidence->get_url());
2011 $this->assertEquals(2, $evidence->get_grade()); // The complete grade has been set.
2012 $this->assertSame(null, $evidence->get_actionuserid());
2013
2014 // Creating a standard evidence and send for review.
2015 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
2016 'error', null, true);
2017 $evidence->read();
2018 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
2019 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2020
2021 // Trying to pass a grade should throw an exception.
2022 try {
2023 api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
2024 'error', null, false, null, 1);
2025 } catch (coding_exception $e) {
2026 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
2027 }
2028 }
2029
2030 public function test_add_evidence_override() {
2031 $this->resetAfterTest(true);
2032 $dg = $this->getDataGenerator();
2033 $lpg = $dg->get_plugin_generator('tool_lp');
2034
2035 $u1 = $dg->create_user();
2036 $u1ctx = context_user::instance($u1->id);
2037 $f1 = $lpg->create_framework();
2038 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2039
2040 // Creating an evidence with minimal information.
2041 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
2042 'error');
2043 $evidence->read();
2044 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2045 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
2046 $this->assertSame(null, $uc->get_grade()); // We overrode with 'null'.
2047 $this->assertSame(null, $uc->get_proficiency());
2048 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2049 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
2050 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2051 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
2052 $this->assertEquals('error', $evidence->get_desccomponent());
2053 $this->assertSame(null, $evidence->get_desca());
2054 $this->assertSame(null, $evidence->get_url());
2055 $this->assertSame(null, $evidence->get_grade()); // We overrode with 'null'.
2056 $this->assertSame(null, $evidence->get_actionuserid());
2057
2058 // Creating an evidence with a grade information.
2059 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
2060 'error', null, false, null, 3);
2061 $evidence->read();
2062 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2063 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
2064 $this->assertEquals(3, $uc->get_grade());
2065 $this->assertEquals(true, $uc->get_proficiency());
2066 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2067 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
2068 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2069 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
2070 $this->assertEquals('error', $evidence->get_desccomponent());
2071 $this->assertSame(null, $evidence->get_desca());
2072 $this->assertSame(null, $evidence->get_url());
2073 $this->assertEquals(3, $evidence->get_grade());
2074 $this->assertSame(null, $evidence->get_actionuserid());
2075
2076 // Creating an evidence with another grade information.
2077 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
2078 'error', null, false, null, 1);
2079 $evidence->read();
2080 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2081 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
2082 $this->assertEquals(1, $uc->get_grade());
2083 $this->assertEquals(0, $uc->get_proficiency());
2084 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2085 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
2086 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2087 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
2088 $this->assertEquals('error', $evidence->get_desccomponent());
2089 $this->assertSame(null, $evidence->get_desca());
2090 $this->assertSame(null, $evidence->get_url());
2091 $this->assertEquals(1, $evidence->get_grade());
2092 $this->assertSame(null, $evidence->get_actionuserid());
2093
2094 // Creating reverting the grade and send for review.
2095 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
2096 'error', null, true);
2097 $evidence->read();
2098 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2099 $this->assertSame(null, $uc->get_grade());
2100 $this->assertSame(null, $uc->get_proficiency());
2101 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2102 $this->assertSame(null, $evidence->get_grade());
2103 }
2104
2105 public function test_add_evidence_and_send_for_review() {
2106 $this->resetAfterTest(true);
2107 $dg = $this->getDataGenerator();
2108 $lpg = $dg->get_plugin_generator('tool_lp');
2109
2110 $u1 = $dg->create_user();
2111 $u1ctx = context_user::instance($u1->id);
2112 $f1 = $lpg->create_framework();
2113 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2114
2115 // Non-existing user competencies are created up for review.
2116 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2117 'error', null, true);
2118 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2119 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2120
2121 // Existing user competencies sent for review don't change.
2122 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2123 'error', null, true);
2124 $uc->read();
2125 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2126
2127 // A user competency with a status non-idle won't change.
2128 $uc->set_status(\tool_lp\user_competency::STATUS_IN_REVIEW);
2129 $uc->update();
2130 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2131 'error', null, true);
2132 $uc->read();
2133 $this->assertEquals(\tool_lp\user_competency::STATUS_IN_REVIEW, $uc->get_status());
2134 }
2135
4c0e8167
SG
2136 /**
2137 * Test add evidence for existing user_competency.
2138 */
2139 public function test_add_evidence_existing_user_competency() {
2140 $this->resetAfterTest(true);
2141 $dg = $this->getDataGenerator();
2142 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2143
2144 $syscontext = context_system::instance();
2145
2146 // Create users.
2147 $user = $dg->create_user();
2148 $this->setUser($user);
2149
2150 // Create a framework and assign competencies.
2151 $framework = $lpg->create_framework();
2152 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2153 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2154 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2155 $uc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
914b580e
FM
2156 $this->assertSame(null, $uc->get_grade());
2157 $this->assertSame(null, $uc->get_proficiency());
4c0e8167
SG
2158
2159 // Create an evidence and check it was created with the right usercomptencyid and information.
914b580e
FM
2160 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
2161 'invalidevidencedesc', 'tool_lp', array('a' => 'b'), false, 'http://moodle.org', 1, 2);
4c0e8167
SG
2162 $this->assertEquals(1, \tool_lp\evidence::count_records());
2163
2164 $evidence->read();
914b580e 2165 $uc->read();
4c0e8167
SG
2166 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2167 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
2168 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
2169 $this->assertEquals((object) array('a' => 'b'), $evidence->get_desca());
914b580e
FM
2170 $this->assertEquals('http://moodle.org', $evidence->get_url());
2171 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2172 $this->assertEquals(2, $evidence->get_actionuserid());
4c0e8167 2173 $this->assertEquals(1, $evidence->get_grade());
914b580e
FM
2174 $this->assertEquals(1, $uc->get_grade());
2175 $this->assertEquals(0, $uc->get_proficiency());
4c0e8167
SG
2176 }
2177
2178 /**
914b580e 2179 * Test add evidence for non-existing user_competency.
4c0e8167
SG
2180 */
2181 public function test_add_evidence_no_existing_user_competency() {
2182 $this->resetAfterTest(true);
2183 $dg = $this->getDataGenerator();
2184 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2185
2186 $syscontext = context_system::instance();
2187
2188 // Create users.
2189 $user = $dg->create_user();
2190 $this->setUser($user);
2191
2192 // Create a framework and assign competencies.
2193 $framework = $lpg->create_framework();
2194 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2195 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
914b580e 2196 $this->assertEquals(0, \tool_lp\user_competency::count_records());
4c0e8167 2197
914b580e
FM
2198 // Create an evidence without a user competency record.
2199 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
2200 'invalidevidencedesc', 'tool_lp', 'Hello world!', false, 'http://moodle.org', 1, 2);
4c0e8167 2201 $this->assertEquals(1, \tool_lp\evidence::count_records());
914b580e 2202 $this->assertEquals(1, \tool_lp\user_competency::count_records());
4c0e8167 2203
914b580e
FM
2204 $uc = \tool_lp\user_competency::get_record(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
2205 $evidence->read();
2206 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2207 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
2208 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
2209 $this->assertEquals('Hello world!', $evidence->get_desca());
2210 $this->assertEquals('http://moodle.org', $evidence->get_url());
2211 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2212 $this->assertEquals(2, $evidence->get_actionuserid());
2213 $this->assertEquals(1, $evidence->get_grade());
2214 $this->assertEquals(1, $uc->get_grade());
2215 $this->assertEquals(0, $uc->get_proficiency());
2216 }
2217
9373acf6
FM
2218 public function test_add_evidence_applies_competency_rules() {
2219 $this->resetAfterTest(true);
2220 $dg = $this->getDataGenerator();
2221 $lpg = $dg->get_plugin_generator('tool_lp');
2222 $syscontext = context_system::instance();
2223 $ctxid = $syscontext->id;
2224
2225 $u1 = $dg->create_user();
2226
2227 // Setting up the framework.
2228 $f1 = $lpg->create_framework();
2229 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2230 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2231 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2232 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2233 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c2->get_id()));
2234 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2235 $c3a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c3->get_id()));
2236 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2237 $c4a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c4->get_id()));
2238 $c5 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2239
2240 // Setting up the rules.
2241 $c1->set_ruletype('tool_lp\\competency_rule_all');
2242 $c1->set_ruleoutcome(\tool_lp\competency::OUTCOME_COMPLETE);
2243 $c1->update();
2244 $c2->set_ruletype('tool_lp\\competency_rule_all');
2245 $c2->set_ruleoutcome(\tool_lp\competency::OUTCOME_RECOMMEND);
2246 $c2->update();
2247 $c3->set_ruletype('tool_lp\\competency_rule_all');
2248 $c3->set_ruleoutcome(\tool_lp\competency::OUTCOME_EVIDENCE);
2249 $c3->update();
2250 $c4->set_ruletype('tool_lp\\competency_rule_all');
2251 $c4->set_ruleoutcome(\tool_lp\competency::OUTCOME_NONE);
2252 $c4->update();
2253
2254 // Confirm the current data.
2255 $this->assertEquals(0, user_competency::count_records());
2256 $this->assertEquals(0, evidence::count_records());
2257
2258 // Let's do this!
2259 // First let's confirm that evidence not marking a completion have no impact.
2260 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_LOG, 'commentincontext', 'core');
2261 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id()));
2262 $this->assertSame(null, $uc1a->get_proficiency());
2263 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c1->get_id())));
2264
2265 api::add_evidence($u1->id, $c2a, $ctxid, evidence::ACTION_SUGGEST, 'commentincontext', 'core', null, false, null, 1);
2266 $uc2a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2a->get_id()));
2267 $this->assertSame(null, $uc2a->get_proficiency());
2268 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c2->get_id())));
2269
2270 // Now let's try complete a competency but the rule won't match (not all children are complete).
2271 // The parent (the thing with the rule) will be created but won't have any evidence attached, and not
2272 // not be marked as completed.
2273 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2274 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id()));
2275 $this->assertEquals(true, $uc1a->get_proficiency());
2276 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2277 $this->assertSame(null, $uc1->get_proficiency());
2278 $this->assertEquals(0, evidence::count_records(array('usercompetencyid' => $uc1->get_id())));
2279
2280 // Now we complete the other child. That will mark the parent as complete with an evidence.
2281 api::add_evidence($u1->id, $c1b, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2282 $uc1b = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1b->get_id()));
2283 $this->assertEquals(true, $uc1a->get_proficiency());
2284 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2285 $this->assertEquals(true, $uc1->get_proficiency());
2286 $this->assertEquals(user_competency::STATUS_IDLE, $uc1->get_status());
2287 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc1->get_id())));
2288
2289 // Check rule recommending.
2290 api::add_evidence($u1->id, $c2a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2291 $uc2a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2a->get_id()));
2292 $this->assertEquals(true, $uc1a->get_proficiency());
2293 $uc2 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
2294 $this->assertSame(null, $uc2->get_proficiency());
2295 $this->assertEquals(user_competency::STATUS_WAITING_FOR_REVIEW, $uc2->get_status());
2296 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc2->get_id())));
2297
2298 // Check rule evidence.
2299 api::add_evidence($u1->id, $c3a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2300 $uc3a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3a->get_id()));
2301 $this->assertEquals(true, $uc1a->get_proficiency());
2302 $uc3 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id()));
2303 $this->assertSame(null, $uc3->get_proficiency());
2304 $this->assertEquals(user_competency::STATUS_IDLE, $uc3->get_status());
2305 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc3->get_id())));
2306
2307 // Check rule nothing.
2308 api::add_evidence($u1->id, $c4a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2309 $uc4a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4a->get_id()));
2310 $this->assertEquals(true, $uc1a->get_proficiency());
2311 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c4->get_id())));
2312
2313 // Check marking on something that has no parent. This just checks that nothing breaks.
2314 api::add_evidence($u1->id, $c5, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2315 }
2316
914b580e
FM
2317 public function test_observe_course_completed() {
2318 $this->resetAfterTest(true);
2319 $dg = $this->getDataGenerator();
2320 $lpg = $dg->get_plugin_generator('tool_lp');
2321
2322 // Set-up users, framework, competencies and course competencies.
2323 $course = $dg->create_course();
2324 $coursectx = context_course::instance($course->id);
2325 $u1 = $dg->create_user();
2326 $f1 = $lpg->create_framework();
2327 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2328 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2329 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2330 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2331 $cc1 = $lpg->create_course_competency(array('competencyid' => $c1->get_id(), 'courseid' => $course->id,
2332 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_NONE));
2333 $cc2 = $lpg->create_course_competency(array('competencyid' => $c2->get_id(), 'courseid' => $course->id,
2334 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_EVIDENCE));
2335 $cc3 = $lpg->create_course_competency(array('competencyid' => $c3->get_id(), 'courseid' => $course->id,
2336 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_RECOMMEND));
2337 $cc4 = $lpg->create_course_competency(array('competencyid' => $c4->get_id(), 'courseid' => $course->id,
2338 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_COMPLETE));
2339
2340 $event = \core\event\course_completed::create(array(
2341 'objectid' => 1,
2342 'relateduserid' => $u1->id,
2343 'context' => $coursectx,
2344 'courseid' => $course->id,
2345 'other' => array('relateduserid' => $u1->id)
2346 ));
2347 $this->assertEquals(0, \tool_lp\user_competency::count_records());
2348 $this->assertEquals(0, \tool_lp\evidence::count_records());
2349
2350 // Let's go!
2351 api::observe_course_completed($event);
2352 $this->assertEquals(3, \tool_lp\user_competency::count_records());
2353 $this->assertEquals(3, \tool_lp\evidence::count_records());
2354
2355 // Outcome NONE did nothing.
2356 $this->assertFalse(\tool_lp\user_competency::record_exists_select('userid = :uid AND competencyid = :cid', array(
2357 'uid' => $u1->id, 'cid' => $c1->get_id()
2358 )));
2359
2360 // Outcome evidence.
2361 $uc2 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
2362 $ev2 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc2->get_id()));
2363
2364 $this->assertEquals(null, $uc2->get_grade());
2365 $this->assertEquals(null, $uc2->get_proficiency());
2366 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc2->get_status());
2367
2368 $this->assertEquals('evidence_coursecompleted', $ev2->get_descidentifier());
2369 $this->assertEquals('tool_lp', $ev2->get_desccomponent());
2370 $this->assertEquals($course->shortname, $ev2->get_desca());
2371 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev2->get_url());
2372 $this->assertEquals(null, $ev2->get_grade());
2373 $this->assertEquals($coursectx->id, $ev2->get_contextid());
2374 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev2->get_action());
2375 $this->assertEquals(null, $ev2->get_actionuserid());
2376
2377 // Outcome recommend.
2378 $uc3 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id()));
2379 $ev3 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc3->get_id()));
2380
2381 $this->assertEquals(null, $uc3->get_grade());
2382 $this->assertEquals(null, $uc3->get_proficiency());
2383 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc3->get_status());
2384
2385 $this->assertEquals('evidence_coursecompleted', $ev3->get_descidentifier());
2386 $this->assertEquals('tool_lp', $ev3->get_desccomponent());
2387 $this->assertEquals($course->shortname, $ev3->get_desca());
2388 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev3->get_url());
2389 $this->assertEquals(null, $ev3->get_grade());
2390 $this->assertEquals($coursectx->id, $ev3->get_contextid());
2391 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev3->get_action());
2392 $this->assertEquals(null, $ev3->get_actionuserid());
2393
2394 // Outcome complete.
2395 $uc4 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4->get_id()));
2396 $ev4 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc4->get_id()));
2397
2398 $this->assertEquals(3, $uc4->get_grade());
2399 $this->assertEquals(1, $uc4->get_proficiency());
2400 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc4->get_status());
2401
2402 $this->assertEquals('evidence_coursecompleted', $ev4->get_descidentifier());
2403 $this->assertEquals('tool_lp', $ev4->get_desccomponent());
2404 $this->assertEquals($course->shortname, $ev4->get_desca());
2405 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev4->get_url());
2406 $this->assertEquals(3, $ev4->get_grade());
2407 $this->assertEquals($coursectx->id, $ev4->get_contextid());
2408 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $ev4->get_action());
2409 $this->assertEquals(null, $ev4->get_actionuserid());
4c0e8167 2410 }
d4c0a2f6 2411
db650737
DW
2412 public function test_list_course_modules_using_competency() {
2413 global $SITE;
2414
2415 $this->resetAfterTest(true);
2416 $dg = $this->getDataGenerator();
2417 $lpg = $dg->get_plugin_generator('tool_lp');
2418 $u1 = $dg->create_user();
2419 $u2 = $dg->create_user();
2420 $course = $dg->create_course();
2421 $course2 = $dg->create_course();
2422
2423 $this->setAdminUser();
2424 $f = $lpg->create_framework();
2425 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2426 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2427 $cc = api::add_competency_to_course($course->id, $c->get_id());
2428 $cc2 = api::add_competency_to_course($course->id, $c2->get_id());
2429
2430 // First check we get an empty list when there are no links.
2431 $expected = array();
2432 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2433 $this->assertEquals($expected, $result);
2434
2435 $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
2436 $page = $pagegenerator->create_instance(array('course'=>$course->id));
2437
2438 $cm = get_coursemodule_from_instance('page', $page->id);
2439 // Add a link and list again.
2440 $ccm = api::add_competency_to_course_module($cm, $c->get_id());
f446b2e1 2441 $expected = array($cm->id);
db650737
DW
2442 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2443 $this->assertEquals($expected, $result);
2444
2445 // Check a different course.
2446 $expected = array();
2447 $result = api::list_course_modules_using_competency($c->get_id(), $course2->id);
2448 $this->assertEquals($expected, $result);
2449
2450 // Remove the link and check again.
2451 $result = api::remove_competency_from_course_module($cm, $c->get_id());
2452 $expected = true;
2453 $this->assertEquals($expected, $result);
2454 $expected = array();
2455 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2456 $this->assertEquals($expected, $result);
2457
2458 // Now add 2 links.
2459 api::add_competency_to_course_module($cm, $c->get_id());
2460 api::add_competency_to_course_module($cm, $c2->get_id());
2461 $result = api::list_course_module_competencies_in_course_module($cm->id);
2462 $this->assertEquals($result[0]->get_competencyid(), $c->get_id());
2463 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
2464
2465 // Now re-order.
2466 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
2467 $result = api::list_course_module_competencies_in_course_module($cm->id);
2468 $this->assertEquals($result[0]->get_competencyid(), $c2->get_id());
2469 $this->assertEquals($result[1]->get_competencyid(), $c->get_id());
2470
2471 // And re-order again.
2472 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
2473 $result = api::list_course_module_competencies_in_course_module($cm->id);
2474 $this->assertEquals($result[0]->get_competencyid(), $c->get_id());
2475 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
2476 }
2477
d4c0a2f6
SG
2478 /**
2479 * Test update ruleoutcome for course_competency.
2480 */
d660824b 2481 public function test_set_ruleoutcome_course_competency() {
d4c0a2f6
SG
2482 $this->resetAfterTest(true);
2483 $dg = $this->getDataGenerator();
2484 $lpg = $dg->get_plugin_generator('tool_lp');
2485 $u1 = $dg->create_user();
2486 $u2 = $dg->create_user();
d660824b 2487 $course = $dg->create_course();
d4c0a2f6
SG
2488
2489 $this->setAdminUser();
2490 $f = $lpg->create_framework();
2491 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
d660824b 2492 $cc = api::add_competency_to_course($course->id, $c->get_id());
d4c0a2f6
SG
2493
2494 // Check record was created with default rule value Evidence.
2495 $this->assertEquals(1, \tool_lp\course_competency::count_records());
d660824b
FM
2496 $recordscc = api::list_course_competencies($course->id);
2497 $this->assertEquals(\tool_lp\course_competency::OUTCOME_EVIDENCE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
2498
2499 // Check ruleoutcome value is updated to None.
d660824b
FM
2500 $this->assertTrue(api::set_course_competency_ruleoutcome($recordscc[0]['coursecompetency']->get_id(),
2501 \tool_lp\course_competency::OUTCOME_NONE));
2502 $recordscc = api::list_course_competencies($course->id);
2503 $this->assertEquals(\tool_lp\course_competency::OUTCOME_NONE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
2504 }
2505
4de456cd
SG
2506 /**
2507 * Test validation on grade on user_competency.
2508 */
2509 public function test_validate_grade_in_user_competency() {
2510 global $DB;
2511
2512 $this->resetAfterTest(true);
2513 $this->setAdminUser();
2514 $dg = $this->getDataGenerator();
2515 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2516 $user = $dg->create_user();
2517
2518 $dg->create_scale(array("id" => "1", "scale" => "value1, value2"));
2519 $dg->create_scale(array("id" => "2", "scale" => "value3, value4, value5, value6"));
2520
2521 $scaleconfiguration1 = '[{"scaleid":"1"},{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .
2522 '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';
2523 $scaleconfiguration2 = '[{"scaleid":"2"},{"name":"value3","id":1,"scaledefault":1,"proficient":0},'
2524 . '{"name":"value4","id":2,"scaledefault":0,"proficient":1},'
2525 . '{"name":"value5","id":3,"scaledefault":0,"proficient":0},'
2526 . '{"name":"value6","id":4,"scaledefault":0,"proficient":0}]';
2527
2528 // Create a framework with scale configuration1.
2529 $frm = array(
2530 'scaleid' => 1,
2531 'scaleconfiguration' => $scaleconfiguration1
2532 );
2533 $framework = $lpg->create_framework($frm);
2534 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2535
2536 // Create competency with its own scale configuration.
2537 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
2538 'scaleid' => 2,
2539 'scaleconfiguration' => $scaleconfiguration2
2540 ));
2541
2542 // Detecte invalid grade in competency using its framework competency scale.
2543 try {
2544 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
2545 'proficiency' => true, 'grade' => 3 ));
2546 $usercompetency->create();
2547 $this->fail('Invalid grade not detected in framework scale');
2548 } catch (\tool_lp\invalid_persistent_exception $e) {
2549 $this->assertTrue(true);
2550 }
2551
2552 // Detecte invalid grade in competency using its own scale.
2553 try {
2554 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
2555 'proficiency' => true, 'grade' => 5 ));
2556 $usercompetency->create();
2557 $this->fail('Invalid grade not detected in competency scale');
2558 } catch (\tool_lp\invalid_persistent_exception $e) {
2559 $this->assertTrue(true);
2560 }
2561
2562 // Accept valid grade in competency using its framework competency scale.
2563 try {
2564 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
2565 'proficiency' => true, 'grade' => 1 ));
2566 $usercompetency->create();
2567 $this->assertTrue(true);
2568 } catch (\tool_lp\invalid_persistent_exception $e) {
2569 $this->fail('Valide grade rejected in framework scale');
2570 }
2571
2572 // Accept valid grade in competency using its framework competency scale.
2573 try {
2574 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
2575 'proficiency' => true, 'grade' => 4 ));
2576 $usercompetency->create();
2577 $this->assertTrue(true);
2578 } catch (\tool_lp\invalid_persistent_exception $e) {
4de456cd
SG
2579 $this->fail('Valide grade rejected in competency scale');
2580 }
2581 }
2582
964afa98
IT
2583 /**
2584 * Test when adding competency that belong to hidden framework to plan/template/course.
2585 */
2586 public function test_hidden_framework() {
2587 $this->resetAfterTest(true);
2588 $this->setAdminUser();
2589 $dg = $this->getDataGenerator();
2590 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2591 $user = $dg->create_user();
2592
2593 // Create a course.
2594 $cat1 = $dg->create_category();
2595 $course = $dg->create_course(array('category' => $cat1->id));
2596 // Create a template.
2597 $template = $lpg->create_template();
2598 // Create a plan.
2599 $plan = $lpg->create_plan(array('userid' => $user->id));
2600
2601 // Create a hidden framework.
2602 $frm = array(
2603 'visible' => false
2604 );
2605 $framework = $lpg->create_framework($frm);
2606 $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2607
2608 // Linking competency that belong to hidden framework to course.
2609 try {
2610 api::add_competency_to_course($course->id, $competency->get_id());
2611 $this->fail('A competency belonging to hidden framework can not be linked to course');
2612 } catch (coding_exception $e) {
2613 $this->assertTrue(true);
2614 }
2615
2616 // Adding competency that belong to hidden framework to template.
2617 try {
2618 api::add_competency_to_template($template->get_id(), $competency->get_id());
2619 $this->fail('A competency belonging to hidden framework can not be added to template');
2620 } catch (coding_exception $e) {
2621 $this->assertTrue(true);
2622 }
2623
2624 // Adding competency that belong to hidden framework to plan.
2625 try {
2626 api::add_competency_to_plan($plan->get_id(), $competency->get_id());
2627 $this->fail('A competency belonging to hidden framework can not be added to plan');
2628 } catch (coding_exception $e) {
2629 $this->assertTrue(true);
2630 }
2631 }
2632
2633 /**
2634 * Test when using hidden template in plan/cohort.
2635 */
2636 public function test_hidden_template() {
2637 $this->resetAfterTest(true);
2638 $this->setAdminUser();
2639 $dg = $this->getDataGenerator();
2640 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2641 $user = $dg->create_user();
2642
2643 // Create a cohort.
2644 $cohort = $dg->create_cohort();
2645 // Create a hidden template.
2646 $template = $lpg->create_template(array('visible' => false));
2647
2648 // Can not link hidden template to plan.
2649 try {
2650 api::create_plan_from_template($template->get_id(), $user->id);
2651 $this->fail('Can not link a hidden template to plan');
2652 } catch (coding_exception $e) {
2653 $this->assertTrue(true);
2654 }
2655
2656 // Can associate hidden template to cohort.
2657 $templatecohort = api::create_template_cohort($template->get_id(), $cohort->id);
2658 $this->assertInstanceOf('\tool_lp\template_cohort', $templatecohort);
2659 }
2660
d3275795
SG
2661 /**
2662 * Test that completed plan created form a template does not change when template is modified.
2663 */
2664 public function test_completed_plan_doesnot_change() {
2665 global $DB;
2666
2667 $this->resetAfterTest(true);
2668 $this->setAdminUser();
2669 $dg = $this->getDataGenerator();
2670 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2671 $user = $dg->create_user();
2672
2673 // Create a framework and assign competencies.
2674 $framework = $lpg->create_framework();
2675 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2676 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2677 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2678 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2679
2680 // Create template and assign competencies.
2681 $tp = $lpg->create_template();
2682 $tpc1 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c1->get_id()));
2683 $tpc2 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c2->get_id()));
2684 $tpc3 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c3->get_id()));
2685
2686 // Create a plan form template and change it status to complete.
2687 $plan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tp->get_id()));
2688 api::complete_plan($plan);
2689
2690 // Check user competency plan created correctly.
2691 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
2692 $ucp = \tool_lp\user_competency_plan::get_records();
2693 $this->assertEquals($ucp[0]->get_competencyid(), $c1->get_id());
2694 $this->assertEquals($ucp[1]->get_competencyid(), $c2->get_id());
2695 $this->assertEquals($ucp[2]->get_competencyid(), $c3->get_id());
2696
2697 // Add and remove a competency from the template.
2698 api::add_competency_to_template($tp->get_id(), $c4->get_id());
2699 api::remove_competency_from_template($tp->get_id(), $c1->get_id());
2700
2701 // Check that user competency plan did not change.
2702 $competencies = $plan->get_competencies();
2703 $this->assertEquals(3, count($competencies));
2704 $ucp1 = array($c1->get_id(), $c2->get_id(), $c3->get_id());
2705 $ucp2 = array();
2706 foreach ($competencies as $id => $cmp) {
2707 $ucp2[] = $id;
2708 }
2709 $this->assertEquals(0, count(array_diff($ucp1, $ucp2)));
2710 }
20c2fe3e
FM
2711
2712 protected function setup_framework_for_reset_rules_tests() {
2713 $this->resetAfterTest(true);
2714 $dg = $this->getDataGenerator();
2715 $lpg = $dg->get_plugin_generator('tool_lp');
2716
2717 $this->setAdminUser();
2718 $f1 = $lpg->create_framework();
2719 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2720 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2721 $c1a1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2722 $c1a1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a1->get_id()));
2723 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2724 $c1b1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2725 $c1b1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b1->get_id()));
2726 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2727 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2728
2729 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2730 $c1->set_ruletype('tool_lp\\competency_rule_all');
2731 $c1->update();
2732 $c1a->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2733 $c1a->set_ruletype('tool_lp\\competency_rule_all');
2734 $c1a->update();
2735 $c1a1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2736 $c1a1->set_ruletype('tool_lp\\competency_rule_all');
2737 $c1a1->update();
2738 $c1b->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2739 $c1b->set_ruletype('tool_lp\\competency_rule_all');
2740 $c1b->update();
2741 $c2->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2742 $c2->set_ruletype('tool_lp\\competency_rule_all');
2743 $c2->update();
2744
2745 return array(
2746 'f1' => $f1,
2747 'c1' => $c1,
2748 'c1a' => $c1a,
2749 'c1a1' => $c1a1,
2750 'c1a1a' => $c1a1a,
2751 'c1b' => $c1b,
2752 'c1b1' => $c1b1,
2753 'c1b1a' => $c1b1a,
2754 'c2' => $c2,
2755 'c2a' => $c2a,
2756 );
2757 }
2758
2759 public function test_moving_competency_reset_rules_updown() {
2760 extract($this->setup_framework_for_reset_rules_tests());
2761
2762 // Moving up and down doesn't change anything.
2763 api::move_down_competency($c1a->get_id());
2764 $c1->read();
2765 $c1a->read();
2766 $c1a1->read();
2767 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2768 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2769 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2770 api::move_up_competency($c1a->get_id());
2771 $c1->read();
2772 $c1a->read();
2773 $c1a1->read();
2774 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2775 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2776 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2777 }
2778
2779 public function test_moving_competency_reset_rules_parent() {
2780 extract($this->setup_framework_for_reset_rules_tests());
2781
2782 // Moving out of parent will reset the parent, and the destination.
2783 api::set_parent_competency($c1a->get_id(), $c1b->get_id());
2784 $c1->read();
2785 $c1a->read();
2786 $c1a1->read();
2787 $c1b->read();
2788 $c2->read();
2789 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2790 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2791 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2792 $this->assertEquals(competency::OUTCOME_NONE, $c1b->get_ruleoutcome());
2793 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2794 }
2795
2796 public function test_moving_competency_reset_rules_totoplevel() {
2797 extract($this->setup_framework_for_reset_rules_tests());
2798
2799 // Moving to top level only affects the initial parent.
2800 api::set_parent_competency($c1a1->get_id(), 0);
2801 $c1->read();
2802 $c1a->read();
2803 $c1a1->read();
2804 $c1b->read();
2805 $c2->read();
2806 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2807 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome());
2808 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2809 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2810 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2811 }
2812
2813 public function test_moving_competency_reset_rules_fromtoplevel() {
2814 extract($this->setup_framework_for_reset_rules_tests());
2815
2816 // Moving from top level only affects the destination parent.
2817 api::set_parent_competency($c2->get_id(), $c1a1->get_id());
2818 $c1->read();
2819 $c1a->read();
2820 $c1a1->read();
2821 $c1b->read();
2822 $c2->read();
2823 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2824 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2825 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome());
2826 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2827 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2828 }
2829
2830 public function test_moving_competency_reset_rules_child() {
2831 extract($this->setup_framework_for_reset_rules_tests());
2832
2833 // Moving to a child of self resets self, parent and destination.
2834 api::set_parent_competency($c1a->get_id(), $c1a1->get_id());
2835 $c1->read();
2836 $c1a->read();
2837 $c1a1->read();
2838 $c1b->read();
2839 $c2->read();
2840 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2841 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome());
2842 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome());
2843 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2844 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2845 }
2846
2847 public function test_create_competency_reset_rules() {
2848 extract($this->setup_framework_for_reset_rules_tests());
2849
2850 // Adding a new competency resets the rule of its parent.
2851 api::create_competency((object) array('shortname' => 'A', 'parentid' => $c1->get_id(), 'idnumber' => 'A',
2852 'competencyframeworkid' => $f1->get_id()));
2853 $c1->read();
2854 $c1a->read();
2855 $c1a1->read();
2856 $c1b->read();
2857 $c2->read();
2858 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2859 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2860 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2861 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2862 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2863 }
2864
2865 public function test_delete_competency_reset_rules() {
2866 extract($this->setup_framework_for_reset_rules_tests());
2867
2868 // Deleting a competency resets the rule of its parent.
2869 api::delete_competency($c1a->get_id());
2870 $c1->read();
2871 $c1b->read();
2872 $c2->read();
2873 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2874 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2875 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2876 }
8fabc738
SG
2877
2878 public function test_template_has_related_data() {
2879 $this->resetAfterTest(true);
2880 $this->setAdminUser();
2881
2882 $dg = $this->getDataGenerator();
2883 $user = $dg->create_user();
2884 $lpg = $dg->get_plugin_generator('tool_lp');
2885 $tpl1 = $lpg->create_template();
2886 $tpl2 = $lpg->create_template();
2887
2888 // Create plans for first template.
2889 $time = time();
2890 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $user->id,
2891 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
2892
2893 $this->assertTrue(api::template_has_related_data($tpl1->get_id()));
2894 $this->assertFalse(api::template_has_related_data($tpl2->get_id()));
2895
2896 }
2897
2898 public function test_delete_template_delete_plans() {
2899 $this->resetAfterTest(true);
2900 $this->setAdminUser();
2901
2902 $dg = $this->getDataGenerator();
2903 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2904
2905 $u1 = $dg->create_user();
2906 $f = $lpg->create_framework();
2907 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2908 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2909
2910 $tpl = $lpg->create_template();
2911
2912 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(),
2913 'sortorder' => 1));
2914 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(),
2915 'sortorder' => 2));
2916
2917 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id));
2918
2919 // Check pre-test.
2920 $this->assertTrue(tool_lp\template::record_exists($tpl->get_id()));
2921 $this->assertEquals(2, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2922 $this->assertEquals(1, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2923
2924 $result = api::delete_template($tpl->get_id(), true);
2925 $this->assertTrue($result);
2926
2927 // Check that the template does not exist anymore.
2928 $this->assertFalse(tool_lp\template::record_exists($tpl->get_id()));
2929
2930 // Check that associated competencies are also deleted.
2931 $this->assertEquals(0, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2932
2933 // Check that associated plan are also deleted.
2934 $this->assertEquals(0, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2935 }
2936
2937 public function test_delete_template_unlink_plans() {
2938 $this->resetAfterTest(true);
2939 $this->setAdminUser();
2940
2941 $dg = $this->getDataGenerator();
2942 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2943
2944 $u1 = $dg->create_user();
2945 $f = $lpg->create_framework();
2946 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2947 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2948
2949 $tpl = $lpg->create_template();
2950
2951 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(),
2952 'sortorder' => 1));
2953 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(),
2954 'sortorder' => 2));
2955
2956 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id));
2957
2958 // Check pre-test.
2959 $this->assertTrue(tool_lp\template::record_exists($tpl->get_id()));
2960 $this->assertEquals(2, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2961 $this->assertEquals(1, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2962
2963 $result = api::delete_template($tpl->get_id(), false);
2964 $this->assertTrue($result);
2965
2966 // Check that the template does not exist anymore.
2967 $this->assertFalse(tool_lp\template::record_exists($tpl->get_id()));
2968
2969 // Check that associated competencies are also deleted.
2970 $this->assertEquals(0, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2971
2972 // Check that associated plan still exist but unlink from template.
2973 $plans = \tool_lp\plan::get_records(array('id' => $p1->get_id()));
2974 $this->assertEquals(1, count($plans));
2975 $this->assertEquals($plans[0]->get_origtemplateid(), $tpl->get_id());
2976 $this->assertNull($plans[0]->get_templateid());
2977 }
9a325eda
IT
2978
2979 public function test_delete_competency() {
2980 $this->resetAfterTest(true);
2981 $dg = $this->getDataGenerator();
2982 $lpg = $dg->get_plugin_generator('tool_lp');
2983 $this->setAdminUser();
2984
2985 $u1 = $dg->create_user();
2986
2987 $f1 = $lpg->create_framework();
2988 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2989 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2990 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2991 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2992 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2993 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2994
2995 // Set rules on parent competency.
2996 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2997 $c1->set_ruletype('tool_lp\\competency_rule_all');
2998 $c1->update();
2999
3000 // If we delete competeny, the related competencies relations and evidences should be deleted.
3001 // Create related competencies using one of c1a competency descendants.
3002 $rc = $lpg->create_related_competency(array(
3003 'competencyid' => $c2->get_id(),
3004 'relatedcompetencyid' => $c11b->get_id()
3005 ));
3006 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3007
3008 // Creating a standard evidence with minimal information.
3009 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3010 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id()));
3011 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
3012 $uc2->delete();
3013
3014 $this->assertTrue(api::delete_competency($c1a->get_id()));
3015 $this->assertFalse(competency::record_exists($c1a->get_id()));
3016
3017 // Check that on delete, we reset the rule on parent competency.
3018 $c1->read();
3019 $this->assertNull($c1->get_ruletype());
3020 $this->assertNull($c1->get_ruletype());
3021 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
3022
3023 // Check that descendants were also deleted.
3024 $this->assertFalse(competency::record_exists($c1b->get_id()));
3025 $this->assertFalse(competency::record_exists($c11b->get_id()));
3026 $this->assertFalse(competency::record_exists($c12b->get_id()));
3027
3028 // Check if evidence are also deleted.
3029 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3030
3031 // Check if related conpetency relation is deleted.
3032 $this->assertEquals(0, count(api::list_related_competencies($c2->get_id())));
3033
3034 // Delete a simple competency.
3035 $this->assertTrue(api::delete_competency($c2->get_id()));
3036 $this->assertFalse(competency::record_exists($c2->get_id()));
3037 }
3038
3039 public function test_delete_competency_used_in_plan() {
3040 $this->resetAfterTest(true);
3041 $dg = $this->getDataGenerator();
3042 $lpg = $dg->get_plugin_generator('tool_lp');
3043 $this->setAdminUser();
3044
3045 $u1 = $dg->create_user();
3046
3047 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3048
3049 $f1 = $lpg->create_framework();
3050 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3051 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3052 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3053 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3054 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3055 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3056
3057 // Add competency to plan.
3058 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id()));
3059 // We can not delete a competency , if competency or competency children is associated to plan.
3060 $this->assertFalse(api::delete_competency($c1a->get_id()));
3061
3062 // We can delete the competency if we remove the competency from the plan.
3063 $pc->delete();
3064
3065 $this->assertTrue(api::delete_competency($c1a->get_id()));
3066 $this->assertFalse(competency::record_exists($c1a->get_id()));
3067 $this->assertFalse(competency::record_exists($c1b->get_id()));
3068 $this->assertFalse(competency::record_exists($c11b->get_id()));
3069 $this->assertFalse(competency::record_exists($c12b->get_id()));
3070 }
3071
3072 public function test_delete_competency_used_in_usercompetency() {
3073 $this->resetAfterTest(true);
3074 $dg = $this->getDataGenerator();
3075 $lpg = $dg->get_plugin_generator('tool_lp');
3076 $this->setAdminUser();
3077
3078 $u1 = $dg->create_user();
3079
3080 $f1 = $lpg->create_framework();
3081 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3082 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3083 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3084 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3085 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3086 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3087
3088 // Create user competency.
3089 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3090
3091 // We can not delete a competency , if competency or competency children exist in user competency.
3092 $this->assertFalse(api::delete_competency($c1a->get_id()));
3093
3094 // We can delete the competency if we remove the competency from user competency.
3095 $uc1->delete();
3096
3097 $this->assertTrue(api::delete_competency($c1a->get_id()));
3098 $this->assertFalse(competency::record_exists($c1a->get_id()));
3099 $this->assertFalse(competency::record_exists($c1b->get_id()));
3100 $this->assertFalse(competency::record_exists($c11b->get_id()));
3101 $this->assertFalse(competency::record_exists($c12b->get_id()));
3102 }
3103
3104 public function test_delete_competency_used_in_usercompetencyplan() {
3105 $this->resetAfterTest(true);
3106 $dg = $this->getDataGenerator();
3107 $lpg = $dg->get_plugin_generator('tool_lp');
3108 $this->setAdminUser();
3109
3110 $u1 = $dg->create_user();
3111
3112 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3113
3114 $f1 = $lpg->create_framework();
3115 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3116 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3117 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3118 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3119 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3120 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3121
3122 // Create user competency plan.
3123 $uc2 = $lpg->create_user_competency_plan(array(
3124 'userid' => $u1->id,
3125 'competencyid' => $c11b->get_id(),
3126 'planid' => $plan->get_id()
3127 ));
3128
3129 // We can not delete a competency , if competency or competency children exist in user competency plan.
3130 $this->assertFalse(api::delete_competency($c1a->get_id()));
3131
3132 // We can delete the competency if we remove the competency from user competency plan.
3133 $uc2->delete();
3134
3135 $this->assertTrue(api::delete_competency($c1a->get_id()));
3136 $this->assertFalse(competency::record_exists($c1a->get_id()));
3137 $this->assertFalse(competency::record_exists($c1b->get_id()));
3138 $this->assertFalse(competency::record_exists($c11b->get_id()));
3139 $this->assertFalse(competency::record_exists($c12b->get_id()));
3140 }
3141
3142 public function test_delete_competency_used_in_template() {
3143 $this->resetAfterTest(true);
3144 $dg = $this->getDataGenerator();
3145 $lpg = $dg->get_plugin_generator('tool_lp');
3146 $this->setAdminUser();
3147
3148 $template = $lpg->create_template();
3149
3150 $f1 = $lpg->create_framework();
3151 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3152 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3153 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3154 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3155 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3156 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3157
3158 // Add competency to a template.
3159 $tc = $lpg->create_template_competency(array(
3160 'templateid' => $template->get_id(),
3161 'competencyid' => $c11b->get_id()
3162 ));
3163 // We can not delete a competency , if competency or competency children is linked to template.
3164 $this->assertFalse(api::delete_competency($c1a->get_id()));
3165
3166 // We can delete the competency if we remove the competency from template.
3167 $tc->delete();
3168
3169 $this->assertTrue(api::delete_competency($c1a->get_id()));
3170 $this->assertFalse(competency::record_exists($c1a->get_id()));
3171 $this->assertFalse(competency::record_exists($c1b->get_id()));
3172 $this->assertFalse(competency::record_exists($c11b->get_id()));
3173 $this->assertFalse(competency::record_exists($c12b->get_id()));
3174 }
3175
3176 public function test_delete_competency_used_in_course() {
3177 $this->resetAfterTest(true);
3178 $dg = $this->getDataGenerator();
3179 $lpg = $dg->get_plugin_generator('tool_lp');
3180 $this->setAdminUser();
3181
3182 $cat1 = $dg->create_category();
3183
3184 $course = $dg->create_course(array('category' => $cat1->id));
3185
3186 $f1 = $lpg->create_framework();
3187 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3188 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3189 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3190 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3191 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3192 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3193
3194 // Add competency to course.
3195 $cc = $lpg->create_course_competency(array(
3196 'courseid' => $course->id,
3197 'competencyid' => $c11b->get_id()
3198 ));
3199
3200 // We can not delete a competency if the competency or competencies children is linked to a course.
3201 $this->assertFalse(api::delete_competency($c1a->get_id()));
3202
3203 // We can delete the competency if we remove the competency from course.
3204 $cc->delete();
3205
3206 $this->assertTrue(api::delete_competency($c1a->get_id()));
3207 $this->assertFalse(competency::record_exists($c1a->get_id()));
3208 $this->assertFalse(competency::record_exists($c1b->get_id()));
3209 $this->assertFalse(competency::record_exists($c11b->get_id()));
3210 $this->assertFalse(competency::record_exists($c12b->get_id()));
3211 }
90c7bdaf
IT
3212
3213 public function test_delete_framework() {
3214 $this->resetAfterTest(true);
3215 $dg = $this->getDataGenerator();
3216 $lpg = $dg->get_plugin_generator('tool_lp');
3217 $this->setAdminUser();
3218
3219 $u1 = $dg->create_user();
3220
3221 $f1 = $lpg->create_framework();
3222 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3223 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3224 $c2id = $c2->get_id();
3225 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3226 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3227 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3228 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3229
3230 // If we delete framework, the related competencies relations and evidences should be deleted.
3231 // Create related competencies using one of c1a competency descendants.
3232 $rc = $lpg->create_related_competency(array(
3233 'competencyid' => $c2->get_id(),
3234 'relatedcompetencyid' => $c11b->get_id()
3235 ));
3236 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3237
3238 // Creating a standard evidence with minimal information.
3239 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3240 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id()));
3241 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
3242 $uc2->delete();
3243
3244 $this->assertTrue(api::delete_framework($f1->get_id()));
3245 $this->assertFalse(competency_framework::record_exists($f1->get_id()));
3246
3247 // Check that all competencies were also deleted.
3248 $this->assertFalse(competency::record_exists($c1->get_id()));
3249 $this->assertFalse(competency::record_exists($c2->get_id()));
3250 $this->assertFalse(competency::record_exists($c1a->get_id()));
3251 $this->assertFalse(competency::record_exists($c1b->get_id()));
3252 $this->assertFalse(competency::record_exists($c11b->get_id()));
3253 $this->assertFalse(competency::record_exists($c12b->get_id()));
3254
3255 // Check if evidence are also deleted.
3256 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3257
3258 // Check if related conpetency relation is deleted.
3259 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3260
3261 // Delete a simple framework.
3262 $f2 = $lpg->create_framework();
3263 $this->assertTrue(api::delete_framework($f2->get_id()));
3264 $this->assertFalse(competency_framework::record_exists($f2->get_id()));
3265 }
3266
3267 public function test_delete_framework_competency_used_in_plan() {
3268 $this->resetAfterTest(true);
3269 $dg = $this->getDataGenerator();
3270 $lpg = $dg->get_plugin_generator('tool_lp');
3271 $this->setAdminUser();
3272
3273 $u1 = $dg->create_user();
3274
3275 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3276
3277 $f1 = $lpg->create_framework();
3278 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3279 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3280 $c2id = $c2->get_id();
3281 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3282 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3283 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3284 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3285
3286 // Create related competencies.
3287 $rc = $lpg->create_related_competency(array(
3288 'competencyid' => $c2->get_id(),
3289 'relatedcompetencyid' => $c11b->get_id()
3290 ));
3291 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3292
3293 // Creating a standard evidence with minimal information.
3294 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3295 $usercompetencyid = $uc2->get_id();
3296 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3297 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
3298 $uc2->delete();
3299
3300 // Add competency to plan.
3301 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id()));
3302 // We can not delete a framework , if competency or competency children is associated to plan.
3303 $this->assertFalse(api::delete_framework($f1->get_id()));
3304 // Check that none of associated data are deleted.
3305 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3306 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3307
3308 // We can delete the competency if we remove the competency from the plan.
3309 $pc->delete();
3310
3311 $this->assertTrue(api::delete_framework($f1->get_id()));
3312 $this->assertFalse(competency::record_exists($c1->get_id()));
3313 $this->assertFalse(competency::record_exists($c2->get_id()));
3314 $this->assertFalse(competency::record_exists($c1a->get_id()));
3315 $this->assertFalse(competency::record_exists($c1b->get_id()));
3316 $this->assertFalse(competency::record_exists($c11b->get_id()));
3317 $this->assertFalse(competency::record_exists($c12b->get_id()));
3318 // Check if evidence are also deleted.
3319 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3320
3321 // Check if related conpetency relation is deleted.
3322 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3323 }
3324
3325 public function test_delete_framework_competency_used_in_usercompetency() {
3326 $this->resetAfterTest(true);
3327 $dg = $this->getDataGenerator();
3328 $lpg = $dg->get_plugin_generator('tool_lp');
3329 $this->setAdminUser();
3330
3331 $u1 = $dg->create_user();
3332
3333 $f1 = $lpg->create_framework();
3334 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3335 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3336 $c2id = $c2->get_id();
3337 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3338 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3339 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3340 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3341
3342 // Create related competencies.
3343 $rc = $lpg->create_related_competency(array(
3344 'competencyid' => $c2->get_id(),
3345 'relatedcompetencyid' => $c11b->get_id()
3346 ));
3347 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3348
3349 // Creating a standard evidence with minimal information.
3350 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3351 $usercompetencyid = $uc1->get_id();
3352 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3353 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3354 $uc1->delete();
3355
3356 // Create user competency.
3357 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3358
3359 // We can not delete a framework , if competency or competency children exist in user competency.
3360 $this->assertFalse(api::delete_framework($f1->get_id()));
3361 // Check that none of associated data are deleted.
3362 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3363 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3364
3365 // We can delete the framework if we remove the competency from user competency.
3366 $uc2->delete();
3367
3368 $this->assertTrue(api::delete_framework($f1->get_id()));
3369 $this->assertFalse(competency::record_exists($c1->get_id()));
3370 $this->assertFalse(competency::record_exists($c2->get_id()));
3371 $this->assertFalse(competency::record_exists($c1a->get_id()));
3372 $this->assertFalse(competency::record_exists($c1b->get_id()));
3373 $this->assertFalse(competency::record_exists($c11b->get_id()));
3374 $this->assertFalse(competency::record_exists($c12b->get_id()));
3375 // Check if evidence are also deleted.
3376 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3377
3378 // Check if related conpetency relation is deleted.
3379 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3380 }
3381
3382 public function test_delete_framework_competency_used_in_usercompetencyplan() {
3383 $this->resetAfterTest(true);
3384 $dg = $this->getDataGenerator();
3385 $lpg = $dg->get_plugin_generator('tool_lp');
3386 $this->setAdminUser();
3387
3388 $u1 = $dg->create_user();
3389
3390 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3391
3392 $f1 = $lpg->create_framework();
3393 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3394 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3395 $c2id = $c2->get_id();
3396 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3397 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3398 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3399 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3400
3401 // Create related competencies.
3402 $rc = $lpg->create_related_competency(array(
3403 'competencyid' => $c2->get_id(),
3404 'relatedcompetencyid' => $c11b->get_id()
3405 ));
3406 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3407
3408 // Creating a standard evidence with minimal information.
3409 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3410 $usercompetencyid = $uc1->get_id();
3411 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3412 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3413 $uc1->delete();
3414
3415 // Create user competency plan.
3416 $uc2 = $lpg->create_user_competency_plan(array(
3417 'userid' => $u1->id,
3418 'competencyid' => $c11b->get_id(),
3419 'planid' => $plan->get_id()
3420 ));
3421
3422 // We can not delete a framework , if competency or competency children exist in user competency plan.
3423 $this->assertFalse(api::delete_framework($f1->get_id()));
3424 // Check that none of associated data are deleted.
3425 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3426 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3427
3428 // We can delete the framework if we remove the competency from user competency plan.
3429 $uc2->delete();
3430
3431 $this->assertTrue(api::delete_framework($f1->get_id()));
3432 $this->assertFalse(competency::record_exists($c1->get_id()));
3433 $this->assertFalse(competency::record_exists($c2->get_id()));
3434 $this->assertFalse(competency::record_exists($c1a->get_id()));
3435 $this->assertFalse(competency::record_exists($c1b->get_id()));
3436 $this->assertFalse(competency::record_exists($c11b->get_id()));
3437 $this->assertFalse(competency::record_exists($c12b->get_id()));
3438 // Check if evidence are also deleted.
3439 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3440
3441 // Check if related conpetency relation is deleted.
3442 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3443 }
3444
3445 public function test_delete_framework_competency_used_in_template() {
3446 $this->resetAfterTest(true);
3447 $dg = $this->getDataGenerator();
3448 $lpg = $dg->get_plugin_generator('tool_lp');
3449 $this->setAdminUser();
3450
3451 $u1 = $dg->create_user();
3452 $template = $lpg->create_template();
3453
3454 $f1 = $lpg->create_framework();
3455 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3456 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3457 $c2id = $c2->get_id();
3458 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3459 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3460 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3461 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3462
3463 // Create related competencies.
3464 $rc = $lpg->create_related_competency(array(
3465 'competencyid' => $c2->get_id(),
3466 'relatedcompetencyid' => $c11b->get_id()
3467 ));
3468 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3469
3470 // Creating a standard evidence with minimal information.
3471 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3472 $usercompetencyid = $uc1->get_id();
3473 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3474 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3475 $uc1->delete();
3476
3477 // Add competency to a template.
3478 $tc = $lpg->create_template_competency(array(
3479 'templateid' => $template->get_id(),
3480 'competencyid' => $c11b->get_id()
3481 ));
3482 // We can not delete a framework , if competency or competency children is linked to template.
3483 $this->assertFalse(api::delete_framework($f1->get_id()));
3484 // Check that none of associated data are deleted.
3485 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3486 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3487
3488 // We can delete the framework if we remove the competency from template.
3489 $tc->delete();
3490
3491 $this->assertTrue(api::delete_framework($f1->get_id()));
3492 $this->assertFalse(competency::record_exists($c1->get_id()));
3493 $this->assertFalse(competency::record_exists($c2->get_id()));
3494 $this->assertFalse(competency::record_exists($c1a->get_id()));
3495 $this->assertFalse(competency::record_exists($c1b->get_id()));
3496 $this->assertFalse(competency::record_exists($c11b->get_id()));
3497 $this->assertFalse(competency::record_exists($c12b->get_id()));
3498 // Check if evidence are also deleted.
3499 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3500
3501 // Check if related conpetency relation is deleted.
3502 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3503 }
3504
3505 public function test_delete_framework_competency_used_in_course() {
3506 $this->resetAfterTest(true);
3507 $dg = $this->getDataGenerator();
3508 $lpg = $dg->get_plugin_generator('tool_lp');
3509 $this->setAdminUser();
3510
3511 $cat1 = $dg->create_category();
3512 $u1 = $dg->create_user();
3513 $course = $dg->create_course(array('category' => $cat1->id));
3514
3515 $f1 = $lpg->create_framework();
3516 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3517 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3518 $c2id = $c2->get_id();
3519 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3520 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3521 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3522 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3523
3524 // Create related competencies.
3525 $rc = $lpg->create_related_competency(array(
3526 'competencyid' => $c2->get_id(),
3527 'relatedcompetencyid' => $c11b->get_id()
3528 ));
3529 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3530
3531 // Creating a standard evidence with minimal information.
3532 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3533 $usercompetencyid = $uc1->get_id();
3534 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3535 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3536 $uc1->delete();
3537
3538 // Add competency to course.
3539 $cc = $lpg->create_course_competency(array(
3540 'courseid' => $course->id,
3541 'competencyid' => $c11b->get_id()
3542 ));
3543
3544 // We can not delete a framework if the competency or competencies children is linked to a course.
3545 $this->assertFalse(api::delete_framework($f1->get_id()));
3546 // Check that none of associated data are deleted.
3547 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3548 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3549
3550 // We can delete the framework if we remove the competency from course.
3551 $cc->delete();
3552
3553 $this->assertTrue(api::delete_framework($f1->get_id()));
3554 $this->assertFalse(competency::record_exists($c1->get_id()));
3555 $this->assertFalse(competency::record_exists($c2->get_id()));
3556 $this->assertFalse(competency::record_exists($c1a->get_id()));
3557 $this->assertFalse(competency::record_exists($c1b->get_id()));
3558 $this->assertFalse(competency::record_exists($c11b->get_id()));
3559 $this->assertFalse(competency::record_exists($c12b->get_id()));
3560 // Check if evidence are also deleted.
3561 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3562
3563 // Check if related conpetency relation is deleted.
3564 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3565 }
f45d0b37
FM
3566
3567 public function test_grade_competency_in_course_permissions() {
3568 $this->resetAfterTest();
3569 $dg = $this->getDataGenerator();
3570
3571 $c1 = $dg->create_course();
3572 $c2 = $dg->create_course();
3573 $sysctx = context_system::instance();
3574 $c1ctx = context_course::instance($c1->id);
3575 $c2ctx = context_course::instance($c2->id);
3576
3577 $teacher1 = $dg->create_user();
1fa13362 3578 $noneditingteacher = $dg->create_user();
f45d0b37
FM
3579 $student1 = $dg->create_user();
3580 $student2 = $dg->create_user();
3581 $notstudent1 = $dg->create_user();
3582
3583 $lpg = $dg->get_plugin_generator('tool_lp');
3584 $framework = $lpg->create_framework();
3585 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
3586 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
3587 $lpg->create_course_competency(array('courseid' => $c1->id, 'competencyid' => $comp1->get_id()));
3588
3589 $studentarch = get_archetype_roles('student');
3590 $studentrole = array_shift($studentarch);
3591
3592 $gradablerole = $dg->create_role();
3593 assign_capability('tool/lp:coursecompetencygradable', CAP_ALLOW, $gradablerole, $sysctx->id);
3594
3595 $notgradablerole = $dg->create_role();
3596 assign_capability('tool/lp:coursecompetencygradable', CAP_PROHIBIT, $notgradablerole, $sysctx->id);
3597
3598 $canviewucrole = $dg->create_role();
3599 assign_capability('tool/lp:usercompetencyview', CAP_ALLOW, $canviewucrole, $sysctx->id);
3600
3601 $cannotviewcomp = $dg->create_role();
3602 assign_capability('tool/lp:competencyread', CAP_PROHIBIT, $cannotviewcomp, $sysctx->id);
3603
3604 $canmanagecomp = $dg->create_role();
3605 assign_capability('tool/lp:competencymanage', CAP_ALLOW, $canmanagecomp, $sysctx->id);
3606
3607 $cangraderole = $dg->create_role();
3608 assign_capability('tool/lp:competencygrade', CAP_ALLOW, $cangraderole, $sysctx->id);
3609
3610 $cansuggestrole = $dg->create_role();
3611 assign_capability('tool/lp:competencysuggestgrade', CAP_ALLOW, $cansuggestrole, $sysctx->id);
3612
3613 // Enrol s1 and s2 as students in course 1.
3614 $dg->enrol_user($student1->id, $c1->id, $studentrole->id);
3615 $dg->enrol_user($student2->id, $c1->id, $studentrole->id);
3616
3617 // Mark the s2 as not being 'gradable'.
3618 $dg->role_assign($notgradablerole, $student2->id, $c1ctx->id);
3619
3620 // Mark the 'non a student' as 'gradable' throughout the site.
3621 $dg->role_assign($gradablerole, $notstudent1->id, $sysctx->id);
3622
3623 // From now we'll iterate over each permission.
3624 accesslib_clear_all_caches_for_unit_testing();
3625 $this->setUser($teacher1);
3626
3627 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View a user competency',