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