2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Plan persistent class tests.
20 * @package core_competency
21 * @copyright 2015 Frédéric Massart - FMCorz.net
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die();
28 use core_competency\api;
29 use core_competency\plan;
32 * Plan persistent testcase.
34 * @package core_competency
35 * @copyright 2015 Frédéric Massart - FMCorz.net
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 class core_competency_plan_testcase extends advanced_testcase {
40 public function test_can_manage_user() {
41 $this->resetAfterTest(true);
43 $manage = create_role('Manage', 'manage', 'Plan manager');
44 $manageown = create_role('Manageown', 'manageown', 'Own plan manager');
46 $u1 = $this->getDataGenerator()->create_user();
47 $u2 = $this->getDataGenerator()->create_user();
48 $u3 = $this->getDataGenerator()->create_user();
50 $syscontext = context_system::instance();
51 $u1context = context_user::instance($u1->id);
52 $u2context = context_user::instance($u2->id);
53 $u3context = context_user::instance($u3->id);
55 assign_capability('moodle/competency:planmanage', CAP_ALLOW, $manage, $syscontext->id);
56 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageown, $u2context->id);
58 role_assign($manage, $u1->id, $syscontext->id);
59 role_assign($manageown, $u2->id, $syscontext->id);
60 role_assign($manage, $u3->id, $u2context->id);
61 accesslib_clear_all_caches_for_unit_testing();
64 $this->assertTrue(plan::can_manage_user($u1->id));
65 $this->assertTrue(plan::can_manage_user($u2->id));
66 $this->assertTrue(plan::can_manage_user($u3->id));
69 $this->assertFalse(plan::can_manage_user($u1->id));
70 $this->assertTrue(plan::can_manage_user($u2->id));
71 $this->assertFalse(plan::can_manage_user($u3->id));
74 $this->assertFalse(plan::can_manage_user($u1->id));
75 $this->assertTrue(plan::can_manage_user($u2->id));
76 $this->assertFalse(plan::can_manage_user($u3->id));
79 public function test_can_manage_user_draft() {
80 $this->resetAfterTest(true);
82 $manage = create_role('Manage', 'manage', 'Plan manager');
83 $manageown = create_role('Manageown', 'manageown', 'Own plan manager');
84 $managedraft = create_role('Managedraft', 'managedraft', 'Draft plan manager');
85 $manageowndraft = create_role('Manageowndraft', 'manageowndraft', 'Own draft plan manager');
87 $u1 = $this->getDataGenerator()->create_user();
88 $u2 = $this->getDataGenerator()->create_user();
89 $u3 = $this->getDataGenerator()->create_user();
90 $u4 = $this->getDataGenerator()->create_user();
91 $u5 = $this->getDataGenerator()->create_user();
93 $syscontext = context_system::instance();
94 $u1context = context_user::instance($u1->id);
95 $u2context = context_user::instance($u2->id);
96 $u3context = context_user::instance($u3->id);
97 $u4context = context_user::instance($u4->id);
98 $u5context = context_user::instance($u5->id);
100 assign_capability('moodle/competency:planmanage', CAP_ALLOW, $manage, $syscontext->id);
101 assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $manageown, $syscontext->id);
102 assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $managedraft, $syscontext->id);
103 assign_capability('moodle/competency:planmanageowndraft', CAP_ALLOW, $manageowndraft, $syscontext->id);
105 role_assign($manage, $u1->id, $syscontext->id);
106 role_assign($manageown, $u2->id, $syscontext->id);
107 role_assign($managedraft, $u3->id, $syscontext->id);
108 role_assign($managedraft, $u4->id, $u2context->id);
109 role_assign($manageowndraft, $u5->id, $syscontext->id);
110 accesslib_clear_all_caches_for_unit_testing();
113 $this->assertFalse(plan::can_manage_user_draft($u1->id));
114 $this->assertFalse(plan::can_manage_user_draft($u2->id));
115 $this->assertFalse(plan::can_manage_user_draft($u3->id));
116 $this->assertFalse(plan::can_manage_user_draft($u4->id));
117 $this->assertFalse(plan::can_manage_user_draft($u5->id));
120 $this->assertFalse(plan::can_manage_user_draft($u1->id));
121 $this->assertFalse(plan::can_manage_user_draft($u2->id));
122 $this->assertFalse(plan::can_manage_user_draft($u3->id));
123 $this->assertFalse(plan::can_manage_user_draft($u4->id));
124 $this->assertFalse(plan::can_manage_user_draft($u5->id));
127 $this->assertTrue(plan::can_manage_user_draft($u1->id));
128 $this->assertTrue(plan::can_manage_user_draft($u2->id));
129 $this->assertTrue(plan::can_manage_user_draft($u3->id));
130 $this->assertTrue(plan::can_manage_user_draft($u4->id));
131 $this->assertTrue(plan::can_manage_user_draft($u5->id));
134 $this->assertFalse(plan::can_manage_user_draft($u1->id));
135 $this->assertTrue(plan::can_manage_user_draft($u2->id));
136 $this->assertFalse(plan::can_manage_user_draft($u3->id));
137 $this->assertFalse(plan::can_manage_user_draft($u4->id));
138 $this->assertFalse(plan::can_manage_user_draft($u5->id));
141 $this->assertFalse(plan::can_manage_user_draft($u1->id));
142 $this->assertFalse(plan::can_manage_user_draft($u2->id));
143 $this->assertFalse(plan::can_manage_user_draft($u3->id));
144 $this->assertFalse(plan::can_manage_user_draft($u4->id));
145 $this->assertTrue(plan::can_manage_user_draft($u5->id));
148 public function test_can_read_user() {
149 $this->resetAfterTest(true);
151 $read = create_role('Read', 'read', 'Plan reader');
152 $readown = create_role('Readown', 'readown', 'Own plan reader');
154 $u1 = $this->getDataGenerator()->create_user();
155 $u2 = $this->getDataGenerator()->create_user();
156 $u3 = $this->getDataGenerator()->create_user();
158 $syscontext = context_system::instance();
159 $u1context = context_user::instance($u1->id);
160 $u2context = context_user::instance($u2->id);
161 $u3context = context_user::instance($u3->id);
163 assign_capability('moodle/competency:planview', CAP_ALLOW, $read, $syscontext->id);
164 assign_capability('moodle/competency:planviewown', CAP_ALLOW, $readown, $u2context->id);
166 role_assign($read, $u1->id, $syscontext->id);
167 role_assign($readown, $u2->id, $syscontext->id);
168 role_assign($read, $u3->id, $u2context->id);
169 accesslib_clear_all_caches_for_unit_testing();
172 $this->assertTrue(plan::can_read_user($u1->id));
173 $this->assertTrue(plan::can_read_user($u2->id));
174 $this->assertTrue(plan::can_read_user($u3->id));
177 $this->assertFalse(plan::can_read_user($u1->id));
178 $this->assertTrue(plan::can_read_user($u2->id));
179 $this->assertFalse(plan::can_read_user($u3->id));
182 $this->assertFalse(plan::can_read_user($u1->id));
183 $this->assertTrue(plan::can_read_user($u2->id));
184 $this->assertTrue(plan::can_read_user($u3->id)); // Due to the default capability.
187 public function test_can_read_user_draft() {
188 $this->resetAfterTest(true);
190 $read = create_role('Read', 'read', 'Plan readr');
191 $readown = create_role('Readown', 'readown', 'Own plan readr');
192 $readdraft = create_role('Readdraft', 'readdraft', 'Draft plan readr');
193 $readowndraft = create_role('Readowndraft', 'readowndraft', 'Own draft plan readr');
195 $u1 = $this->getDataGenerator()->create_user();
196 $u2 = $this->getDataGenerator()->create_user();
197 $u3 = $this->getDataGenerator()->create_user();
198 $u4 = $this->getDataGenerator()->create_user();
199 $u5 = $this->getDataGenerator()->create_user();
201 $syscontext = context_system::instance();
202 $u1context = context_user::instance($u1->id);
203 $u2context = context_user::instance($u2->id);
204 $u3context = context_user::instance($u3->id);
205 $u4context = context_user::instance($u4->id);
206 $u5context = context_user::instance($u5->id);
208 assign_capability('moodle/competency:planview', CAP_ALLOW, $read, $syscontext->id);
209 assign_capability('moodle/competency:planviewown', CAP_ALLOW, $readown, $syscontext->id);
210 assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $readdraft, $syscontext->id);
211 assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $readowndraft, $syscontext->id);
212 assign_capability('moodle/competency:planviewown', CAP_PROHIBIT, $readowndraft, $syscontext->id);
214 role_assign($read, $u1->id, $syscontext->id);
215 role_assign($readown, $u2->id, $syscontext->id);
216 role_assign($readdraft, $u3->id, $syscontext->id);
217 role_assign($readdraft, $u4->id, $u2context->id);
218 role_assign($readowndraft, $u5->id, $syscontext->id);
219 accesslib_clear_all_caches_for_unit_testing();
222 $this->assertFalse(plan::can_read_user_draft($u1->id));
223 $this->assertFalse(plan::can_read_user_draft($u2->id));
224 $this->assertFalse(plan::can_read_user_draft($u3->id));
225 $this->assertFalse(plan::can_read_user_draft($u4->id));
226 $this->assertFalse(plan::can_read_user_draft($u5->id));
229 $this->assertFalse(plan::can_read_user_draft($u1->id));
230 $this->assertFalse(plan::can_read_user_draft($u2->id));
231 $this->assertFalse(plan::can_read_user_draft($u3->id));
232 $this->assertFalse(plan::can_read_user_draft($u4->id));
233 $this->assertFalse(plan::can_read_user_draft($u5->id));
236 $this->assertTrue(plan::can_read_user_draft($u1->id));
237 $this->assertTrue(plan::can_read_user_draft($u2->id));
238 $this->assertTrue(plan::can_read_user_draft($u3->id));
239 $this->assertTrue(plan::can_read_user_draft($u4->id));
240 $this->assertTrue(plan::can_read_user_draft($u5->id));
243 $this->assertFalse(plan::can_read_user_draft($u1->id));
244 $this->assertTrue(plan::can_read_user_draft($u2->id));
245 $this->assertFalse(plan::can_read_user_draft($u3->id));
246 $this->assertFalse(plan::can_read_user_draft($u4->id));
247 $this->assertFalse(plan::can_read_user_draft($u5->id));
250 $this->assertFalse(plan::can_read_user_draft($u1->id));
251 $this->assertFalse(plan::can_read_user_draft($u2->id));
252 $this->assertFalse(plan::can_read_user_draft($u3->id));
253 $this->assertFalse(plan::can_read_user_draft($u4->id));
254 $this->assertTrue(plan::can_read_user_draft($u5->id));
257 public function test_validate_duedate() {
259 $this->resetAfterTest(true);
260 $this->setAdminUser();
261 $dg = $this->getDataGenerator();
262 $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency');
263 $user = $dg->create_user();
265 $record = array('userid' => $user->id,
266 'status' => plan::STATUS_DRAFT,
267 'duedate' => time() - 8000);
269 // Ignore duedate validation on create/update draft plan.
270 $plan = $lpg->create_plan($record);
271 $this->assertInstanceOf('core_competency\plan', $plan);
273 // Passing from draft to active.
274 $plan->set_status(plan::STATUS_ACTIVE);
276 // Draft to active with duedate in the past.
278 'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
280 $this->assertEquals($expected, $plan->validate());
282 // Draft to active: past date => past date(fail).
283 $plan->set_duedate(time() - 100);
285 'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
287 $this->assertEquals($expected, $plan->validate());
289 // Draft to active: past date => too soon (fail).
290 $plan->set_duedate(time() + 100);
292 'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
294 $this->assertEquals($expected, $plan->validate());
296 // Draft to active: past date => future date (pass).
297 $plan->set_duedate(time() + plan::DUEDATE_THRESHOLD + 10);
298 $this->assertEquals(true, $plan->validate());
300 // Draft to active: past date => unset date (pass).
301 $plan->set_duedate(0);
302 $this->assertEquals(true, $plan->validate());
304 // Updating active plan.
307 // Active to active: past => same past (pass).
308 $record = $plan->to_record();
309 $record->duedate = 1;
310 $DB->update_record(plan::TABLE, $record);
312 $plan->set_description(uniqid()); // Force revalidation.
313 $this->assertTrue($plan->is_valid());
315 // Active to active: past => unset (pass).
316 $plan->set_duedate(0);
317 $this->assertTrue($plan->is_valid());
320 // Active to active: unset => unset (pass).
321 $plan->set_description(uniqid()); // Force revalidation.
322 $this->assertTrue($plan->is_valid());
324 // Active to active: unset date => past date(fail).
325 $plan->set_duedate(time() - 100);
327 'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
329 $this->assertEquals($expected, $plan->validate());
331 // Active to active: unset date => too soon (fail).
332 $plan->set_duedate(time() + 100);
334 'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
336 $this->assertEquals($expected, $plan->validate());
338 // Active to active: unset date => future date (pass).
339 $plan->set_duedate(time() + plan::DUEDATE_THRESHOLD + 10);
340 $this->assertEquals(true, $plan->validate());
342 // Updating active plan with future date.
345 // Active to active: future => same future (pass).
346 $plan->set_description(uniqid()); // Force revalidation.
347 $this->assertTrue($plan->is_valid());
349 // Active to active: future date => unset date (pass).
350 $plan->set_duedate(0);
351 $this->assertEquals(true, $plan->validate());
353 // Active to active: future date => past date(fail).
354 $plan->set_duedate(time() - 100);
356 'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
358 $this->assertEquals($expected, $plan->validate());
360 // Active to active: future date => too soon (fail).
361 $plan->set_duedate(time() + 100);
363 'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
365 $this->assertEquals($expected, $plan->validate());
367 // Active to active: future date => future date (pass).
368 $plan->set_duedate(time() + plan::DUEDATE_THRESHOLD + 10);
369 $this->assertEquals(true, $plan->validate());
371 // Completing plan: with due date in the past.
372 $record = $plan->to_record();
373 $record->status = plan::STATUS_ACTIVE;
374 $record->duedate = time() - 200;
375 $DB->update_record(plan::TABLE, $record);
377 $success = core_competency\api::complete_plan($plan->get_id());
378 $this->assertTrue($success);
380 // Completing plan: with due date too soon (pass).
381 $record = $plan->to_record();
382 $record->status = plan::STATUS_ACTIVE;
383 $record->duedate = time() + 200;
384 $DB->update_record(plan::TABLE, $record);
386 $success = core_competency\api::complete_plan($plan->get_id());
387 $this->assertTrue($success);
389 // Completing plan: with due date in the future (pass).
390 $record = $plan->to_record();
391 $record->status = plan::STATUS_ACTIVE;
392 $record->duedate = time() + plan::DUEDATE_THRESHOLD + 10;
393 $DB->update_record(plan::TABLE, $record);
395 $success = core_competency\api::complete_plan($plan->get_id());
396 $this->assertTrue($success);
398 // Completing plan: with due date unset (pass).
399 $record = $plan->to_record();
400 $record->status = plan::STATUS_ACTIVE;
401 $record->duedate = 0;
402 $DB->update_record(plan::TABLE, $record);
404 $success = core_competency\api::complete_plan($plan->get_id());
405 $this->assertTrue($success);
407 // Reopening plan: with due date in the past => duedate unset.
408 $record = $plan->to_record();
409 $record->status = plan::STATUS_COMPLETE;
410 $record->duedate = time() - 200;
411 $DB->update_record(plan::TABLE, $record);
413 $success = core_competency\api::reopen_plan($plan->get_id());
414 $this->assertTrue($success);
416 $this->assertEquals(0, $plan->get_duedate());
418 // Reopening plan: with due date too soon => duedate unset.
419 $record = $plan->to_record();
420 $record->status = plan::STATUS_COMPLETE;
421 $record->duedate = time() + 100;
422 $DB->update_record(plan::TABLE, $record);
424 $success = core_competency\api::reopen_plan($plan->get_id());
425 $this->assertTrue($success);
427 $this->assertEquals(0, $plan->get_duedate());
429 // Reopening plan: with due date in the future => duedate unchanged.
430 $record = $plan->to_record();
431 $record->status = plan::STATUS_COMPLETE;
432 $record->duedate = time() + plan::DUEDATE_THRESHOLD + 10;
433 $DB->update_record(plan::TABLE, $record);
435 $success = core_competency\api::reopen_plan($plan->get_id());
436 $this->assertTrue($success);
439 // Check that the due date has not changed, but allow for PHP Unit latency.
440 $this->assertTrue($plan->get_duedate() >= time() + plan::DUEDATE_THRESHOLD + 10);
441 $this->assertTrue($plan->get_duedate() <= time() + plan::DUEDATE_THRESHOLD + 15);
444 public function test_get_by_user_and_competency() {
445 $this->resetAfterTest();
446 $this->setAdminUser();
448 $dg = $this->getDataGenerator();
449 $lpg = $dg->get_plugin_generator('core_competency');
451 $u1 = $dg->create_user();
452 $u2 = $dg->create_user();
453 $u3 = $dg->create_user();
454 $u4 = $dg->create_user();
456 $f1 = $lpg->create_framework();
457 $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
458 $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id()));
460 $tpl1 = $lpg->create_template();
461 $lpg->create_template_competency(array('competencyid' => $c1->get_id(), 'templateid' => $tpl1->get_id()));
463 $p1 = $lpg->create_plan(array('userid' => $u1->id));
464 $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c1->get_id()));
465 $p2 = $lpg->create_plan(array('userid' => $u2->id));
466 $lpg->create_plan_competency(array('planid' => $p2->get_id(), 'competencyid' => $c1->get_id()));
467 $p3 = $lpg->create_plan(array('userid' => $u3->id, 'templateid' => $tpl1->get_id()));
468 $p4 = $lpg->create_plan(array('userid' => $u4->id, 'templateid' => $tpl1->get_id()));
469 api::complete_plan($p2);
470 api::complete_plan($p4);
472 // Finding a plan, not completed.
473 $plans = plan::get_by_user_and_competency($u1->id, $c1->get_id());
474 $this->assertCount(1, $plans);
475 $plan = array_shift($plans);
476 $this->assertEquals($p1->get_id(), $plan->get_id());
477 $this->assertNotEquals(plan::STATUS_COMPLETE, $plan->get_status());
479 // Finding a completed plan.
480 $plans = plan::get_by_user_and_competency($u2->id, $c1->get_id());
481 $this->assertCount(1, $plans);
482 $plan = array_shift($plans);
483 $this->assertEquals($p2->get_id(), $plan->get_id());
484 $this->assertEquals(plan::STATUS_COMPLETE, $plan->get_status());
486 // Finding a plan based on a template, not completed.
487 $plans = plan::get_by_user_and_competency($u3->id, $c1->get_id());
488 $this->assertCount(1, $plans);
489 $plan = array_shift($plans);
490 $this->assertEquals($p3->get_id(), $plan->get_id());
491 $this->assertTrue($plan->is_based_on_template());
492 $this->assertNotEquals(plan::STATUS_COMPLETE, $plan->get_status());
494 // Finding a plan based on a template.
495 $plans = plan::get_by_user_and_competency($u4->id, $c1->get_id());
496 $this->assertCount(1, $plans);
497 $plan = array_shift($plans);
498 $this->assertEquals($p4->get_id(), $plan->get_id());
499 $this->assertTrue($plan->is_based_on_template());
500 $this->assertEquals(plan::STATUS_COMPLETE, $plan->get_status());
502 // Finding more than one plan, no template.
503 $p5 = $lpg->create_plan(array('userid' => $u1->id));
504 $lpg->create_plan_competency(array('planid' => $p5->get_id(), 'competencyid' => $c1->get_id()));
505 $plans = plan::get_by_user_and_competency($u1->id, $c1->get_id());
506 $this->assertCount(2, $plans);
507 $plan = array_shift($plans);
508 $this->assertEquals($p1->get_id(), $plan->get_id());
509 $plan = array_shift($plans);
510 $this->assertEquals($p5->get_id(), $plan->get_id());
512 // Finding more than one plan, with template.
513 $p6 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id()));
514 $plans = plan::get_by_user_and_competency($u1->id, $c1->get_id());
515 $this->assertCount(3, $plans);
516 $plan = array_shift($plans);
517 $this->assertEquals($p1->get_id(), $plan->get_id());
518 $plan = array_shift($plans);
519 $this->assertEquals($p5->get_id(), $plan->get_id());
520 $plan = array_shift($plans);
521 $this->assertEquals($p6->get_id(), $plan->get_id());
524 $plans = plan::get_by_user_and_competency($u1->id, $c2->get_id());
525 $this->assertCount(0, $plans);