MDL-63513 mod_assignment: Add removal of context users.
[moodle.git] / lib / tests / indicators_test.php
blob4511766535832f9bbdcef2023cb0d02687e18835
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.
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 * Unit tests for core indicators.
20 * @package core
21 * @category analytics
22 * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 require_once(__DIR__ . '/../../analytics/tests/fixtures/test_target_shortname.php');
29 require_once(__DIR__ . '/../../admin/tool/log/store/standard/tests/fixtures/event.php');
30 require_once(__DIR__ . '/../../lib/enrollib.php');
32 /**
33 * Unit tests for core indicators.
35 * @package core
36 * @category analytics
37 * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 class core_analytics_indicators_testcase extends advanced_testcase {
42 /**
43 * Test all core indicators.
45 * Single method as it is significantly faster (from 13s to 5s) than having separate
46 * methods because of preventResetByRollback.
48 * @return void
50 public function test_core_indicators() {
52 $this->preventResetByRollback();
53 $this->resetAfterTest(true);
54 $this->setAdminuser();
56 set_config('enabled_stores', 'logstore_standard', 'tool_log');
57 set_config('buffersize', 0, 'logstore_standard');
59 $user1 = $this->getDataGenerator()->create_user();
60 $user2 = $this->getDataGenerator()->create_user();
62 // Test any access after end.
63 $params = array(
64 'startdate' => mktime(0, 0, 0, 10, 24, 2015),
65 'enddate' => mktime(0, 0, 0, 10, 24, 2016)
67 $course = $this->getDataGenerator()->create_course($params);
68 $coursecontext = \context_course::instance($course->id);
69 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
71 $indicator = new \core\analytics\indicator\any_access_after_end();
73 $sampleids = array($user1->id => $user1->id, $user2->id => $user2->id);
74 $data = array($user1->id => array(
75 'context' => $coursecontext,
76 'course' => $course,
77 'user' => $user1
78 ));
79 $data[$user2->id] = $data[$user1->id];
80 $data[$user2->id]['user'] = $user2;
81 $indicator->add_sample_data($data);
83 list($values, $unused) = $indicator->calculate($sampleids, 'notrelevanthere');
84 $this->assertEquals($indicator::get_min_value(), $values[$user1->id][0]);
85 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
87 \logstore_standard\event\unittest_executed::create(
88 array('context' => $coursecontext, 'userid' => $user1->id))->trigger();
89 list($values, $unused) = $indicator->calculate($sampleids, 'notrelevanthere');
90 $this->assertEquals($indicator::get_max_value(), $values[$user1->id][0]);
91 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
93 // Test any access before start.
94 $params = array(
95 'startdate' => 9999999998,
96 'enddate' => 9999999999
98 // Resetting $course var.
99 $course = $this->getDataGenerator()->create_course($params);
100 $coursecontext = \context_course::instance($course->id);
101 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
103 $indicator = new \core\analytics\indicator\any_access_before_start();
105 $sampleids = array($user1->id => $user1->id, $user2->id => $user2->id);
106 $data = array($user1->id => array(
107 'context' => $coursecontext,
108 'course' => $course,
109 'user' => $user1
111 $data[$user2->id] = $data[$user1->id];
112 $data[$user2->id]['user'] = $user2;
113 $indicator->add_sample_data($data);
115 list($values, $unused) = $indicator->calculate($sampleids, 'notrelevanthere');
116 $this->assertEquals($indicator::get_min_value(), $values[$user1->id][0]);
117 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
119 \logstore_standard\event\unittest_executed::create(
120 array('context' => $coursecontext, 'userid' => $user1->id))->trigger();
121 list($values, $unused) = $indicator->calculate($sampleids, 'notrelevanthere');
122 $this->assertEquals($indicator::get_max_value(), $values[$user1->id][0]);
123 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
125 // Test any write action.
126 $course1 = $this->getDataGenerator()->create_course();
127 $coursecontext1 = \context_course::instance($course1->id);
128 $course2 = $this->getDataGenerator()->create_course();
129 $coursecontext2 = \context_course::instance($course2->id);
130 $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
132 $indicator = new \core\analytics\indicator\any_write_action();
134 $sampleids = array($user1->id => $user1->id, $user2->id => $user2->id);
135 $data = array($user1->id => array(
136 'context' => $coursecontext1,
137 'course' => $course1,
138 'user' => $user1
140 $data[$user2->id] = $data[$user1->id];
141 $data[$user2->id]['user'] = $user2;
142 $indicator->add_sample_data($data);
144 list($values, $unused) = $indicator->calculate($sampleids, 'user');
145 $this->assertEquals($indicator::get_min_value(), $values[$user1->id][0]);
146 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
148 $beforecourseeventcreate = time();
149 sleep(1);
151 \logstore_standard\event\unittest_executed::create(
152 array('context' => $coursecontext1, 'userid' => $user1->id))->trigger();
153 list($values, $unused) = $indicator->calculate($sampleids, 'user');
154 $this->assertEquals($indicator::get_max_value(), $values[$user1->id][0]);
155 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
157 // Now try with course-level samples where user is not available.
158 $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id);
159 $data = array(
160 $course1->id => array(
161 'context' => $coursecontext1,
162 'course' => $course1,
164 $course2->id => array(
165 'context' => $coursecontext2,
166 'course' => $course2,
169 $indicator->clear_sample_data();
170 $indicator->add_sample_data($data);
172 // Limited by time to avoid previous logs interfering as other logs
173 // have been generated by the system.
174 list($values, $unused) = $indicator->calculate($sampleids, 'course', $beforecourseeventcreate);
175 $this->assertEquals($indicator::get_max_value(), $values[$course1->id][0]);
176 $this->assertEquals($indicator::get_min_value(), $values[$course2->id][0]);
178 // Test any write action in the course.
179 $course1 = $this->getDataGenerator()->create_course();
180 $coursecontext1 = \context_course::instance($course1->id);
181 $activity1 = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id));
182 $activity1context = \context_module::instance($activity1->cmid);
183 $course2 = $this->getDataGenerator()->create_course();
184 $coursecontext2 = \context_course::instance($course2->id);
185 $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
187 $indicator = new \core\analytics\indicator\any_write_action_in_course();
189 $sampleids = array($user1->id => $user1->id, $user2->id => $user2->id);
190 $data = array($user1->id => array(
191 'context' => $coursecontext1,
192 'course' => $course1,
193 'user' => $user1
195 $data[$user2->id] = $data[$user1->id];
196 $data[$user2->id]['user'] = $user2;
197 $indicator->add_sample_data($data);
199 list($values, $unused) = $indicator->calculate($sampleids, 'user');
200 $this->assertEquals($indicator::get_min_value(), $values[$user1->id][0]);
201 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
203 $beforecourseeventcreate = time();
204 sleep(1);
206 \logstore_standard\event\unittest_executed::create(
207 array('context' => $activity1context, 'userid' => $user1->id))->trigger();
208 list($values, $unused) = $indicator->calculate($sampleids, 'user');
209 $this->assertEquals($indicator::get_max_value(), $values[$user1->id][0]);
210 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
212 // Now try with course-level samples where user is not available.
213 $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id);
214 $data = array(
215 $course1->id => array(
216 'context' => $coursecontext1,
217 'course' => $course1,
219 $course2->id => array(
220 'context' => $coursecontext2,
221 'course' => $course2,
224 $indicator->clear_sample_data();
225 $indicator->add_sample_data($data);
227 // Limited by time to avoid previous logs interfering as other logs
228 // have been generated by the system.
229 list($values, $unused) = $indicator->calculate($sampleids, 'course', $beforecourseeventcreate);
230 $this->assertEquals($indicator::get_max_value(), $values[$course1->id][0]);
231 $this->assertEquals($indicator::get_min_value(), $values[$course2->id][0]);
233 // Test read actions.
234 $course = $this->getDataGenerator()->create_course();
235 $coursecontext = \context_course::instance($course->id);
236 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
238 $indicator = new \core\analytics\indicator\read_actions();
240 $sampleids = array($user1->id => $user1->id, $user2->id => $user2->id);
241 $data = array($user1->id => array(
242 'context' => $coursecontext,
243 'course' => $course,
244 'user' => $user1
246 $data[$user2->id] = $data[$user1->id];
247 $data[$user2->id]['user'] = $user2;
248 $indicator->add_sample_data($data);
250 // More or less 4 weeks duration.
251 $startdate = time() - (WEEKSECS * 2);
252 $enddate = time() + (WEEKSECS * 2);
254 $this->setAdminUser();
255 list($values, $unused) = $indicator->calculate($sampleids, 'user');
256 $this->assertNull($values[$user1->id][0]);
257 $this->assertNull($values[$user1->id][1]);
258 $this->assertNull($values[$user1->id][0]);
259 $this->assertNull($values[$user2->id][1]);
261 // Zero score for 0 accesses.
262 list($values, $unused) = $indicator->calculate($sampleids, 'user', $startdate, $enddate);
263 $this->assertEquals($indicator::get_min_value(), $values[$user1->id][0]);
264 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
266 // 1/3 score for more than 0 accesses.
267 \core\event\course_viewed::create(
268 array('context' => $coursecontext, 'userid' => $user1->id))->trigger();
269 list($values, $unused) = $indicator->calculate($sampleids, 'user', $startdate, $enddate);
270 $this->assertEquals(-0.33, $values[$user1->id][0]);
271 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
273 // 2/3 score for more than 1 access per week.
274 for ($i = 0; $i < 12; $i++) {
275 \core\event\course_viewed::create(
276 array('context' => $coursecontext, 'userid' => $user1->id))->trigger();
278 list($values, $unused) = $indicator->calculate($sampleids, 'user', $startdate, $enddate);
279 $this->assertEquals(0.33, $values[$user1->id][0]);
280 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
282 // 100% score for tons of accesses during this period (3 logs per access * 4 weeks * 10 accesses).
283 for ($i = 0; $i < (3 * 10 * 4); $i++) {
284 \core\event\course_viewed::create(
285 array('context' => $coursecontext, 'userid' => $user1->id))->trigger();
287 list($values, $unused) = $indicator->calculate($sampleids, 'user', $startdate, $enddate);
288 $this->assertEquals($indicator::get_max_value(), $values[$user1->id][0]);
289 $this->assertEquals($indicator::get_min_value(), $values[$user2->id][0]);
291 set_config('enabled_stores', '', 'tool_log');
292 get_log_manager(true);