MDL-51029 tool_lp: Implement competency rules
[moodle.git] / admin / tool / lp / tests / competency_rule_test.php
CommitLineData
1896274f
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 * Competency rule 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();
26
27global $CFG;
28require_once($CFG->dirroot . '/webservice/tests/helpers.php');
29
30use tool_lp\user_competency;
31use tool_lp\competency;
32use tool_lp\competency_rule_all;
33use tool_lp\competency_rule_points;
34
35/**
36 * Competency rule testcase.
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_competency_rule_testcase extends externallib_advanced_testcase {
43
44 public function test_rule_all_matching() {
45 $this->resetAfterTest(true);
46
47 $this->setAdminUser();
48 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
49 $u1 = $this->getDataGenerator()->create_user();
50
51 // Set up the framework and competencies.
52 $framework = $lpg->create_framework();
53 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(),
54 'ruletype' => 'tool_lp\competency_rule_all'));
55 $c11 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id(),
56 'ruletype' => 'tool_lp\competency_rule_all'));
57 $c111 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c11->get_id(),
58 'ruletype' => 'tool_lp\competency_rule_all'));
59 $c112 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c11->get_id(),
60 'ruletype' => 'tool_lp\competency_rule_all'));
61 $c12 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id(),
62 'ruletype' => 'tool_lp\competency_rule_all'));
63 $c13 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id(),
64 'ruletype' => 'tool_lp\competency_rule_all'));
65 $c131 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c13->get_id(),
66 'ruletype' => 'tool_lp\competency_rule_all'));
67
68 // Create some user competency records.
69 $uc1 = $lpg->create_user_competency(array('competencyid' => $c1->get_id(), 'userid' => $u1->id));
70 $uc11 = $lpg->create_user_competency(array('competencyid' => $c11->get_id(), 'userid' => $u1->id, 'proficiency' => 1));
71 $uc111 = $lpg->create_user_competency(array('competencyid' => $c111->get_id(), 'userid' => $u1->id, 'proficiency' => 1));
72 $uc112 = $lpg->create_user_competency(array('competencyid' => $c112->get_id(), 'userid' => $u1->id, 'proficiency' => 1));
73 $uc12 = $lpg->create_user_competency(array('competencyid' => $c12->get_id(), 'userid' => $u1->id));
74 $uc13 = new user_competency(0, (object) array('userid' => $u1->id, 'competencyid' => $c13->get_id()));
75
76 // Not all children are met.
77 $cr = new competency_rule_all($c1);
78 $this->assertFalse($cr->matches($uc1));
79
80 // All children are met.
81 $cr = new competency_rule_all($c11);
82 $this->assertTrue($cr->matches($uc11));
83
84 // The competency doesn't have any children.
85 $cr = new competency_rule_all($c12);
86 $this->assertFalse($cr->matches($uc12));
87
88 // The competency doesn't have saved user competency records.
89 $cr = new competency_rule_all($c13);
90 $this->assertFalse($cr->matches($uc13));
91 }
92
93 public function test_rule_points_validation() {
94 $this->resetAfterTest(true);
95 $this->setAdminUser();
96
97 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
98 $framework = $lpg->create_framework();
99 $framework2 = $lpg->create_framework();
100 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
101 $c2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
102 $c3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
103 $c4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
104 $cx = $lpg->create_competency(array('competencyframeworkid' => $framework2->get_id()));
105
106 $c1->set_ruletype('tool_lp\competency_rule_points');
107 $rule = new competency_rule_points($c1);
108
109 // Invalid config.
110 $config = json_encode(array());
111 $this->assertFalse($rule->validate_config($config));
112
113 // Missing required points.
114 $config = json_encode(array(
115 'base' => array(),
116 'competencies' => array(
117 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
118 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
119 )
120 ));
121 $this->assertFalse($rule->validate_config($config));
122
123 // Invalid required points.
124 $config = json_encode(array(
125 'base' => array('points' => 'abc'),
126 'competencies' => array(
127 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
128 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
129 )
130 ));
131 $this->assertFalse($rule->validate_config($config));
132
133 // Less than 1 required points.
134 $config = json_encode(array(
135 'base' => array('points' => 0),
136 'competencies' => array(
137 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
138 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
139 )
140 ));
141 $this->assertFalse($rule->validate_config($config));
142
143 // Not enough required points.
144 $config = json_encode(array(
145 'base' => array('points' => 3),
146 'competencies' => array(
147 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
148 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
149 )
150 ));
151 $this->assertFalse($rule->validate_config($config));
152
153 // Duplicate competency.
154 $config = json_encode(array(
155 'base' => array('points' => 1),
156 'competencies' => array(
157 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
158 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
159 )
160 ));
161 $this->assertFalse($rule->validate_config($config));
162
163 // Competency includes itself.
164 $config = json_encode(array(
165 'base' => array('points' => 1),
166 'competencies' => array(
167 array('id' => $c1->get_id(), 'points' => 1, 'required' => 0),
168 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
169 )
170 ));
171 $this->assertFalse($rule->validate_config($config));
172
173 // Cannot use negative points.
174 $config = json_encode(array(
175 'base' => array('points' => 1),
176 'competencies' => array(
177 array('id' => $c2->get_id(), 'points' => -1, 'required' => 0),
178 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
179 )
180 ));
181 $this->assertFalse($rule->validate_config($config));
182
183 // Not competencies set.
184 $config = json_encode(array(
185 'base' => array('points' => 1),
186 'competencies' => array(
187 )
188 ));
189 $this->assertFalse($rule->validate_config($config));
190
191 // There is a competency that is not a child.
192 $config = json_encode(array(
193 'base' => array('points' => 1),
194 'competencies' => array(
195 array('id' => $c1->get_id(), 'points' => 1, 'required' => 0),
196 array('id' => $c2->get_id(), 'points' => 1, 'required' => 0),
197 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
198 )
199 ));
200 $this->assertFalse($rule->validate_config($config));
201
202 // There is a competency from another framework in there.
203 $config = json_encode(array(
204 'base' => array('points' => 1),
205 'competencies' => array(
206 array('id' => $cx->get_id(), 'points' => 1, 'required' => 0),
207 array('id' => $c3->get_id(), 'points' => 1, 'required' => 0),
208 )
209 ));
210 $this->assertFalse($rule->validate_config($config));
211
212 // A normal config.
213 $config = json_encode(array(
214 'base' => array('points' => 4),
215 'competencies' => array(
216 array('id' => $c2->get_id(), 'points' => 3, 'required' => 0),
217 array('id' => $c3->get_id(), 'points' => 2, 'required' => 1),
218 )
219 ));
220 $this->assertTrue($rule->validate_config($config));
221 }
222
223 public function test_rule_points_matching() {
224 $this->resetAfterTest(true);
225
226 $this->setAdminUser();
227 $lpg = $this->getDataGenerator()->get_plugin_generator('tool_lp');
228 $u1 = $this->getDataGenerator()->create_user();
229
230 // Set up the framework and competencies.
231 $framework = $lpg->create_framework();
232 $c1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
233 $c1->set_ruletype('tool_lp\competency_rule_points');
234 $comprule = new competency_rule_points($c1);
235 $c11 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
236 $c12 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
237 $c13 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
238 $c14 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id(), 'parentid' => $c1->get_id()));
239
240 // Create some user competency records.
241 $uc1 = $lpg->create_user_competency(array('competencyid' => $c1->get_id(), 'userid' => $u1->id));
242 $uc11 = $lpg->create_user_competency(array('competencyid' => $c11->get_id(), 'userid' => $u1->id, 'proficiency' => 1));
243 $uc12 = $lpg->create_user_competency(array('competencyid' => $c12->get_id(), 'userid' => $u1->id, 'proficiency' => 1));
244 $uc13 = $lpg->create_user_competency(array('competencyid' => $c13->get_id(), 'userid' => $u1->id));
245
246 // Enough points.
247 $rule = array(
248 'base' => array('points' => 8),
249 'competencies' => array(
250 array(
251 'id' => $c11->get_id(),
252 'points' => 4,
253 'required' => 0
254 ),
255 array(
256 'id' => $c12->get_id(),
257 'points' => 4,
258 'required' => 0
259 ),
260 )
261 );
262 $c1->set_ruleconfig(json_encode($rule));
263 $c1->update();
264 $this->assertTrue($comprule->matches($uc1));
265
266 // Not enough points.
267 $rule = array(
268 'base' => array('points' => 8),
269 'competencies' => array(
270 array(
271 'id' => $c11->get_id(),
272 'points' => 4,
273 'required' => 0
274 ),
275 array(
276 'id' => $c13->get_id(),
277 'points' => 4,
278 'required' => 0
279 ),
280 )
281 );
282 $c1->set_ruleconfig(json_encode($rule));
283 $c1->update();
284 $this->assertFalse($comprule->matches($uc1));
285
286 // One required that is not met but points were OK.
287 $rule = array(
288 'base' => array('points' => 8),
289 'competencies' => array(
290 array(
291 'id' => $c11->get_id(),
292 'points' => 4,
293 'required' => 0
294 ),
295 array(
296 'id' => $c12->get_id(),
297 'points' => 4,
298 'required' => 0
299 ),
300 array(
301 'id' => $c13->get_id(),
302 'points' => 4,
303 'required' => 1
304 ),
305 )
306 );
307 $c1->set_ruleconfig(json_encode($rule));
308 $c1->update();
309 $this->assertFalse($comprule->matches($uc1));
310
311 // One required, one not, should match.
312 $rule = array(
313 'base' => array('points' => 8),
314 'competencies' => array(
315 array(
316 'id' => $c11->get_id(),
317 'points' => 4,
318 'required' => 0
319 ),
320 array(
321 'id' => $c12->get_id(),
322 'points' => 4,
323 'required' => 1
324 ),
325 )
326 );
327 $c1->set_ruleconfig(json_encode($rule));
328 $c1->update();
329 $this->assertTrue($comprule->matches($uc1));
330
331 // All required and should match.
332 $rule = array(
333 'base' => array('points' => 8),
334 'competencies' => array(
335 array(
336 'id' => $c11->get_id(),
337 'points' => 4,
338 'required' => 1
339 ),
340 array(
341 'id' => $c12->get_id(),
342 'points' => 4,
343 'required' => 1
344 ),
345 )
346 );
347 $c1->set_ruleconfig(json_encode($rule));
348 $c1->update();
349 $this->assertTrue($comprule->matches($uc1));
350
351 // All required, but one doesn't have a user record.
352 $rule = array(
353 'base' => array('points' => 4),
354 'competencies' => array(
355 array(
356 'id' => $c12->get_id(),
357 'points' => 4,
358 'required' => 1
359 ),
360 array(
361 'id' => $c14->get_id(),
362 'points' => 4,
363 'required' => 1
364 ),
365 )
366 );
367 $c1->set_ruleconfig(json_encode($rule));
368 $c1->update();
369 $this->assertFalse($comprule->matches($uc1));
370 }
371
372}