MDL-52775 tool_lp: get_course_competency and list_course_competencies
[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
1512 /**
1513 * Test remove plan and the managing of archived user competencies.
1514 */
1515 public function test_delete_plan_manage_archived_competencies() {
1516 $this->resetAfterTest(true);
1517 $dg = $this->getDataGenerator();
1518 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1519
1520 $syscontext = context_system::instance();
1521
1522 // Create user and role for the test.
1523 $user = $dg->create_user();
1524 $managerole = $dg->create_role(array(
1525 'name' => 'User manage own',
1526 'shortname' => 'manageown'
1527 ));
1528 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $managerole, $syscontext->id);
1529 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $managerole, $syscontext->id);
1530 $dg->role_assign($managerole, $user->id, $syscontext->id);
1531 $this->setUser($user);
1532
1533 // Create a framework and assign competencies.
1534 $framework = $lpg->create_framework();
1535 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1536 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1537 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1538
1539 // Create completed plan with records in user_competency.
1540 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
1541
1542 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
1543 $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
1544
1545 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
1546 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
1547
1548 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1549 'planid' => $completedplan->get_id()));
1550 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1551 'planid' => $completedplan->get_id()));
1552
1553 api::delete_plan($completedplan->get_id());
1554
1555 // Check that achived user competencies are deleted.
1556 $this->assertEquals(0, \tool_lp\plan::count_records());
1557 $this->assertEquals(2, \tool_lp\user_competency::count_records());
1558 $this->assertEquals(0, \tool_lp\user_competency_plan::count_records());
1559 }
1560
1561 /**
1562 * Test listing of plan competencies.
1563 */
1564 public function test_list_plan_competencies_manage_archived_competencies() {
1565 $this->resetAfterTest(true);
1566 $dg = $this->getDataGenerator();
1567 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1568
1569 $syscontext = context_system::instance();
1570
1571 // Create user and role for the test.
1572 $user = $dg->create_user();
1573 $viewrole = $dg->create_role(array(
1574 'name' => 'User view',
1575 'shortname' => 'view'
1576 ));
1577 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $viewrole, $syscontext->id);
1578 assign_capability('tool/lp:planview', CAP_ALLOW, $viewrole, $syscontext->id);
1579 $dg->role_assign($viewrole, $user->id, $syscontext->id);
1580 $this->setUser($user);
1581
1582 // Create a framework and assign competencies.
1583 $framework = $lpg->create_framework();
1584 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1585 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1586 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
1587
1588 // Create draft plan with records in user_competency.
1589 $draftplan = $lpg->create_plan(array('userid' => $user->id));
1590
1591 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c1->get_id()));
1592 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c2->get_id()));
1593 $lpg->create_plan_competency(array('planid' => $draftplan->get_id(), 'competencyid' => $c3->get_id()));
1594
1595 $uc1 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
1596 $uc2 = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c2->get_id()));
1597
1598 // Check that user_competency objects are returned when plan status is not complete.
1599 $plancompetencies = api::list_plan_competencies($draftplan);
1600
1601 $this->assertCount(3, $plancompetencies);
1602 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[0]->usercompetency);
1603 $this->assertEquals($uc1->get_id(), $plancompetencies[0]->usercompetency->get_id());
1604 $this->assertNull($plancompetencies[0]->usercompetencyplan);
1605
1606 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[1]->usercompetency);
1607 $this->assertEquals($uc2->get_id(), $plancompetencies[1]->usercompetency->get_id());
1608 $this->assertNull($plancompetencies[1]->usercompetencyplan);
1609
1610 $this->assertInstanceOf('\tool_lp\user_competency', $plancompetencies[2]->usercompetency);
1611 $this->assertEquals(0, $plancompetencies[2]->usercompetency->get_id());
1612 $this->assertNull($plancompetencies[2]->usercompetencyplan);
1613
1614 // Create completed plan with records in user_competency_plan.
1615 $completedplan = $lpg->create_plan(array('userid' => $user->id, 'status' => \tool_lp\plan::STATUS_COMPLETE));
1616
1617 $pc1 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c1->get_id()));
1618 $pc2 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c2->get_id()));
1619 $pc3 = $lpg->create_plan_competency(array('planid' => $completedplan->get_id(), 'competencyid' => $c3->get_id()));
1620
1621 $ucp1 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c1->get_id(),
1622 'planid' => $completedplan->get_id()));
1623 $ucp2 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c2->get_id(),
1624 'planid' => $completedplan->get_id()));
192569ed
JPG
1625 $ucp3 = $lpg->create_user_competency_plan(array('userid' => $user->id, 'competencyid' => $c3->get_id(),
1626 'planid' => $completedplan->get_id()));
1627
1628 // Check that user_competency_plan objects are returned when plan status is complete.
1629 $plancompetencies = api::list_plan_competencies($completedplan);
1630
1631 $this->assertCount(3, $plancompetencies);
1632 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[0]->usercompetencyplan);
1633 $this->assertEquals($ucp1->get_id(), $plancompetencies[0]->usercompetencyplan->get_id());
1634 $this->assertNull($plancompetencies[0]->usercompetency);
1635 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[1]->usercompetencyplan);
1636 $this->assertEquals($ucp2->get_id(), $plancompetencies[1]->usercompetencyplan->get_id());
1637 $this->assertNull($plancompetencies[1]->usercompetency);
1638 $this->assertInstanceOf('\tool_lp\user_competency_plan', $plancompetencies[2]->usercompetencyplan);
1639 $this->assertEquals($ucp3->get_id(), $plancompetencies[2]->usercompetencyplan->get_id());
1640 $this->assertNull($plancompetencies[2]->usercompetency);
1641 }
1642
bee480a4
FM
1643 public function test_create_template_cohort() {
1644 $this->resetAfterTest(true);
1645 $this->setAdminUser();
1646
1647 $dg = $this->getDataGenerator();
1648 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1649
1650 $c1 = $dg->create_cohort();
1651 $c2 = $dg->create_cohort();
1652 $t1 = $lpg->create_template();
1653 $t2 = $lpg->create_template();
1654
1655 $this->assertEquals(0, \tool_lp\template_cohort::count_records());
1656
1657 // Create two relations with mixed parameters.
1658 $result = api::create_template_cohort($t1->get_id(), $c1->id);
1659 $result = api::create_template_cohort($t1, $c2);
1660
1661 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
1662 $this->assertInstanceOf('tool_lp\template_cohort', $result);
1663 $this->assertEquals($c2->id, $result->get_cohortid());
1664 $this->assertEquals($t1->get_id(), $result->get_templateid());
1665 $this->assertEquals(2, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1666 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1667 }
1668
5a4ee001
IT
1669 public function test_delete_template() {
1670 $this->resetAfterTest(true);
1671 $this->setAdminUser();
1672
1673 $dg = $this->getDataGenerator();
1674 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1675
1676 $c1 = $dg->create_cohort();
1677 $c2 = $dg->create_cohort();
1678 $template = $lpg->create_template();
1679 $id = $template->get_id();
1680
1681 // Create 2 template cohorts.
1682 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c1->id));
1683 $tc1 = $lpg->create_template_cohort(array('templateid' => $template->get_id(), 'cohortid' => $c2->id));
1684
1685 // Check pre-test.
1686 $this->assertTrue(tool_lp\template::record_exists($id));
1687 $this->assertEquals(2, \tool_lp\template_cohort::count_records(array('templateid' => $id)));
1688
1689 $result = api::delete_template($template->get_id());
1690 $this->assertTrue($result);
1691
1692 // Check that the template deos not exist anymore.
1693 $this->assertFalse(tool_lp\template::record_exists($id));
1694
1695 // Test if associated cohorts are also deleted.
1696 $this->assertEquals(0, \tool_lp\template_cohort::count_records(array('templateid' => $id)));
1697 }
1698
bee480a4
FM
1699 public function test_delete_template_cohort() {
1700 $this->resetAfterTest(true);
1701 $this->setAdminUser();
1702
1703 $dg = $this->getDataGenerator();
1704 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
1705
1706 $c1 = $dg->create_cohort();
1707 $c2 = $dg->create_cohort();
1708 $t1 = $lpg->create_template();
1709 $t2 = $lpg->create_template();
1710 $tc1 = $lpg->create_template_cohort(array('templateid' => $t1->get_id(), 'cohortid' => $c1->id));
1711 $tc1 = $lpg->create_template_cohort(array('templateid' => $t2->get_id(), 'cohortid' => $c2->id));
1712
1713 $this->assertEquals(2, \tool_lp\template_cohort::count_records());
1714 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1715 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1716
1717 // Delete existing.
1718 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1719 $this->assertTrue($result);
1720 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1721 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1722 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1723
1724 // Delete non-existant.
1725 $result = api::delete_template_cohort($t1->get_id(), $c1->id);
1726 $this->assertTrue($result);
1727 $this->assertEquals(1, \tool_lp\template_cohort::count_records());
1728 $this->assertEquals(0, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t1->get_id())));
1729 $this->assertEquals(1, \tool_lp\template_cohort::count_records_select('templateid = :id', array('id' => $t2->get_id())));
1730 }
4c0e8167 1731
914b580e
FM
1732 public function test_add_evidence_log() {
1733 $this->resetAfterTest(true);
1734 $dg = $this->getDataGenerator();
1735 $lpg = $dg->get_plugin_generator('tool_lp');
1736
1737 $u1 = $dg->create_user();
1738 $u1ctx = context_user::instance($u1->id);
1739 $f1 = $lpg->create_framework();
1740 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1741 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1742
1743 // Creating a standard evidence with minimal information.
1744 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error');
1745 $evidence->read();
1746 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1747 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1748 $this->assertSame(null, $uc->get_grade());
1749 $this->assertSame(null, $uc->get_proficiency());
1750 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1751 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1752 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1753 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1754 $this->assertEquals('error', $evidence->get_desccomponent());
1755 $this->assertSame(null, $evidence->get_desca());
1756 $this->assertSame(null, $evidence->get_url());
1757 $this->assertSame(null, $evidence->get_grade());
1758 $this->assertSame(null, $evidence->get_actionuserid());
1759
1760 // Creating a standard evidence with more information.
1761 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
d17cbbfb 1762 '$a', false, 'http://moodle.org', null, 2, 'The evidence of prior learning were reviewed.');
914b580e
FM
1763 $evidence->read();
1764 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1765 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1766 $this->assertSame(null, $uc->get_grade());
1767 $this->assertSame(null, $uc->get_proficiency());
1768 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1769 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1770 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $evidence->get_action());
1771 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1772 $this->assertEquals('error', $evidence->get_desccomponent());
1773 $this->assertEquals('$a', $evidence->get_desca());
1774 $this->assertEquals('http://moodle.org', $evidence->get_url());
1775 $this->assertSame(null, $evidence->get_grade());
1776 $this->assertEquals(2, $evidence->get_actionuserid());
d17cbbfb 1777 $this->assertSame('The evidence of prior learning were reviewed.', $evidence->get_note());
914b580e
FM
1778
1779 // Creating a standard evidence and send for review.
1780 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
1781 'error', null, true);
1782 $evidence->read();
1783 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1784 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1785
1786 // Trying to pass a grade should fail.
1787 try {
1788 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata', 'error',
1789 null, false, null, 1);
1790 $this->fail('A grade can not be set');
1791 } catch (coding_exception $e) {
1792 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
1793 }
1794 }
1795
1796 public function test_add_evidence_suggest() {
1797 $this->resetAfterTest(true);
1798 $dg = $this->getDataGenerator();
1799 $lpg = $dg->get_plugin_generator('tool_lp');
1800
1801 $u1 = $dg->create_user();
1802 $u1ctx = context_user::instance($u1->id);
1803 $f1 = $lpg->create_framework();
1804 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1805 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1806
1807 // Creating an evidence with minimal information.
1808 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1809 'error', null, false, null, 1, 2);
1810 $evidence->read();
1811 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1812 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1813 $this->assertSame(null, $uc->get_grade()); // We don't grade, we just suggest.
1814 $this->assertSame(null, $uc->get_proficiency());
1815 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1816 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1817 $this->assertEquals(\tool_lp\evidence::ACTION_SUGGEST, $evidence->get_action());
1818 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1819 $this->assertEquals('error', $evidence->get_desccomponent());
1820 $this->assertSame(null, $evidence->get_desca());
1821 $this->assertSame(null, $evidence->get_url());
1822 $this->assertEquals(1, $evidence->get_grade());
1823 $this->assertEquals(2, $evidence->get_actionuserid());
1824
1825 // Creating a standard evidence and send for review.
1826 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata',
1827 'error', null, true, null, 1, 2);
1828 $evidence->read();
1829 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1830 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1831
1832 // Trying not to pass a grade should fail.
1833 try {
1834 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_SUGGEST, 'invaliddata', 'error',
1835 false, null);
1836 $this->fail('A grade must be set');
1837 } catch (coding_exception $e) {
1838 $this->assertRegExp('/grade MUST be set/', $e->getMessage());
1839 }
1840 }
1841
1842 public function test_add_evidence_complete() {
1843 $this->resetAfterTest(true);
1844 $dg = $this->getDataGenerator();
1845 $lpg = $dg->get_plugin_generator('tool_lp');
1846
1847 $u1 = $dg->create_user();
1848 $u1ctx = context_user::instance($u1->id);
1849 $scale = $dg->create_scale(array('scale' => 'A,B,C,D'));
1850 $scaleconfig = array(array('scaleid' => $scale->id));
1851 $scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1852 $scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 1, 'proficient' => 0);
1853 $scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 1);
1854 $scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 0, 'proficient' => 1);
1855 $c2scaleconfig = array(array('scaleid' => $scale->id));
1856 $c2scaleconfig[] = array('name' => 'A', 'id' => 1, 'scaledefault' => 0, 'proficient' => 0);
1857 $c2scaleconfig[] = array('name' => 'B', 'id' => 2, 'scaledefault' => 0, 'proficient' => 1);
1858 $c2scaleconfig[] = array('name' => 'C', 'id' => 3, 'scaledefault' => 0, 'proficient' => 0);
1859 $c2scaleconfig[] = array('name' => 'D', 'id' => 4, 'scaledefault' => 1, 'proficient' => 1);
1860 $f1 = $lpg->create_framework(array('scaleid' => $scale->id, 'scaleconfiguration' => $scaleconfig));
1861 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1862 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'scaleid' => $scale->id,
1863 'scaleconfiguration' => $c2scaleconfig));
1864 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1865
1866 // Creating an evidence with minimal information.
1867 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1868 'error');
1869 $evidence->read();
1870 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1871 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1872 $this->assertEquals(2, $uc->get_grade()); // The grade has been set automatically to the framework default.
1873 $this->assertEquals(0, $uc->get_proficiency());
1874 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1875 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1876 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1877 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1878 $this->assertEquals('error', $evidence->get_desccomponent());
1879 $this->assertSame(null, $evidence->get_desca());
1880 $this->assertSame(null, $evidence->get_url());
1881 $this->assertEquals(2, $evidence->get_grade());
1882 $this->assertSame(null, $evidence->get_actionuserid());
1883
1884 // Creating an evidence complete on competency with custom scale.
1885 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1886 'error');
1887 $evidence->read();
1888 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1889 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1890 $this->assertEquals(4, $uc->get_grade()); // The grade has been set automatically to the competency default.
1891 $this->assertEquals(true, $uc->get_proficiency());
1892 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1893 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1894 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1895 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1896 $this->assertEquals('error', $evidence->get_desccomponent());
1897 $this->assertSame(null, $evidence->get_desca());
1898 $this->assertSame(null, $evidence->get_url());
1899 $this->assertEquals(4, $evidence->get_grade());
1900 $this->assertSame(null, $evidence->get_actionuserid());
1901
1902 // Creating an evidence complete on a user competency with an existing grade.
1903 $uc = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get_id(), 'grade' => 1,
1904 'proficiency' => 0));
1905 $this->assertEquals(1, $uc->get_grade());
1906 $this->assertEquals(0, $uc->get_proficiency());
1907 $evidence = api::add_evidence($u1->id, $c3->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1908 'error');
1909 $evidence->read();
1910 $uc->read();
1911 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1912 $this->assertEquals(1, $uc->get_grade()); // The grade has not been changed.
1913 $this->assertEquals(0, $uc->get_proficiency());
1914 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1915 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1916 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $evidence->get_action());
1917 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1918 $this->assertEquals('error', $evidence->get_desccomponent());
1919 $this->assertSame(null, $evidence->get_desca());
1920 $this->assertSame(null, $evidence->get_url());
1921 $this->assertEquals(2, $evidence->get_grade()); // The complete grade has been set.
1922 $this->assertSame(null, $evidence->get_actionuserid());
1923
1924 // Creating a standard evidence and send for review.
1925 $evidence = api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1926 'error', null, true);
1927 $evidence->read();
1928 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
1929 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
1930
1931 // Trying to pass a grade should throw an exception.
1932 try {
1933 api::add_evidence($u1->id, $c2->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_COMPLETE, 'invaliddata',
1934 'error', null, false, null, 1);
1935 } catch (coding_exception $e) {
1936 $this->assertRegExp('/grade MUST NOT be set/', $e->getMessage());
1937 }
1938 }
1939
1940 public function test_add_evidence_override() {
1941 $this->resetAfterTest(true);
1942 $dg = $this->getDataGenerator();
1943 $lpg = $dg->get_plugin_generator('tool_lp');
1944
1945 $u1 = $dg->create_user();
1946 $u1ctx = context_user::instance($u1->id);
1947 $f1 = $lpg->create_framework();
1948 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
1949
1950 // Creating an evidence with minimal information.
1951 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1952 'error');
1953 $evidence->read();
1954 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1955 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1956 $this->assertSame(null, $uc->get_grade()); // We overrode with 'null'.
1957 $this->assertSame(null, $uc->get_proficiency());
1958 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1959 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1960 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1961 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1962 $this->assertEquals('error', $evidence->get_desccomponent());
1963 $this->assertSame(null, $evidence->get_desca());
1964 $this->assertSame(null, $evidence->get_url());
1965 $this->assertSame(null, $evidence->get_grade()); // We overrode with 'null'.
1966 $this->assertSame(null, $evidence->get_actionuserid());
1967
1968 // Creating an evidence with a grade information.
1969 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1970 'error', null, false, null, 3);
1971 $evidence->read();
1972 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1973 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1974 $this->assertEquals(3, $uc->get_grade());
1975 $this->assertEquals(true, $uc->get_proficiency());
1976 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1977 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1978 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1979 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1980 $this->assertEquals('error', $evidence->get_desccomponent());
1981 $this->assertSame(null, $evidence->get_desca());
1982 $this->assertSame(null, $evidence->get_url());
1983 $this->assertEquals(3, $evidence->get_grade());
1984 $this->assertSame(null, $evidence->get_actionuserid());
1985
1986 // Creating an evidence with another grade information.
1987 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
1988 'error', null, false, null, 1);
1989 $evidence->read();
1990 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
1991 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc->get_status());
1992 $this->assertEquals(1, $uc->get_grade());
1993 $this->assertEquals(0, $uc->get_proficiency());
1994 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
1995 $this->assertEquals($u1ctx->id, $evidence->get_contextid());
1996 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
1997 $this->assertEquals('invaliddata', $evidence->get_descidentifier());
1998 $this->assertEquals('error', $evidence->get_desccomponent());
1999 $this->assertSame(null, $evidence->get_desca());
2000 $this->assertSame(null, $evidence->get_url());
2001 $this->assertEquals(1, $evidence->get_grade());
2002 $this->assertSame(null, $evidence->get_actionuserid());
2003
2004 // Creating reverting the grade and send for review.
2005 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_OVERRIDE, 'invaliddata',
2006 'error', null, true);
2007 $evidence->read();
2008 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2009 $this->assertSame(null, $uc->get_grade());
2010 $this->assertSame(null, $uc->get_proficiency());
2011 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2012 $this->assertSame(null, $evidence->get_grade());
2013 }
2014
2015 public function test_add_evidence_and_send_for_review() {
2016 $this->resetAfterTest(true);
2017 $dg = $this->getDataGenerator();
2018 $lpg = $dg->get_plugin_generator('tool_lp');
2019
2020 $u1 = $dg->create_user();
2021 $u1ctx = context_user::instance($u1->id);
2022 $f1 = $lpg->create_framework();
2023 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2024
2025 // Non-existing user competencies are created up for review.
2026 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2027 'error', null, true);
2028 $uc = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2029 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2030
2031 // Existing user competencies sent for review don't change.
2032 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2033 'error', null, true);
2034 $uc->read();
2035 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc->get_status());
2036
2037 // A user competency with a status non-idle won't change.
2038 $uc->set_status(\tool_lp\user_competency::STATUS_IN_REVIEW);
2039 $uc->update();
2040 $evidence = api::add_evidence($u1->id, $c1->get_id(), $u1ctx->id, \tool_lp\evidence::ACTION_LOG, 'invaliddata',
2041 'error', null, true);
2042 $uc->read();
2043 $this->assertEquals(\tool_lp\user_competency::STATUS_IN_REVIEW, $uc->get_status());
2044 }
2045
4c0e8167
SG
2046 /**
2047 * Test add evidence for existing user_competency.
2048 */
2049 public function test_add_evidence_existing_user_competency() {
2050 $this->resetAfterTest(true);
2051 $dg = $this->getDataGenerator();
2052 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2053
2054 $syscontext = context_system::instance();
2055
2056 // Create users.
2057 $user = $dg->create_user();
2058 $this->setUser($user);
2059
2060 // Create a framework and assign competencies.
2061 $framework = $lpg->create_framework();
2062 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2063 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2064 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2065 $uc = $lpg->create_user_competency(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
914b580e
FM
2066 $this->assertSame(null, $uc->get_grade());
2067 $this->assertSame(null, $uc->get_proficiency());
4c0e8167
SG
2068
2069 // Create an evidence and check it was created with the right usercomptencyid and information.
914b580e
FM
2070 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
2071 'invalidevidencedesc', 'tool_lp', array('a' => 'b'), false, 'http://moodle.org', 1, 2);
4c0e8167
SG
2072 $this->assertEquals(1, \tool_lp\evidence::count_records());
2073
2074 $evidence->read();
914b580e 2075 $uc->read();
4c0e8167
SG
2076 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2077 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
2078 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
2079 $this->assertEquals((object) array('a' => 'b'), $evidence->get_desca());
914b580e
FM
2080 $this->assertEquals('http://moodle.org', $evidence->get_url());
2081 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2082 $this->assertEquals(2, $evidence->get_actionuserid());
4c0e8167 2083 $this->assertEquals(1, $evidence->get_grade());
914b580e
FM
2084 $this->assertEquals(1, $uc->get_grade());
2085 $this->assertEquals(0, $uc->get_proficiency());
4c0e8167
SG
2086 }
2087
2088 /**
914b580e 2089 * Test add evidence for non-existing user_competency.
4c0e8167
SG
2090 */
2091 public function test_add_evidence_no_existing_user_competency() {
2092 $this->resetAfterTest(true);
2093 $dg = $this->getDataGenerator();
2094 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2095
2096 $syscontext = context_system::instance();
2097
2098 // Create users.
2099 $user = $dg->create_user();
2100 $this->setUser($user);
2101
2102 // Create a framework and assign competencies.
2103 $framework = $lpg->create_framework();
2104 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2105 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
914b580e 2106 $this->assertEquals(0, \tool_lp\user_competency::count_records());
4c0e8167 2107
914b580e
FM
2108 // Create an evidence without a user competency record.
2109 $evidence = api::add_evidence($user->id, $c1->get_id(), $syscontext->id, \tool_lp\evidence::ACTION_OVERRIDE,
2110 'invalidevidencedesc', 'tool_lp', 'Hello world!', false, 'http://moodle.org', 1, 2);
4c0e8167 2111 $this->assertEquals(1, \tool_lp\evidence::count_records());
914b580e 2112 $this->assertEquals(1, \tool_lp\user_competency::count_records());
4c0e8167 2113
914b580e
FM
2114 $uc = \tool_lp\user_competency::get_record(array('userid' => $user->id, 'competencyid' => $c1->get_id()));
2115 $evidence->read();
2116 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
2117 $this->assertEquals('invalidevidencedesc', $evidence->get_descidentifier());
2118 $this->assertEquals('tool_lp', $evidence->get_desccomponent());
2119 $this->assertEquals('Hello world!', $evidence->get_desca());
2120 $this->assertEquals('http://moodle.org', $evidence->get_url());
2121 $this->assertEquals(\tool_lp\evidence::ACTION_OVERRIDE, $evidence->get_action());
2122 $this->assertEquals(2, $evidence->get_actionuserid());
2123 $this->assertEquals(1, $evidence->get_grade());
2124 $this->assertEquals(1, $uc->get_grade());
2125 $this->assertEquals(0, $uc->get_proficiency());
2126 }
2127
9373acf6
FM
2128 public function test_add_evidence_applies_competency_rules() {
2129 $this->resetAfterTest(true);
2130 $dg = $this->getDataGenerator();
2131 $lpg = $dg->get_plugin_generator('tool_lp');
2132 $syscontext = context_system::instance();
2133 $ctxid = $syscontext->id;
2134
2135 $u1 = $dg->create_user();
2136
2137 // Setting up the framework.
2138 $f1 = $lpg->create_framework();
2139 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2140 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2141 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2142 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2143 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c2->get_id()));
2144 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2145 $c3a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c3->get_id()));
2146 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2147 $c4a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c4->get_id()));
2148 $c5 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2149
2150 // Setting up the rules.
2151 $c1->set_ruletype('tool_lp\\competency_rule_all');
2152 $c1->set_ruleoutcome(\tool_lp\competency::OUTCOME_COMPLETE);
2153 $c1->update();
2154 $c2->set_ruletype('tool_lp\\competency_rule_all');
2155 $c2->set_ruleoutcome(\tool_lp\competency::OUTCOME_RECOMMEND);
2156 $c2->update();
2157 $c3->set_ruletype('tool_lp\\competency_rule_all');
2158 $c3->set_ruleoutcome(\tool_lp\competency::OUTCOME_EVIDENCE);
2159 $c3->update();
2160 $c4->set_ruletype('tool_lp\\competency_rule_all');
2161 $c4->set_ruleoutcome(\tool_lp\competency::OUTCOME_NONE);
2162 $c4->update();
2163
2164 // Confirm the current data.
2165 $this->assertEquals(0, user_competency::count_records());
2166 $this->assertEquals(0, evidence::count_records());
2167
2168 // Let's do this!
2169 // First let's confirm that evidence not marking a completion have no impact.
2170 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_LOG, 'commentincontext', 'core');
2171 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id()));
2172 $this->assertSame(null, $uc1a->get_proficiency());
2173 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c1->get_id())));
2174
2175 api::add_evidence($u1->id, $c2a, $ctxid, evidence::ACTION_SUGGEST, 'commentincontext', 'core', null, false, null, 1);
2176 $uc2a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2a->get_id()));
2177 $this->assertSame(null, $uc2a->get_proficiency());
2178 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c2->get_id())));
2179
2180 // Now let's try complete a competency but the rule won't match (not all children are complete).
2181 // The parent (the thing with the rule) will be created but won't have any evidence attached, and not
2182 // not be marked as completed.
2183 api::add_evidence($u1->id, $c1a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2184 $uc1a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1a->get_id()));
2185 $this->assertEquals(true, $uc1a->get_proficiency());
2186 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2187 $this->assertSame(null, $uc1->get_proficiency());
2188 $this->assertEquals(0, evidence::count_records(array('usercompetencyid' => $uc1->get_id())));
2189
2190 // Now we complete the other child. That will mark the parent as complete with an evidence.
2191 api::add_evidence($u1->id, $c1b, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2192 $uc1b = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1b->get_id()));
2193 $this->assertEquals(true, $uc1a->get_proficiency());
2194 $uc1 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c1->get_id()));
2195 $this->assertEquals(true, $uc1->get_proficiency());
2196 $this->assertEquals(user_competency::STATUS_IDLE, $uc1->get_status());
2197 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc1->get_id())));
2198
2199 // Check rule recommending.
2200 api::add_evidence($u1->id, $c2a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2201 $uc2a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2a->get_id()));
2202 $this->assertEquals(true, $uc1a->get_proficiency());
2203 $uc2 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
2204 $this->assertSame(null, $uc2->get_proficiency());
2205 $this->assertEquals(user_competency::STATUS_WAITING_FOR_REVIEW, $uc2->get_status());
2206 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc2->get_id())));
2207
2208 // Check rule evidence.
2209 api::add_evidence($u1->id, $c3a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2210 $uc3a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3a->get_id()));
2211 $this->assertEquals(true, $uc1a->get_proficiency());
2212 $uc3 = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id()));
2213 $this->assertSame(null, $uc3->get_proficiency());
2214 $this->assertEquals(user_competency::STATUS_IDLE, $uc3->get_status());
2215 $this->assertEquals(1, evidence::count_records(array('usercompetencyid' => $uc3->get_id())));
2216
2217 // Check rule nothing.
2218 api::add_evidence($u1->id, $c4a, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2219 $uc4a = user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4a->get_id()));
2220 $this->assertEquals(true, $uc1a->get_proficiency());
2221 $this->assertFalse(user_competency::record_exists_select('userid = ? AND competencyid = ?', array($u1->id, $c4->get_id())));
2222
2223 // Check marking on something that has no parent. This just checks that nothing breaks.
2224 api::add_evidence($u1->id, $c5, $ctxid, evidence::ACTION_COMPLETE, 'commentincontext', 'core');
2225 }
2226
914b580e
FM
2227 public function test_observe_course_completed() {
2228 $this->resetAfterTest(true);
2229 $dg = $this->getDataGenerator();
2230 $lpg = $dg->get_plugin_generator('tool_lp');
2231
2232 // Set-up users, framework, competencies and course competencies.
2233 $course = $dg->create_course();
2234 $coursectx = context_course::instance($course->id);
2235 $u1 = $dg->create_user();
2236 $f1 = $lpg->create_framework();
2237 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2238 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2239 $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2240 $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2241 $cc1 = $lpg->create_course_competency(array('competencyid' => $c1->get_id(), 'courseid' => $course->id,
2242 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_NONE));
2243 $cc2 = $lpg->create_course_competency(array('competencyid' => $c2->get_id(), 'courseid' => $course->id,
2244 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_EVIDENCE));
2245 $cc3 = $lpg->create_course_competency(array('competencyid' => $c3->get_id(), 'courseid' => $course->id,
2246 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_RECOMMEND));
2247 $cc4 = $lpg->create_course_competency(array('competencyid' => $c4->get_id(), 'courseid' => $course->id,
2248 'ruleoutcome' => \tool_lp\course_competency::OUTCOME_COMPLETE));
2249
2250 $event = \core\event\course_completed::create(array(
2251 'objectid' => 1,
2252 'relateduserid' => $u1->id,
2253 'context' => $coursectx,
2254 'courseid' => $course->id,
2255 'other' => array('relateduserid' => $u1->id)
2256 ));
2257 $this->assertEquals(0, \tool_lp\user_competency::count_records());
2258 $this->assertEquals(0, \tool_lp\evidence::count_records());
2259
2260 // Let's go!
2261 api::observe_course_completed($event);
2262 $this->assertEquals(3, \tool_lp\user_competency::count_records());
2263 $this->assertEquals(3, \tool_lp\evidence::count_records());
2264
2265 // Outcome NONE did nothing.
2266 $this->assertFalse(\tool_lp\user_competency::record_exists_select('userid = :uid AND competencyid = :cid', array(
2267 'uid' => $u1->id, 'cid' => $c1->get_id()
2268 )));
2269
2270 // Outcome evidence.
2271 $uc2 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id()));
2272 $ev2 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc2->get_id()));
2273
2274 $this->assertEquals(null, $uc2->get_grade());
2275 $this->assertEquals(null, $uc2->get_proficiency());
2276 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc2->get_status());
2277
2278 $this->assertEquals('evidence_coursecompleted', $ev2->get_descidentifier());
2279 $this->assertEquals('tool_lp', $ev2->get_desccomponent());
2280 $this->assertEquals($course->shortname, $ev2->get_desca());
2281 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev2->get_url());
2282 $this->assertEquals(null, $ev2->get_grade());
2283 $this->assertEquals($coursectx->id, $ev2->get_contextid());
2284 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev2->get_action());
2285 $this->assertEquals(null, $ev2->get_actionuserid());
2286
2287 // Outcome recommend.
2288 $uc3 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id()));
2289 $ev3 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc3->get_id()));
2290
2291 $this->assertEquals(null, $uc3->get_grade());
2292 $this->assertEquals(null, $uc3->get_proficiency());
2293 $this->assertEquals(\tool_lp\user_competency::STATUS_WAITING_FOR_REVIEW, $uc3->get_status());
2294
2295 $this->assertEquals('evidence_coursecompleted', $ev3->get_descidentifier());
2296 $this->assertEquals('tool_lp', $ev3->get_desccomponent());
2297 $this->assertEquals($course->shortname, $ev3->get_desca());
2298 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev3->get_url());
2299 $this->assertEquals(null, $ev3->get_grade());
2300 $this->assertEquals($coursectx->id, $ev3->get_contextid());
2301 $this->assertEquals(\tool_lp\evidence::ACTION_LOG, $ev3->get_action());
2302 $this->assertEquals(null, $ev3->get_actionuserid());
2303
2304 // Outcome complete.
2305 $uc4 = \tool_lp\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4->get_id()));
2306 $ev4 = \tool_lp\evidence::get_record(array('usercompetencyid' => $uc4->get_id()));
2307
2308 $this->assertEquals(3, $uc4->get_grade());
2309 $this->assertEquals(1, $uc4->get_proficiency());
2310 $this->assertEquals(\tool_lp\user_competency::STATUS_IDLE, $uc4->get_status());
2311
2312 $this->assertEquals('evidence_coursecompleted', $ev4->get_descidentifier());
2313 $this->assertEquals('tool_lp', $ev4->get_desccomponent());
2314 $this->assertEquals($course->shortname, $ev4->get_desca());
2315 $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev4->get_url());
2316 $this->assertEquals(3, $ev4->get_grade());
2317 $this->assertEquals($coursectx->id, $ev4->get_contextid());
2318 $this->assertEquals(\tool_lp\evidence::ACTION_COMPLETE, $ev4->get_action());
2319 $this->assertEquals(null, $ev4->get_actionuserid());
4c0e8167 2320 }
d4c0a2f6 2321
db650737
DW
2322 public function test_list_course_modules_using_competency() {
2323 global $SITE;
2324
2325 $this->resetAfterTest(true);
2326 $dg = $this->getDataGenerator();
2327 $lpg = $dg->get_plugin_generator('tool_lp');
2328 $u1 = $dg->create_user();
2329 $u2 = $dg->create_user();
2330 $course = $dg->create_course();
2331 $course2 = $dg->create_course();
2332
2333 $this->setAdminUser();
2334 $f = $lpg->create_framework();
2335 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2336 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2337 $cc = api::add_competency_to_course($course->id, $c->get_id());
2338 $cc2 = api::add_competency_to_course($course->id, $c2->get_id());
2339
2340 // First check we get an empty list when there are no links.
2341 $expected = array();
2342 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2343 $this->assertEquals($expected, $result);
2344
2345 $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
2346 $page = $pagegenerator->create_instance(array('course'=>$course->id));
2347
2348 $cm = get_coursemodule_from_instance('page', $page->id);
2349 // Add a link and list again.
2350 $ccm = api::add_competency_to_course_module($cm, $c->get_id());
f446b2e1 2351 $expected = array($cm->id);
db650737
DW
2352 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2353 $this->assertEquals($expected, $result);
2354
2355 // Check a different course.
2356 $expected = array();
2357 $result = api::list_course_modules_using_competency($c->get_id(), $course2->id);
2358 $this->assertEquals($expected, $result);
2359
2360 // Remove the link and check again.
2361 $result = api::remove_competency_from_course_module($cm, $c->get_id());
2362 $expected = true;
2363 $this->assertEquals($expected, $result);
2364 $expected = array();
2365 $result = api::list_course_modules_using_competency($c->get_id(), $course->id);
2366 $this->assertEquals($expected, $result);
2367
2368 // Now add 2 links.
2369 api::add_competency_to_course_module($cm, $c->get_id());
2370 api::add_competency_to_course_module($cm, $c2->get_id());
2371 $result = api::list_course_module_competencies_in_course_module($cm->id);
2372 $this->assertEquals($result[0]->get_competencyid(), $c->get_id());
2373 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
2374
2375 // Now re-order.
2376 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
2377 $result = api::list_course_module_competencies_in_course_module($cm->id);
2378 $this->assertEquals($result[0]->get_competencyid(), $c2->get_id());
2379 $this->assertEquals($result[1]->get_competencyid(), $c->get_id());
2380
2381 // And re-order again.
2382 api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
2383 $result = api::list_course_module_competencies_in_course_module($cm->id);
2384 $this->assertEquals($result[0]->get_competencyid(), $c->get_id());
2385 $this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
2386 }
2387
d4c0a2f6
SG
2388 /**
2389 * Test update ruleoutcome for course_competency.
2390 */
d660824b 2391 public function test_set_ruleoutcome_course_competency() {
d4c0a2f6
SG
2392 $this->resetAfterTest(true);
2393 $dg = $this->getDataGenerator();
2394 $lpg = $dg->get_plugin_generator('tool_lp');
2395 $u1 = $dg->create_user();
2396 $u2 = $dg->create_user();
d660824b 2397 $course = $dg->create_course();
d4c0a2f6
SG
2398
2399 $this->setAdminUser();
2400 $f = $lpg->create_framework();
2401 $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
d660824b 2402 $cc = api::add_competency_to_course($course->id, $c->get_id());
d4c0a2f6
SG
2403
2404 // Check record was created with default rule value Evidence.
2405 $this->assertEquals(1, \tool_lp\course_competency::count_records());
d660824b
FM
2406 $recordscc = api::list_course_competencies($course->id);
2407 $this->assertEquals(\tool_lp\course_competency::OUTCOME_EVIDENCE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
2408
2409 // Check ruleoutcome value is updated to None.
d660824b
FM
2410 $this->assertTrue(api::set_course_competency_ruleoutcome($recordscc[0]['coursecompetency']->get_id(),
2411 \tool_lp\course_competency::OUTCOME_NONE));
2412 $recordscc = api::list_course_competencies($course->id);
2413 $this->assertEquals(\tool_lp\course_competency::OUTCOME_NONE, $recordscc[0]['coursecompetency']->get_ruleoutcome());
d4c0a2f6
SG
2414 }
2415
4de456cd
SG
2416 /**
2417 * Test validation on grade on user_competency.
2418 */
2419 public function test_validate_grade_in_user_competency() {
2420 global $DB;
2421
2422 $this->resetAfterTest(true);
2423 $this->setAdminUser();
2424 $dg = $this->getDataGenerator();
2425 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2426 $user = $dg->create_user();
2427
2428 $dg->create_scale(array("id" => "1", "scale" => "value1, value2"));
2429 $dg->create_scale(array("id" => "2", "scale" => "value3, value4, value5, value6"));
2430
2431 $scaleconfiguration1 = '[{"scaleid":"1"},{"name":"value1","id":1,"scaledefault":1,"proficient":0},' .
2432 '{"name":"value2","id":2,"scaledefault":0,"proficient":1}]';
2433 $scaleconfiguration2 = '[{"scaleid":"2"},{"name":"value3","id":1,"scaledefault":1,"proficient":0},'
2434 . '{"name":"value4","id":2,"scaledefault":0,"proficient":1},'
2435 . '{"name":"value5","id":3,"scaledefault":0,"proficient":0},'
2436 . '{"name":"value6","id":4,"scaledefault":0,"proficient":0}]';
2437
2438 // Create a framework with scale configuration1.
2439 $frm = array(
2440 'scaleid' => 1,
2441 'scaleconfiguration' => $scaleconfiguration1
2442 );
2443 $framework = $lpg->create_framework($frm);
2444 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2445
2446 // Create competency with its own scale configuration.
2447 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
2448 'scaleid' => 2,
2449 'scaleconfiguration' => $scaleconfiguration2
2450 ));
2451
2452 // Detecte invalid grade in competency using its framework competency scale.
2453 try {
2454 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
2455 'proficiency' => true, 'grade' => 3 ));
2456 $usercompetency->create();
2457 $this->fail('Invalid grade not detected in framework scale');
2458 } catch (\tool_lp\invalid_persistent_exception $e) {
2459 $this->assertTrue(true);
2460 }
2461
2462 // Detecte invalid grade in competency using its own scale.
2463 try {
2464 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
2465 'proficiency' => true, 'grade' => 5 ));
2466 $usercompetency->create();
2467 $this->fail('Invalid grade not detected in competency scale');
2468 } catch (\tool_lp\invalid_persistent_exception $e) {
2469 $this->assertTrue(true);
2470 }
2471
2472 // Accept valid grade in competency using its framework competency scale.
2473 try {
2474 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c1->get_id(),
2475 'proficiency' => true, 'grade' => 1 ));
2476 $usercompetency->create();
2477 $this->assertTrue(true);
2478 } catch (\tool_lp\invalid_persistent_exception $e) {
2479 $this->fail('Valide grade rejected in framework scale');
2480 }
2481
2482 // Accept valid grade in competency using its framework competency scale.
2483 try {
2484 $usercompetency = new user_competency(0, (object) array('userid' => $user->id, 'competencyid' => $c2->get_id(),
2485 'proficiency' => true, 'grade' => 4 ));
2486 $usercompetency->create();
2487 $this->assertTrue(true);
2488 } catch (\tool_lp\invalid_persistent_exception $e) {
4de456cd
SG
2489 $this->fail('Valide grade rejected in competency scale');
2490 }
2491 }
2492
964afa98
IT
2493 /**
2494 * Test when adding competency that belong to hidden framework to plan/template/course.
2495 */
2496 public function test_hidden_framework() {
2497 $this->resetAfterTest(true);
2498 $this->setAdminUser();
2499 $dg = $this->getDataGenerator();
2500 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2501 $user = $dg->create_user();
2502
2503 // Create a course.
2504 $cat1 = $dg->create_category();
2505 $course = $dg->create_course(array('category' => $cat1->id));
2506 // Create a template.
2507 $template = $lpg->create_template();
2508 // Create a plan.
2509 $plan = $lpg->create_plan(array('userid' => $user->id));
2510
2511 // Create a hidden framework.
2512 $frm = array(
2513 'visible' => false
2514 );
2515 $framework = $lpg->create_framework($frm);
2516 $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2517
2518 // Linking competency that belong to hidden framework to course.
2519 try {
2520 api::add_competency_to_course($course->id, $competency->get_id());
2521 $this->fail('A competency belonging to hidden framework can not be linked to course');
2522 } catch (coding_exception $e) {
2523 $this->assertTrue(true);
2524 }
2525
2526 // Adding competency that belong to hidden framework to template.
2527 try {
2528 api::add_competency_to_template($template->get_id(), $competency->get_id());
2529 $this->fail('A competency belonging to hidden framework can not be added to template');
2530 } catch (coding_exception $e) {
2531 $this->assertTrue(true);
2532 }
2533
2534 // Adding competency that belong to hidden framework to plan.
2535 try {
2536 api::add_competency_to_plan($plan->get_id(), $competency->get_id());
2537 $this->fail('A competency belonging to hidden framework can not be added to plan');
2538 } catch (coding_exception $e) {
2539 $this->assertTrue(true);
2540 }
2541 }
2542
2543 /**
2544 * Test when using hidden template in plan/cohort.
2545 */
2546 public function test_hidden_template() {
2547 $this->resetAfterTest(true);
2548 $this->setAdminUser();
2549 $dg = $this->getDataGenerator();
2550 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2551 $user = $dg->create_user();
2552
2553 // Create a cohort.
2554 $cohort = $dg->create_cohort();
2555 // Create a hidden template.
2556 $template = $lpg->create_template(array('visible' => false));
2557
2558 // Can not link hidden template to plan.
2559 try {
2560 api::create_plan_from_template($template->get_id(), $user->id);
2561 $this->fail('Can not link a hidden template to plan');
2562 } catch (coding_exception $e) {
2563 $this->assertTrue(true);
2564 }
2565
2566 // Can associate hidden template to cohort.
2567 $templatecohort = api::create_template_cohort($template->get_id(), $cohort->id);
2568 $this->assertInstanceOf('\tool_lp\template_cohort', $templatecohort);
2569 }
2570
d3275795
SG
2571 /**
2572 * Test that completed plan created form a template does not change when template is modified.
2573 */
2574 public function test_completed_plan_doesnot_change() {
2575 global $DB;
2576
2577 $this->resetAfterTest(true);
2578 $this->setAdminUser();
2579 $dg = $this->getDataGenerator();
2580 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2581 $user = $dg->create_user();
2582
2583 // Create a framework and assign competencies.
2584 $framework = $lpg->create_framework();
2585 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2586 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2587 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2588 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
2589
2590 // Create template and assign competencies.
2591 $tp = $lpg->create_template();
2592 $tpc1 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c1->get_id()));
2593 $tpc2 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c2->get_id()));
2594 $tpc3 = $lpg->create_template_competency(array('templateid' => $tp->get_id(), 'competencyid' => $c3->get_id()));
2595
2596 // Create a plan form template and change it status to complete.
2597 $plan = $lpg->create_plan(array('userid' => $user->id, 'templateid' => $tp->get_id()));
2598 api::complete_plan($plan);
2599
2600 // Check user competency plan created correctly.
2601 $this->assertEquals(3, \tool_lp\user_competency_plan::count_records());
2602 $ucp = \tool_lp\user_competency_plan::get_records();
2603 $this->assertEquals($ucp[0]->get_competencyid(), $c1->get_id());
2604 $this->assertEquals($ucp[1]->get_competencyid(), $c2->get_id());
2605 $this->assertEquals($ucp[2]->get_competencyid(), $c3->get_id());
2606
2607 // Add and remove a competency from the template.
2608 api::add_competency_to_template($tp->get_id(), $c4->get_id());
2609 api::remove_competency_from_template($tp->get_id(), $c1->get_id());
2610
2611 // Check that user competency plan did not change.
2612 $competencies = $plan->get_competencies();
2613 $this->assertEquals(3, count($competencies));
2614 $ucp1 = array($c1->get_id(), $c2->get_id(), $c3->get_id());
2615 $ucp2 = array();
2616 foreach ($competencies as $id => $cmp) {
2617 $ucp2[] = $id;
2618 }
2619 $this->assertEquals(0, count(array_diff($ucp1, $ucp2)));
2620 }
20c2fe3e
FM
2621
2622 protected function setup_framework_for_reset_rules_tests() {
2623 $this->resetAfterTest(true);
2624 $dg = $this->getDataGenerator();
2625 $lpg = $dg->get_plugin_generator('tool_lp');
2626
2627 $this->setAdminUser();
2628 $f1 = $lpg->create_framework();
2629 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2630 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2631 $c1a1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2632 $c1a1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a1->get_id()));
2633 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2634 $c1b1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2635 $c1b1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b1->get_id()));
2636 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2637 $c2a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2638
2639 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2640 $c1->set_ruletype('tool_lp\\competency_rule_all');
2641 $c1->update();
2642 $c1a->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2643 $c1a->set_ruletype('tool_lp\\competency_rule_all');
2644 $c1a->update();
2645 $c1a1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2646 $c1a1->set_ruletype('tool_lp\\competency_rule_all');
2647 $c1a1->update();
2648 $c1b->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2649 $c1b->set_ruletype('tool_lp\\competency_rule_all');
2650 $c1b->update();
2651 $c2->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2652 $c2->set_ruletype('tool_lp\\competency_rule_all');
2653 $c2->update();
2654
2655 return array(
2656 'f1' => $f1,
2657 'c1' => $c1,
2658 'c1a' => $c1a,
2659 'c1a1' => $c1a1,
2660 'c1a1a' => $c1a1a,
2661 'c1b' => $c1b,
2662 'c1b1' => $c1b1,
2663 'c1b1a' => $c1b1a,
2664 'c2' => $c2,
2665 'c2a' => $c2a,
2666 );
2667 }
2668
2669 public function test_moving_competency_reset_rules_updown() {
2670 extract($this->setup_framework_for_reset_rules_tests());
2671
2672 // Moving up and down doesn't change anything.
2673 api::move_down_competency($c1a->get_id());
2674 $c1->read();
2675 $c1a->read();
2676 $c1a1->read();
2677 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2678 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2679 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2680 api::move_up_competency($c1a->get_id());
2681 $c1->read();
2682 $c1a->read();
2683 $c1a1->read();
2684 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2685 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2686 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2687 }
2688
2689 public function test_moving_competency_reset_rules_parent() {
2690 extract($this->setup_framework_for_reset_rules_tests());
2691
2692 // Moving out of parent will reset the parent, and the destination.
2693 api::set_parent_competency($c1a->get_id(), $c1b->get_id());
2694 $c1->read();
2695 $c1a->read();
2696 $c1a1->read();
2697 $c1b->read();
2698 $c2->read();
2699 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2700 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2701 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2702 $this->assertEquals(competency::OUTCOME_NONE, $c1b->get_ruleoutcome());
2703 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2704 }
2705
2706 public function test_moving_competency_reset_rules_totoplevel() {
2707 extract($this->setup_framework_for_reset_rules_tests());
2708
2709 // Moving to top level only affects the initial parent.
2710 api::set_parent_competency($c1a1->get_id(), 0);
2711 $c1->read();
2712 $c1a->read();
2713 $c1a1->read();
2714 $c1b->read();
2715 $c2->read();
2716 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2717 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome());
2718 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2719 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2720 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2721 }
2722
2723 public function test_moving_competency_reset_rules_fromtoplevel() {
2724 extract($this->setup_framework_for_reset_rules_tests());
2725
2726 // Moving from top level only affects the destination parent.
2727 api::set_parent_competency($c2->get_id(), $c1a1->get_id());
2728 $c1->read();
2729 $c1a->read();
2730 $c1a1->read();
2731 $c1b->read();
2732 $c2->read();
2733 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1->get_ruleoutcome());
2734 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2735 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome());
2736 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2737 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2738 }
2739
2740 public function test_moving_competency_reset_rules_child() {
2741 extract($this->setup_framework_for_reset_rules_tests());
2742
2743 // Moving to a child of self resets self, parent and destination.
2744 api::set_parent_competency($c1a->get_id(), $c1a1->get_id());
2745 $c1->read();
2746 $c1a->read();
2747 $c1a1->read();
2748 $c1b->read();
2749 $c2->read();
2750 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2751 $this->assertEquals(competency::OUTCOME_NONE, $c1a->get_ruleoutcome());
2752 $this->assertEquals(competency::OUTCOME_NONE, $c1a1->get_ruleoutcome());
2753 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2754 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2755 }
2756
2757 public function test_create_competency_reset_rules() {
2758 extract($this->setup_framework_for_reset_rules_tests());
2759
2760 // Adding a new competency resets the rule of its parent.
2761 api::create_competency((object) array('shortname' => 'A', 'parentid' => $c1->get_id(), 'idnumber' => 'A',
2762 'competencyframeworkid' => $f1->get_id()));
2763 $c1->read();
2764 $c1a->read();
2765 $c1a1->read();
2766 $c1b->read();
2767 $c2->read();
2768 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2769 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a->get_ruleoutcome());
2770 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1a1->get_ruleoutcome());
2771 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2772 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2773 }
2774
2775 public function test_delete_competency_reset_rules() {
2776 extract($this->setup_framework_for_reset_rules_tests());
2777
2778 // Deleting a competency resets the rule of its parent.
2779 api::delete_competency($c1a->get_id());
2780 $c1->read();
2781 $c1b->read();
2782 $c2->read();
2783 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2784 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c1b->get_ruleoutcome());
2785 $this->assertEquals(competency::OUTCOME_EVIDENCE, $c2->get_ruleoutcome());
2786 }
8fabc738
SG
2787
2788 public function test_template_has_related_data() {
2789 $this->resetAfterTest(true);
2790 $this->setAdminUser();
2791
2792 $dg = $this->getDataGenerator();
2793 $user = $dg->create_user();
2794 $lpg = $dg->get_plugin_generator('tool_lp');
2795 $tpl1 = $lpg->create_template();
2796 $tpl2 = $lpg->create_template();
2797
2798 // Create plans for first template.
2799 $time = time();
2800 $plan1 = $lpg->create_plan(array('templateid' => $tpl1->get_id(), 'userid' => $user->id,
2801 'name' => 'Not good name', 'duedate' => $time + 3600, 'description' => 'Ahah', 'descriptionformat' => FORMAT_PLAIN));
2802
2803 $this->assertTrue(api::template_has_related_data($tpl1->get_id()));
2804 $this->assertFalse(api::template_has_related_data($tpl2->get_id()));
2805
2806 }
2807
2808 public function test_delete_template_delete_plans() {
2809 $this->resetAfterTest(true);
2810 $this->setAdminUser();
2811
2812 $dg = $this->getDataGenerator();
2813 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2814
2815 $u1 = $dg->create_user();
2816 $f = $lpg->create_framework();
2817 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2818 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2819
2820 $tpl = $lpg->create_template();
2821
2822 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(),
2823 'sortorder' => 1));
2824 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(),
2825 'sortorder' => 2));
2826
2827 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id));
2828
2829 // Check pre-test.
2830 $this->assertTrue(tool_lp\template::record_exists($tpl->get_id()));
2831 $this->assertEquals(2, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2832 $this->assertEquals(1, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2833
2834 $result = api::delete_template($tpl->get_id(), true);
2835 $this->assertTrue($result);
2836
2837 // Check that the template does not exist anymore.
2838 $this->assertFalse(tool_lp\template::record_exists($tpl->get_id()));
2839
2840 // Check that associated competencies are also deleted.
2841 $this->assertEquals(0, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2842
2843 // Check that associated plan are also deleted.
2844 $this->assertEquals(0, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2845 }
2846
2847 public function test_delete_template_unlink_plans() {
2848 $this->resetAfterTest(true);
2849 $this->setAdminUser();
2850
2851 $dg = $this->getDataGenerator();
2852 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
2853
2854 $u1 = $dg->create_user();
2855 $f = $lpg->create_framework();
2856 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2857 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
2858
2859 $tpl = $lpg->create_template();
2860
2861 $tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c1->get_id(),
2862 'sortorder' => 1));
2863 $tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $c2->get_id(),
2864 'sortorder' => 2));
2865
2866 $p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id));
2867
2868 // Check pre-test.
2869 $this->assertTrue(tool_lp\template::record_exists($tpl->get_id()));
2870 $this->assertEquals(2, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2871 $this->assertEquals(1, count(\tool_lp\plan::get_records(array('templateid' => $tpl->get_id()))));
2872
2873 $result = api::delete_template($tpl->get_id(), false);
2874 $this->assertTrue($result);
2875
2876 // Check that the template does not exist anymore.
2877 $this->assertFalse(tool_lp\template::record_exists($tpl->get_id()));
2878
2879 // Check that associated competencies are also deleted.
2880 $this->assertEquals(0, \tool_lp\template_competency::count_competencies($tpl->get_id()));
2881
2882 // Check that associated plan still exist but unlink from template.
2883 $plans = \tool_lp\plan::get_records(array('id' => $p1->get_id()));
2884 $this->assertEquals(1, count($plans));
2885 $this->assertEquals($plans[0]->get_origtemplateid(), $tpl->get_id());
2886 $this->assertNull($plans[0]->get_templateid());
2887 }
9a325eda
IT
2888
2889 public function test_delete_competency() {
2890 $this->resetAfterTest(true);
2891 $dg = $this->getDataGenerator();
2892 $lpg = $dg->get_plugin_generator('tool_lp');
2893 $this->setAdminUser();
2894
2895 $u1 = $dg->create_user();
2896
2897 $f1 = $lpg->create_framework();
2898 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2899 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2900 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2901 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2902 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2903 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2904
2905 // Set rules on parent competency.
2906 $c1->set_ruleoutcome(competency::OUTCOME_EVIDENCE);
2907 $c1->set_ruletype('tool_lp\\competency_rule_all');
2908 $c1->update();
2909
2910 // If we delete competeny, the related competencies relations and evidences should be deleted.
2911 // Create related competencies using one of c1a competency descendants.
2912 $rc = $lpg->create_related_competency(array(
2913 'competencyid' => $c2->get_id(),
2914 'relatedcompetencyid' => $c11b->get_id()
2915 ));
2916 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
2917
2918 // Creating a standard evidence with minimal information.
2919 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
2920 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id()));
2921 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
2922 $uc2->delete();
2923
2924 $this->assertTrue(api::delete_competency($c1a->get_id()));
2925 $this->assertFalse(competency::record_exists($c1a->get_id()));
2926
2927 // Check that on delete, we reset the rule on parent competency.
2928 $c1->read();
2929 $this->assertNull($c1->get_ruletype());
2930 $this->assertNull($c1->get_ruletype());
2931 $this->assertEquals(competency::OUTCOME_NONE, $c1->get_ruleoutcome());
2932
2933 // Check that descendants were also deleted.
2934 $this->assertFalse(competency::record_exists($c1b->get_id()));
2935 $this->assertFalse(competency::record_exists($c11b->get_id()));
2936 $this->assertFalse(competency::record_exists($c12b->get_id()));
2937
2938 // Check if evidence are also deleted.
2939 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
2940
2941 // Check if related conpetency relation is deleted.
2942 $this->assertEquals(0, count(api::list_related_competencies($c2->get_id())));
2943
2944 // Delete a simple competency.
2945 $this->assertTrue(api::delete_competency($c2->get_id()));
2946 $this->assertFalse(competency::record_exists($c2->get_id()));
2947 }
2948
2949 public function test_delete_competency_used_in_plan() {
2950 $this->resetAfterTest(true);
2951 $dg = $this->getDataGenerator();
2952 $lpg = $dg->get_plugin_generator('tool_lp');
2953 $this->setAdminUser();
2954
2955 $u1 = $dg->create_user();
2956
2957 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
2958
2959 $f1 = $lpg->create_framework();
2960 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2961 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2962 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2963 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2964 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2965 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2966
2967 // Add competency to plan.
2968 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id()));
2969 // We can not delete a competency , if competency or competency children is associated to plan.
2970 $this->assertFalse(api::delete_competency($c1a->get_id()));
2971
2972 // We can delete the competency if we remove the competency from the plan.
2973 $pc->delete();
2974
2975 $this->assertTrue(api::delete_competency($c1a->get_id()));
2976 $this->assertFalse(competency::record_exists($c1a->get_id()));
2977 $this->assertFalse(competency::record_exists($c1b->get_id()));
2978 $this->assertFalse(competency::record_exists($c11b->get_id()));
2979 $this->assertFalse(competency::record_exists($c12b->get_id()));
2980 }
2981
2982 public function test_delete_competency_used_in_usercompetency() {
2983 $this->resetAfterTest(true);
2984 $dg = $this->getDataGenerator();
2985 $lpg = $dg->get_plugin_generator('tool_lp');
2986 $this->setAdminUser();
2987
2988 $u1 = $dg->create_user();
2989
2990 $f1 = $lpg->create_framework();
2991 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2992 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
2993 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
2994 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
2995 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2996 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
2997
2998 // Create user competency.
2999 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3000
3001 // We can not delete a competency , if competency or competency children exist in user competency.
3002 $this->assertFalse(api::delete_competency($c1a->get_id()));
3003
3004 // We can delete the competency if we remove the competency from user competency.
3005 $uc1->delete();
3006
3007 $this->assertTrue(api::delete_competency($c1a->get_id()));
3008 $this->assertFalse(competency::record_exists($c1a->get_id()));
3009 $this->assertFalse(competency::record_exists($c1b->get_id()));
3010 $this->assertFalse(competency::record_exists($c11b->get_id()));
3011 $this->assertFalse(competency::record_exists($c12b->get_id()));
3012 }
3013
3014 public function test_delete_competency_used_in_usercompetencyplan() {
3015 $this->resetAfterTest(true);
3016 $dg = $this->getDataGenerator();
3017 $lpg = $dg->get_plugin_generator('tool_lp');
3018 $this->setAdminUser();
3019
3020 $u1 = $dg->create_user();
3021
3022 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3023
3024 $f1 = $lpg->create_framework();
3025 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3026 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3027 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3028 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3029 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3030 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3031
3032 // Create user competency plan.
3033 $uc2 = $lpg->create_user_competency_plan(array(
3034 'userid' => $u1->id,
3035 'competencyid' => $c11b->get_id(),
3036 'planid' => $plan->get_id()
3037 ));
3038
3039 // We can not delete a competency , if competency or competency children exist in user competency plan.
3040 $this->assertFalse(api::delete_competency($c1a->get_id()));
3041
3042 // We can delete the competency if we remove the competency from user competency plan.
3043 $uc2->delete();
3044
3045 $this->assertTrue(api::delete_competency($c1a->get_id()));
3046 $this->assertFalse(competency::record_exists($c1a->get_id()));
3047 $this->assertFalse(competency::record_exists($c1b->get_id()));
3048 $this->assertFalse(competency::record_exists($c11b->get_id()));
3049 $this->assertFalse(competency::record_exists($c12b->get_id()));
3050 }
3051
3052 public function test_delete_competency_used_in_template() {
3053 $this->resetAfterTest(true);
3054 $dg = $this->getDataGenerator();
3055 $lpg = $dg->get_plugin_generator('tool_lp');
3056 $this->setAdminUser();
3057
3058 $template = $lpg->create_template();
3059
3060 $f1 = $lpg->create_framework();
3061 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3062 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3063 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3064 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3065 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3066 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3067
3068 // Add competency to a template.
3069 $tc = $lpg->create_template_competency(array(
3070 'templateid' => $template->get_id(),
3071 'competencyid' => $c11b->get_id()
3072 ));
3073 // We can not delete a competency , if competency or competency children is linked to template.
3074 $this->assertFalse(api::delete_competency($c1a->get_id()));
3075
3076 // We can delete the competency if we remove the competency from template.
3077 $tc->delete();
3078
3079 $this->assertTrue(api::delete_competency($c1a->get_id()));
3080 $this->assertFalse(competency::record_exists($c1a->get_id()));
3081 $this->assertFalse(competency::record_exists($c1b->get_id()));
3082 $this->assertFalse(competency::record_exists($c11b->get_id()));
3083 $this->assertFalse(competency::record_exists($c12b->get_id()));
3084 }
3085
3086 public function test_delete_competency_used_in_course() {
3087 $this->resetAfterTest(true);
3088 $dg = $this->getDataGenerator();
3089 $lpg = $dg->get_plugin_generator('tool_lp');
3090 $this->setAdminUser();
3091
3092 $cat1 = $dg->create_category();
3093
3094 $course = $dg->create_course(array('category' => $cat1->id));
3095
3096 $f1 = $lpg->create_framework();
3097 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3098 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3099 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3100 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3101 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3102 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3103
3104 // Add competency to course.
3105 $cc = $lpg->create_course_competency(array(
3106 'courseid' => $course->id,
3107 'competencyid' => $c11b->get_id()
3108 ));
3109
3110 // We can not delete a competency if the competency or competencies children is linked to a course.
3111 $this->assertFalse(api::delete_competency($c1a->get_id()));
3112
3113 // We can delete the competency if we remove the competency from course.
3114 $cc->delete();
3115
3116 $this->assertTrue(api::delete_competency($c1a->get_id()));
3117 $this->assertFalse(competency::record_exists($c1a->get_id()));
3118 $this->assertFalse(competency::record_exists($c1b->get_id()));
3119 $this->assertFalse(competency::record_exists($c11b->get_id()));
3120 $this->assertFalse(competency::record_exists($c12b->get_id()));
3121 }
90c7bdaf
IT
3122
3123 public function test_delete_framework() {
3124 $this->resetAfterTest(true);
3125 $dg = $this->getDataGenerator();
3126 $lpg = $dg->get_plugin_generator('tool_lp');
3127 $this->setAdminUser();
3128
3129 $u1 = $dg->create_user();
3130
3131 $f1 = $lpg->create_framework();
3132 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3133 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3134 $c2id = $c2->get_id();
3135 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3136 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3137 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3138 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3139
3140 // If we delete framework, the related competencies relations and evidences should be deleted.
3141 // Create related competencies using one of c1a competency descendants.
3142 $rc = $lpg->create_related_competency(array(
3143 'competencyid' => $c2->get_id(),
3144 'relatedcompetencyid' => $c11b->get_id()
3145 ));
3146 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3147
3148 // Creating a standard evidence with minimal information.
3149 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3150 $evidence = $lpg->create_evidence(array('usercompetencyid' => $uc2->get_id()));
3151 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
3152 $uc2->delete();
3153
3154 $this->assertTrue(api::delete_framework($f1->get_id()));
3155 $this->assertFalse(competency_framework::record_exists($f1->get_id()));
3156
3157 // Check that all competencies were also deleted.
3158 $this->assertFalse(competency::record_exists($c1->get_id()));
3159 $this->assertFalse(competency::record_exists($c2->get_id()));
3160 $this->assertFalse(competency::record_exists($c1a->get_id()));
3161 $this->assertFalse(competency::record_exists($c1b->get_id()));
3162 $this->assertFalse(competency::record_exists($c11b->get_id()));
3163 $this->assertFalse(competency::record_exists($c12b->get_id()));
3164
3165 // Check if evidence are also deleted.
3166 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3167
3168 // Check if related conpetency relation is deleted.
3169 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3170
3171 // Delete a simple framework.
3172 $f2 = $lpg->create_framework();
3173 $this->assertTrue(api::delete_framework($f2->get_id()));
3174 $this->assertFalse(competency_framework::record_exists($f2->get_id()));
3175 }
3176
3177 public function test_delete_framework_competency_used_in_plan() {
3178 $this->resetAfterTest(true);
3179 $dg = $this->getDataGenerator();
3180 $lpg = $dg->get_plugin_generator('tool_lp');
3181 $this->setAdminUser();
3182
3183 $u1 = $dg->create_user();
3184
3185 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3186
3187 $f1 = $lpg->create_framework();
3188 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3189 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3190 $c2id = $c2->get_id();
3191 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3192 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3193 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3194 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3195
3196 // Create related competencies.
3197 $rc = $lpg->create_related_competency(array(
3198 'competencyid' => $c2->get_id(),
3199 'relatedcompetencyid' => $c11b->get_id()
3200 ));
3201 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3202
3203 // Creating a standard evidence with minimal information.
3204 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3205 $usercompetencyid = $uc2->get_id();
3206 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3207 $this->assertEquals($uc2->get_id(), $evidence->get_usercompetencyid());
3208 $uc2->delete();
3209
3210 // Add competency to plan.
3211 $pc = $lpg->create_plan_competency(array('planid' => $plan->get_id(), 'competencyid' => $c11b->get_id()));
3212 // We can not delete a framework , if competency or competency children is associated to plan.
3213 $this->assertFalse(api::delete_framework($f1->get_id()));
3214 // Check that none of associated data are deleted.
3215 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3216 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3217
3218 // We can delete the competency if we remove the competency from the plan.
3219 $pc->delete();
3220
3221 $this->assertTrue(api::delete_framework($f1->get_id()));
3222 $this->assertFalse(competency::record_exists($c1->get_id()));
3223 $this->assertFalse(competency::record_exists($c2->get_id()));
3224 $this->assertFalse(competency::record_exists($c1a->get_id()));
3225 $this->assertFalse(competency::record_exists($c1b->get_id()));
3226 $this->assertFalse(competency::record_exists($c11b->get_id()));
3227 $this->assertFalse(competency::record_exists($c12b->get_id()));
3228 // Check if evidence are also deleted.
3229 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3230
3231 // Check if related conpetency relation is deleted.
3232 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3233 }
3234
3235 public function test_delete_framework_competency_used_in_usercompetency() {
3236 $this->resetAfterTest(true);
3237 $dg = $this->getDataGenerator();
3238 $lpg = $dg->get_plugin_generator('tool_lp');
3239 $this->setAdminUser();
3240
3241 $u1 = $dg->create_user();
3242
3243 $f1 = $lpg->create_framework();
3244 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3245 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3246 $c2id = $c2->get_id();
3247 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3248 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3249 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3250 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3251
3252 // Create related competencies.
3253 $rc = $lpg->create_related_competency(array(
3254 'competencyid' => $c2->get_id(),
3255 'relatedcompetencyid' => $c11b->get_id()
3256 ));
3257 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3258
3259 // Creating a standard evidence with minimal information.
3260 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3261 $usercompetencyid = $uc1->get_id();
3262 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3263 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3264 $uc1->delete();
3265
3266 // Create user competency.
3267 $uc2 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3268
3269 // We can not delete a framework , if competency or competency children exist in user competency.
3270 $this->assertFalse(api::delete_framework($f1->get_id()));
3271 // Check that none of associated data are deleted.
3272 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3273 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3274
3275 // We can delete the framework if we remove the competency from user competency.
3276 $uc2->delete();
3277
3278 $this->assertTrue(api::delete_framework($f1->get_id()));
3279 $this->assertFalse(competency::record_exists($c1->get_id()));
3280 $this->assertFalse(competency::record_exists($c2->get_id()));
3281 $this->assertFalse(competency::record_exists($c1a->get_id()));
3282 $this->assertFalse(competency::record_exists($c1b->get_id()));
3283 $this->assertFalse(competency::record_exists($c11b->get_id()));
3284 $this->assertFalse(competency::record_exists($c12b->get_id()));
3285 // Check if evidence are also deleted.
3286 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3287
3288 // Check if related conpetency relation is deleted.
3289 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3290 }
3291
3292 public function test_delete_framework_competency_used_in_usercompetencyplan() {
3293 $this->resetAfterTest(true);
3294 $dg = $this->getDataGenerator();
3295 $lpg = $dg->get_plugin_generator('tool_lp');
3296 $this->setAdminUser();
3297
3298 $u1 = $dg->create_user();
3299
3300 $plan = $lpg->create_plan((object) array('userid' => $u1->id));
3301
3302 $f1 = $lpg->create_framework();
3303 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3304 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3305 $c2id = $c2->get_id();
3306 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3307 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3308 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3309 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3310
3311 // Create related competencies.
3312 $rc = $lpg->create_related_competency(array(
3313 'competencyid' => $c2->get_id(),
3314 'relatedcompetencyid' => $c11b->get_id()
3315 ));
3316 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3317
3318 // Creating a standard evidence with minimal information.
3319 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3320 $usercompetencyid = $uc1->get_id();
3321 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3322 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3323 $uc1->delete();
3324
3325 // Create user competency plan.
3326 $uc2 = $lpg->create_user_competency_plan(array(
3327 'userid' => $u1->id,
3328 'competencyid' => $c11b->get_id(),
3329 'planid' => $plan->get_id()
3330 ));
3331
3332 // We can not delete a framework , if competency or competency children exist in user competency plan.
3333 $this->assertFalse(api::delete_framework($f1->get_id()));
3334 // Check that none of associated data are deleted.
3335 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3336 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3337
3338 // We can delete the framework if we remove the competency from user competency plan.
3339 $uc2->delete();
3340
3341 $this->assertTrue(api::delete_framework($f1->get_id()));
3342 $this->assertFalse(competency::record_exists($c1->get_id()));
3343 $this->assertFalse(competency::record_exists($c2->get_id()));
3344 $this->assertFalse(competency::record_exists($c1a->get_id()));
3345 $this->assertFalse(competency::record_exists($c1b->get_id()));
3346 $this->assertFalse(competency::record_exists($c11b->get_id()));
3347 $this->assertFalse(competency::record_exists($c12b->get_id()));
3348 // Check if evidence are also deleted.
3349 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3350
3351 // Check if related conpetency relation is deleted.
3352 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3353 }
3354
3355 public function test_delete_framework_competency_used_in_template() {
3356 $this->resetAfterTest(true);
3357 $dg = $this->getDataGenerator();
3358 $lpg = $dg->get_plugin_generator('tool_lp');
3359 $this->setAdminUser();
3360
3361 $u1 = $dg->create_user();
3362 $template = $lpg->create_template();
3363
3364 $f1 = $lpg->create_framework();
3365 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3366 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3367 $c2id = $c2->get_id();
3368 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3369 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3370 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3371 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3372
3373 // Create related competencies.
3374 $rc = $lpg->create_related_competency(array(
3375 'competencyid' => $c2->get_id(),
3376 'relatedcompetencyid' => $c11b->get_id()
3377 ));
3378 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3379
3380 // Creating a standard evidence with minimal information.
3381 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3382 $usercompetencyid = $uc1->get_id();
3383 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3384 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3385 $uc1->delete();
3386
3387 // Add competency to a template.
3388 $tc = $lpg->create_template_competency(array(
3389 'templateid' => $template->get_id(),
3390 'competencyid' => $c11b->get_id()
3391 ));
3392 // We can not delete a framework , if competency or competency children is linked to template.
3393 $this->assertFalse(api::delete_framework($f1->get_id()));
3394 // Check that none of associated data are deleted.
3395 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3396 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3397
3398 // We can delete the framework if we remove the competency from template.
3399 $tc->delete();
3400
3401 $this->assertTrue(api::delete_framework($f1->get_id()));
3402 $this->assertFalse(competency::record_exists($c1->get_id()));
3403 $this->assertFalse(competency::record_exists($c2->get_id()));
3404 $this->assertFalse(competency::record_exists($c1a->get_id()));
3405 $this->assertFalse(competency::record_exists($c1b->get_id()));
3406 $this->assertFalse(competency::record_exists($c11b->get_id()));
3407 $this->assertFalse(competency::record_exists($c12b->get_id()));
3408 // Check if evidence are also deleted.
3409 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3410
3411 // Check if related conpetency relation is deleted.
3412 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3413 }
3414
3415 public function test_delete_framework_competency_used_in_course() {
3416 $this->resetAfterTest(true);
3417 $dg = $this->getDataGenerator();
3418 $lpg = $dg->get_plugin_generator('tool_lp');
3419 $this->setAdminUser();
3420
3421 $cat1 = $dg->create_category();
3422 $u1 = $dg->create_user();
3423 $course = $dg->create_course(array('category' => $cat1->id));
3424
3425 $f1 = $lpg->create_framework();
3426 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3427 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
3428 $c2id = $c2->get_id();
3429 $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id()));
3430 $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id()));
3431 $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3432 $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id()));
3433
3434 // Create related competencies.
3435 $rc = $lpg->create_related_competency(array(
3436 'competencyid' => $c2->get_id(),
3437 'relatedcompetencyid' => $c11b->get_id()
3438 ));
3439 $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid());
3440
3441 // Creating a standard evidence with minimal information.
3442 $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id()));
3443 $usercompetencyid = $uc1->get_id();
3444 $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid));
3445 $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid());
3446 $uc1->delete();
3447
3448 // Add competency to course.
3449 $cc = $lpg->create_course_competency(array(
3450 'courseid' => $course->id,
3451 'competencyid' => $c11b->get_id()
3452 ));
3453
3454 // We can not delete a framework if the competency or competencies children is linked to a course.
3455 $this->assertFalse(api::delete_framework($f1->get_id()));
3456 // Check that none of associated data are deleted.
3457 $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid());
3458 $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid());
3459
3460 // We can delete the framework if we remove the competency from course.
3461 $cc->delete();
3462
3463 $this->assertTrue(api::delete_framework($f1->get_id()));
3464 $this->assertFalse(competency::record_exists($c1->get_id()));
3465 $this->assertFalse(competency::record_exists($c2->get_id()));
3466 $this->assertFalse(competency::record_exists($c1a->get_id()));
3467 $this->assertFalse(competency::record_exists($c1b->get_id()));
3468 $this->assertFalse(competency::record_exists($c11b->get_id()));
3469 $this->assertFalse(competency::record_exists($c12b->get_id()));
3470 // Check if evidence are also deleted.
3471 $this->assertEquals(0, tool_lp\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id())));
3472
3473 // Check if related conpetency relation is deleted.
3474 $this->assertEquals(0, count(\tool_lp\related_competency::get_multiple_relations(array($c2id))));
3475 }
f45d0b37
FM
3476
3477 public function test_grade_competency_in_course_permissions() {
3478 $this->resetAfterTest();
3479 $dg = $this->getDataGenerator();
3480
3481 $c1 = $dg->create_course();
3482 $c2 = $dg->create_course();
3483 $sysctx = context_system::instance();
3484 $c1ctx = context_course::instance($c1->id);
3485 $c2ctx = context_course::instance($c2->id);
3486
3487 $teacher1 = $dg->create_user();
3488 $student1 = $dg->create_user();
3489 $student2 = $dg->create_user();
3490 $notstudent1 = $dg->create_user();
3491
3492 $lpg = $dg->get_plugin_generator('tool_lp');
3493 $framework = $lpg->create_framework();
3494 $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
3495 $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
3496 $lpg->create_course_competency(array('courseid' => $c1->id, 'competencyid' => $comp1->get_id()));
3497
3498 $studentarch = get_archetype_roles('student');
3499 $studentrole = array_shift($studentarch);
3500
3501 $gradablerole = $dg->create_role();
3502 assign_capability('tool/lp:coursecompetencygradable', CAP_ALLOW, $gradablerole, $sysctx->id);
3503
3504 $notgradablerole = $dg->create_role();
3505 assign_capability('tool/lp:coursecompetencygradable', CAP_PROHIBIT, $notgradablerole, $sysctx->id);
3506
3507 $canviewucrole = $dg->create_role();
3508 assign_capability('tool/lp:usercompetencyview', CAP_ALLOW, $canviewucrole, $sysctx->id);
3509
3510 $cannotviewcomp = $dg->create_role();
3511 assign_capability('tool/lp:competencyread', CAP_PROHIBIT, $cannotviewcomp, $sysctx->id);
3512
3513 $canmanagecomp = $dg->create_role();
3514 assign_capability('tool/lp:competencymanage', CAP_ALLOW, $canmanagecomp, $sysctx->id);
3515
3516 $cangraderole = $dg->create_role();
3517 assign_capability('tool/lp:competencygrade', CAP_ALLOW, $cangraderole, $sysctx->id);
3518
3519 $cansuggestrole = $dg->create_role();
3520 assign_capability('tool/lp:competencysuggestgrade', CAP_ALLOW, $cansuggestrole, $sysctx->id);
3521
3522 // Enrol s1 and s2 as students in course 1.
3523 $dg->enrol_user($student1->id, $c1->id, $studentrole->id);
3524 $dg->enrol_user($student2->id, $c1->id, $studentrole->id);
3525
3526 // Mark the s2 as not being 'gradable'.
3527 $dg->role_assign($notgradablerole, $student2->id, $c1ctx->id);
3528
3529 // Mark the 'non a student' as 'gradable' throughout the site.
3530 $dg->role_assign($gradablerole, $notstudent1->id, $sysctx->id);
3531
3532 // From now we'll iterate over each permission.
3533 accesslib_clear_all_caches_for_unit_testing();
3534 $this->setUser($teacher1);
3535
3536 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View a user competency',
3537 $c1->id, $student1->id, $comp1->get_id());
3538
3539 // Give permission to view competencies.
3540 $dg->role_assign($canviewucrole, $teacher1->id, $c1ctx->id);
3541 accesslib_clear_all_caches_for_unit_testing();
3542 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'Set competency grade',
3543 $c1->id, $student1->id, $comp1->get_id());
3544 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'Suggest competency grade',
3545 $c1->id, $student1->id, $comp1->get_id(), 1, false);
3546
3547 // Give permission to suggest.
3548 $dg->role_assign($cansuggestrole, $teacher1->id, $c1ctx->id);
3549 accesslib_clear_all_caches_for_unit_testing();
3550 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'Set competency grade',
3551 $c1->id, $student1->id, $comp1->get_id());
3552 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id(), 1, false);
3553
3554 // Give permission to rate.
3555 $dg->role_assign($cangraderole, $teacher1->id, $c1ctx->id);
3556 accesslib_clear_all_caches_for_unit_testing();
3557 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id());
3558
3559 // Remove permssion to read competencies, this leads to error.
3560 $dg->role_assign($cannotviewcomp, $teacher1->id, $sysctx->id);
3561 accesslib_clear_all_caches_for_unit_testing();
3562 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View competency frameworks',
3563 $c1->id, $student1->id, $comp1->get_id());
3564 $this->assertExceptionWithGradeCompetencyInCourse('required_capability_exception', 'View competency frameworks',
3565 $c1->id, $student1->id, $comp1->get_id(), 1, false);
3566
3567 // Give permssion to manage course competencies, this leads to success.
3568 $dg->role_assign($canmanagecomp, $teacher1->id, $sysctx->id);
3569 accesslib_clear_all_caches_for_unit_testing();
3570 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id());
3571 $this->assertSuccessWithGradeCompetencyInCourse($c1->id, $student1->id, $comp1->get_id(), 1, false);
3572
3573 // Try to grade a user that is not gradable, lead to errors.
3574 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency may not be rated at this time.',
3575 $c1->id, $student2->id, $comp1->get_id());
3576
3577 // Try to grade a competency not in the course.
3578 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency does not belong to this course',
3579 $c1->id, $student1->id, $comp2->get_id());
3580
3581 // Try to grade a user that is not enrolled, even though they are 'gradable'.
3582 $this->assertExceptionWithGradeCompetencyInCourse('coding_exception', 'The competency may not be rated at this time.',
3583 $c1->id, $notstudent1->id, $comp1->get_id());
3584 }
3585
3586 protected function assertSuccessWithGradeCompetencyInCourse($courseid, $userid, $compid, $grade = 1, $override = true) {
3587 $beforecount = evidence::count_records();
3588 api::grade_competency_in_course($courseid, $userid, $compid, $grade, $override);
3589 $this->assertEquals($beforecount + 1, evidence::count_records());
3590 $uc = user_competency::get_record(array('userid' => $userid, 'competencyid' => $compid));
3591 $records = evidence::get_records(array(), 'id', 'DESC', 0, 1);
3592 $evidence = array_pop($records);
3593 $this->assertEquals($uc->get_id(), $evidence->get_usercompetencyid());
3594 }
3595
3596 protected function assertExceptionWithGradeCompetencyInCourse($exceptiontype, $exceptiontext, $courseid, $userid, $compid,
3597 $grade = 1, $override = true) {
3598
3599 $raised = false;
3600 try {
3601 api::grade_competency_in_course($courseid, $userid, $compid, $grade, $override);
3602 } catch (moodle_exception $e) {
3603 $raised = true;
3604 $this->assertInstanceOf($exceptiontype, $e);
3605 $this->assertRegExp('@' . $exceptiontext . '@', $e->getMessage());
3606 }
3607
3608 if (!$raised) {
3609 $this->fail('Grading should not be allowed.');
3610 }
3611 }
b200c8c8
SG
3612
3613 /**
3614 * Test list of evidences for plan completed and not completed.
3615 */
3616 public function test_list_evidence() {
3617 global $DB;
3618
3619 $this->resetAfterTest(true);
3620 $dg = $this->getDataGenerator();
3621 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
3622
3623 $currenttime = time();
3624 $syscontext = context_system::instance();
3625
3626 // Create users.
3627 $user = $dg->create_user();
3628<