MDL-53700 competency: Migrating data generator to core
[moodle.git] / competency / tests / plan_test.php
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/>.
17 /**
18  * Plan persistent class tests.
19  *
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
23  */
25 defined('MOODLE_INTERNAL') || die();
26 global $CFG;
28 use core_competency\api;
29 use core_competency\plan;
31 /**
32  * Plan persistent testcase.
33  *
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
37  */
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();
63         $this->setUser($u1);
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));
68         $this->setUser($u2);
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));
73         $this->setUser($u3);
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));
77     }
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();
112         $this->setUser($u1);
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));
119         $this->setUser($u2);
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));
126         $this->setUser($u3);
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));
133         $this->setUser($u4);
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));
140         $this->setUser($u5);
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));
146     }
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();
171         $this->setUser($u1);
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));
176         $this->setUser($u2);
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));
181         $this->setUser($u3);
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.
185     }
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();
221         $this->setUser($u1);
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));
228         $this->setUser($u2);
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));
235         $this->setUser($u3);
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));
242         $this->setUser($u4);
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));
249         $this->setUser($u5);
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));
255     }
257     public function test_validate_duedate() {
258         global $DB;
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.
277         $expected = array(
278             'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
279         );
280         $this->assertEquals($expected, $plan->validate());
282         // Draft to active: past date => past date(fail).
283         $plan->set_duedate(time() - 100);
284         $expected = array(
285             'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
286         );
287         $this->assertEquals($expected, $plan->validate());
289         // Draft to active: past date => too soon (fail).
290         $plan->set_duedate(time() + 100);
291         $expected = array(
292             'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
293         );
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.
305         $plan->update();
307         // Active to active: past => same past (pass).
308         $record = $plan->to_record();
309         $record->duedate = 1;
310         $DB->update_record(plan::TABLE, $record);
311         $plan->read();
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());
318         $plan->update();
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);
326         $expected = array(
327             'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
328         );
329         $this->assertEquals($expected, $plan->validate());
331         // Active to active: unset date => too soon (fail).
332         $plan->set_duedate(time() + 100);
333         $expected = array(
334             'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
335         );
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.
343         $plan->update();
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);
355         $expected = array(
356             'duedate' => new lang_string('errorcannotsetduedateinthepast', 'tool_lp'),
357         );
358         $this->assertEquals($expected, $plan->validate());
360         // Active to active: future date => too soon (fail).
361         $plan->set_duedate(time() + 100);
362         $expected = array(
363             'duedate' => new lang_string('errorcannotsetduedatetoosoon', 'tool_lp'),
364         );
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);
415         $plan->read();
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);
426         $plan->read();
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);
437         $plan->read();
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);
442     }
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());
523         // Finding no plans.
524         $plans = plan::get_by_user_and_competency($u1->id, $c2->get_id());
525         $this->assertCount(0, $plans);
526     }