MDL-51961 cbe: UX improvements to manage competencies
[moodle.git] / admin / tool / lp / tests / api_test.php
CommitLineData
f610a957
FM
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * API tests.
19 *
20 * @package tool_lp
21 * @copyright 2015 Frédéric Massart - FMCorz.net
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26global $CFG;
27
28use tool_lp\api;
29
30/**
31 * API tests.
32 *
33 * @package tool_lp
34 * @copyright 2015 Frédéric Massart - FMCorz.net
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class tool_lp_api_testcase extends advanced_testcase {
38
39 public function test_get_framework_related_contexts() {
40 $this->resetAfterTest(true);
41 $dg = $this->getDataGenerator();
42 $cat1 = $dg->create_category();
43 $cat2 = $dg->create_category(array('parent' => $cat1->id));
44 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 45 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
46
47 $cat1ctx = context_coursecat::instance($cat1->id);
48 $cat2ctx = context_coursecat::instance($cat2->id);
49 $cat3ctx = context_coursecat::instance($cat3->id);
50 $sysctx = context_system::instance();
51
52 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 53 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
f610a957
FM
54
55 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
f0da26a4 56 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
f610a957
FM
57
58 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
f0da26a4 59 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
f610a957
FM
60 }
61
62 public function test_get_framework_related_contexts_with_capabilities() {
63 $this->resetAfterTest(true);
64 $dg = $this->getDataGenerator();
65 $user = $dg->create_user();
66 $cat1 = $dg->create_category();
67 $cat2 = $dg->create_category(array('parent' => $cat1->id));
68 $cat3 = $dg->create_category(array('parent' => $cat2->id));
f0da26a4 69 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
f610a957
FM
70
71 $cat1ctx = context_coursecat::instance($cat1->id);
72 $cat2ctx = context_coursecat::instance($cat2->id);
73 $cat3ctx = context_coursecat::instance($cat3->id);
74 $sysctx = context_system::instance();
75
76 $roleallow = create_role('Allow', 'allow', 'Allow read');
77 assign_capability('tool/lp:competencyread', CAP_ALLOW, $roleallow, $sysctx->id);
78 role_assign($roleallow, $user->id, $sysctx->id);
79
80 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
81 assign_capability('tool/lp:competencyread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
82 role_assign($roleprevent, $user->id, $cat2ctx->id);
83
84 accesslib_clear_all_caches_for_unit_testing();
85 $this->setUser($user);
86 $this->assertFalse(has_capability('tool/lp:competencyread', $cat2ctx));
87
88 $requiredcap = array('tool/lp:competencyread');
89
90 $expected = array();
f0da26a4 91 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
f610a957
FM
92
93 $expected = array($cat1ctx->id => $cat1ctx);
f0da26a4 94 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
f610a957
FM
95
96 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
f0da26a4 97 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
f610a957 98 }
f0da26a4
FM
99
100 public function test_get_template_related_contexts() {
101 $this->resetAfterTest(true);
102 $dg = $this->getDataGenerator();
103 $cat1 = $dg->create_category();
104 $cat2 = $dg->create_category(array('parent' => $cat1->id));
105 $cat3 = $dg->create_category(array('parent' => $cat2->id));
106 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
107
108 $cat1ctx = context_coursecat::instance($cat1->id);
109 $cat2ctx = context_coursecat::instance($cat2->id);
110 $cat3ctx = context_coursecat::instance($cat3->id);
111 $sysctx = context_system::instance();
112
113 $expected = array($cat1ctx->id => $cat1ctx);
114 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'self'));
115
116 $expected = array($cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx, $cat3ctx->id => $cat3ctx);
117 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children'));
118
119 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx, $cat2ctx->id => $cat2ctx);
120 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents'));
121 }
122
123 public function test_get_template_related_contexts_with_capabilities() {
124 $this->resetAfterTest(true);
125 $dg = $this->getDataGenerator();
126 $user = $dg->create_user();
127 $cat1 = $dg->create_category();
128 $cat2 = $dg->create_category(array('parent' => $cat1->id));
129 $cat3 = $dg->create_category(array('parent' => $cat2->id));
130 $c1 = $dg->create_course(array('category' => $cat2->id)); // This context should not be returned.
131
132 $cat1ctx = context_coursecat::instance($cat1->id);
133 $cat2ctx = context_coursecat::instance($cat2->id);
134 $cat3ctx = context_coursecat::instance($cat3->id);
135 $sysctx = context_system::instance();
136
137 $roleallow = create_role('Allow', 'allow', 'Allow read');
138 assign_capability('tool/lp:templateread', CAP_ALLOW, $roleallow, $sysctx->id);
139 role_assign($roleallow, $user->id, $sysctx->id);
140
141 $roleprevent = create_role('Prevent', 'prevent', 'Prevent read');
142 assign_capability('tool/lp:templateread', CAP_PROHIBIT, $roleprevent, $sysctx->id);
143 role_assign($roleprevent, $user->id, $cat2ctx->id);
144
145 accesslib_clear_all_caches_for_unit_testing();
146 $this->setUser($user);
147 $this->assertFalse(has_capability('tool/lp:templateread', $cat2ctx));
148
149 $requiredcap = array('tool/lp:templateread');
150
151 $expected = array();
152 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'self', $requiredcap));
153
154 $expected = array($cat1ctx->id => $cat1ctx);
155 $this->assertEquals($expected, api::get_related_contexts($cat1ctx, 'children', $requiredcap));
156
157 $expected = array($sysctx->id => $sysctx, $cat1ctx->id => $cat1ctx);
158 $this->assertEquals($expected, api::get_related_contexts($cat2ctx, 'parents', $requiredcap));
159 }
160
ec324dc6
FM
161 /**
162 * Test updating a template.
163 */
164 public function test_update_template() {
165 $cat = $this->getDataGenerator()->create_category();
166 $this->resetAfterTest(true);
167 $this->setAdminUser();
168
169 $syscontext = context_system::instance();
170 $template = api::create_template((object) array('shortname' => 'testing', 'contextid' => $syscontext->id));
171
172 $this->assertEquals('testing', $template->get_shortname());
173 $this->assertEquals($syscontext->id, $template->get_contextid());
174
175 // Simple update.
176 api::update_template((object) array('id' => $template->get_id(), 'shortname' => 'success'));
177 $template = api::read_template($template->get_id());
178 $this->assertEquals('success', $template->get_shortname());
179
180 // Trying to change the context.
181 $this->setExpectedException('coding_exception');
182 api::update_template((object) array('id' => $template->get_id(), 'contextid' => context_coursecat::instance($cat->id)));
183 }
184
b3979696
IT
185 /**
186 * Test listing framework with order param.
187 */
188 public function test_list_frameworks() {
189 $this->resetAfterTest(true);
190 $this->setAdminUser();
bf61cd0c 191 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
b3979696
IT
192
193 // Create a list of frameworks.
bf61cd0c
FM
194 $framework1 = $lpg->create_framework(array(
195 'shortname' => 'shortname_a',
196 'idnumber' => 'idnumber_c',
197 'description' => 'description',
198 'descriptionformat' => FORMAT_HTML,
199 'visible' => true,
200 'contextid' => context_system::instance()->id
201 ));
202
203 $framework2 = $lpg->create_framework(array(
204 'shortname' => 'shortname_b',
205 'idnumber' => 'idnumber_a',
206 'description' => 'description',
207 'descriptionformat' => FORMAT_HTML,
208 'visible' => true,
209 'contextid' => context_system::instance()->id
210 ));
211
212 $framework3 = $lpg->create_framework(array(
213 'shortname' => 'shortname_c',
214 'idnumber' => 'idnumber_b',
215 'description' => 'description',
216 'descriptionformat' => FORMAT_HTML,
217 'visible' => true,
218 'contextid' => context_system::instance()->id
219 ));
b3979696
IT
220
221 // Get frameworks list order by shortname desc.
222 $result = api::list_frameworks('shortname', 'DESC', null, 3, context_system::instance());
223
224 $r1 = (object) $result[0];
225 $r2 = (object) $result[1];
226 $r3 = (object) $result[2];
227
228 $this->assertEquals($framework1->get_id(), $r3->get_id());
229 $this->assertEquals($framework2->get_id(), $r2->get_id());
230 $this->assertEquals($framework3->get_id(), $r1->get_id());
231
232 // Get frameworks list order by idnumber asc.
233 $result = api::list_frameworks('idnumber', 'ASC', null, 3, context_system::instance());
234
235 $r1 = (object) $result[0];
236 $r2 = (object) $result[1];
237 $r3 = (object) $result[2];
238
239 $this->assertEquals($framework1->get_id(), $r3->get_id());
240 $this->assertEquals($framework2->get_id(), $r1->get_id());
241 $this->assertEquals($framework3->get_id(), $r2->get_id());
242 }
243
c61db7bb
IT
244 /**
245 * Test duplicate a framework.
246 */
247 public function test_duplicate_framework() {
248 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
249 $this->resetAfterTest(true);
250 $this->setAdminUser();
251
252 $syscontext = context_system::instance();
253 $params = array(
254 'shortname' => 'shortname_a',
255 'idnumber' => 'idnumber_c',
256 'description' => 'description',
257 'descriptionformat' => FORMAT_HTML,
258 'visible' => true,
259 'contextid' => $syscontext->id
260 );
261 $framework = $lpg->create_framework($params);
262 $competency1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
263 $competency2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
264 $competency3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
265 $competency4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
266 $competencyidnumbers = array($competency1->get_idnumber(),
267 $competency2->get_idnumber(),
268 $competency3->get_idnumber(),
269 $competency4->get_idnumber()
270 );
271
272 api::add_related_competency($competency1->get_id(), $competency2->get_id());
273 api::add_related_competency($competency3->get_id(), $competency4->get_id());
274
275 $frameworkduplicated1 = api::duplicate_framework($framework->get_id());
276 $frameworkduplicated2 = api::duplicate_framework($framework->get_id());
277
278 $this->assertEquals($framework->get_idnumber().'_1', $frameworkduplicated1->get_idnumber());
279 $this->assertEquals($framework->get_idnumber().'_2', $frameworkduplicated2->get_idnumber());
280
281 $competenciesfr1 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated1->get_id()));
282 $competenciesfr2 = api::list_competencies(array('competencyframeworkid' => $frameworkduplicated2->get_id()));
283
284 $competencyidsfr1 = array();
285 $competencyidsfr2 = array();
286
287 foreach ($competenciesfr1 as $cmp) {
288 $competencyidsfr1[] = $cmp->get_idnumber();
289 }
290 foreach ($competenciesfr2 as $cmp) {
291 $competencyidsfr2[] = $cmp->get_idnumber();
292 }
293
294 $this->assertEmpty(array_diff($competencyidsfr1, $competencyidnumbers));
295 $this->assertEmpty(array_diff($competencyidsfr2, $competencyidnumbers));
296 $this->assertCount(4, $competenciesfr1);
297 $this->assertCount(4, $competenciesfr2);
298
299 // Test the related competencies.
300 reset($competenciesfr1);
301 $compduplicated1 = current($competenciesfr1);
302 $relatedcompetencies = $compduplicated1->get_related_competencies();
303 $comprelated = current($relatedcompetencies);
304 $this->assertEquals($comprelated->get_idnumber(), $competency2->get_idnumber());
305 }
306
58405003
IT
307 /**
308 * Test update plan.
309 */
310 public function test_update_plan() {
311 $this->resetAfterTest(true);
312 $dg = $this->getDataGenerator();
313 $usermanageowndraft = $dg->create_user();
314 $usermanageown = $dg->create_user();
315 $usermanagedraft = $dg->create_user();
316 $usermanage = $dg->create_user();
317
318 $syscontext = context_system::instance();
319
320 // Creating specific roles.
321 $manageowndraftrole = $dg->create_role(array(
322 'name' => 'User manage own draft',
323 'shortname' => 'manage-own-draft'
324 ));
325 $manageownrole = $dg->create_role(array(
326 'name' => 'User manage own',
327 'shortname' => 'manage-own'
328 ));
329 $managedraftrole = $dg->create_role(array(
330 'name' => 'User manage draft',
331 'shortname' => 'manage-draft'
332 ));
333 $managerole = $dg->create_role(array(
334 'name' => 'User manage',
335 'shortname' => 'manage'
336 ));
337
338 assign_capability('tool/lp:planmanageowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
339 assign_capability('tool/lp:planviewowndraft', CAP_ALLOW, $manageowndraftrole, $syscontext->id);
340
341 assign_capability('tool/lp:planmanageown', CAP_ALLOW, $manageownrole, $syscontext->id);
342 assign_capability('tool/lp:planviewown', CAP_ALLOW, $manageownrole, $syscontext->id);
343
344 assign_capability('tool/lp:planmanagedraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
345 assign_capability('tool/lp:planviewdraft', CAP_ALLOW, $managedraftrole, $syscontext->id);
346
347 assign_capability('tool/lp:planmanage', CAP_ALLOW, $managerole, $syscontext->id);
348 assign_capability('tool/lp:planview', CAP_ALLOW, $managerole, $syscontext->id);
349
350 $dg->role_assign($manageowndraftrole, $usermanageowndraft->id, $syscontext->id);
351 $dg->role_assign($manageownrole, $usermanageown->id, $syscontext->id);
352 $dg->role_assign($managedraftrole, $usermanagedraft->id, $syscontext->id);
353 $dg->role_assign($managerole, $usermanage->id, $syscontext->id);
354
355 // Create first learning plan with user create draft.
356 $this->setUser($usermanageowndraft);
357 $plan = array (
358 'name' => 'plan own draft',
359 'description' => 'plan own draft',
360 'userid' => $usermanageowndraft->id
361 );
362 $plan = api::create_plan((object)$plan);
363 $record = $plan->to_record();
364 $record->name = 'plan own draft modified';
365
366 // Check if user create draft can edit the plan name.
367 $plan = api::update_plan($record);
368 $this->assertInstanceOf('\tool_lp\plan', $plan);
369
370 // Thrown exception when manageowndraft user try to change the status.
371 $record->status = \tool_lp\plan::STATUS_ACTIVE;
372 try {
373 $plan = api::update_plan($record);
374 $this->fail('User with manage own draft capability cannot edit the plan status.');
375 } catch (required_capability_exception $e) {
376 $this->assertTrue(true);
377 }
378
379 // Test when user with manage own plan capability try to edit other user plan.
380 $record->status = \tool_lp\plan::STATUS_DRAFT;
381 $record->name = 'plan create draft modified 2';
382 $this->setUser($usermanageown);
383 try {
384 $plan = api::update_plan($record);
385 $this->fail('User with manage own plan capability can only edit his own plan.');
386 } catch (required_capability_exception $e) {
387 $this->assertTrue(true);
388 }
389
390 // User with manage plan capability cannot edit the other user plans with status draft.
391 $this->setUser($usermanage);
392 $record->status = \tool_lp\plan::STATUS_COMPLETE;
393 try {
394 $plan = api::update_plan($record);
395 $this->fail('User with manage plan capability cannot edit the other user plans with status draft');
396 } catch (required_capability_exception $e) {
397 $this->assertTrue(true);
398 }
399
400 // User with manage draft capability can edit other user's learning plan if the status is draft.
401 $this->setUser($usermanagedraft);
402 $record->status = \tool_lp\plan::STATUS_DRAFT;
403 $record->name = 'plan manage draft modified 3';
404 $plan = api::update_plan($record);
405 $this->assertInstanceOf('\tool_lp\plan', $plan);
406
407 // User with manage plan capability can create/edit learning plan if status is active/complete.
408 $this->setUser($usermanage);
409 $plan = array (
410 'name' => 'plan create',
411 'description' => 'plan create',
412 'userid' => $usermanage->id,
413 'status' => \tool_lp\plan::STATUS_ACTIVE
414 );
415 $plan = api::create_plan((object)$plan);
416 $record = $plan->to_record();
417 $record->name = 'plan create own modified';
418 $record->status = \tool_lp\plan::STATUS_COMPLETE;
419 $plan = api::update_plan($record);
420 $this->assertInstanceOf('\tool_lp\plan', $plan);
421
422 }
423
f610a957 424}