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/>.
17 namespace core_analytics
;
19 defined('MOODLE_INTERNAL') ||
die();
21 require_once(__DIR__
. '/fixtures/test_indicator_max.php');
22 require_once(__DIR__
. '/fixtures/test_target_shortname.php');
25 * Unit tests for prediction actions.
27 * @package core_analytics
28 * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 class prediction_actions_test
extends \advanced_testcase
{
34 * Common startup tasks
36 public function setUp(): void
{
39 $this->setAdminUser();
40 $target = \core_analytics\manager
::get_target('test_target_shortname');
41 $indicators = array('test_indicator_max');
42 foreach ($indicators as $key => $indicator) {
43 $indicators[$key] = \core_analytics\manager
::get_indicator($indicator);
46 $this->model
= \core_analytics\model
::create($target, $indicators);
47 $this->modelobj
= $this->model
->get_model_obj();
48 $this->model
->enable('\core\analytics\time_splitting\single_range');
50 $this->resetAfterTest(true);
52 $this->course1
= $this->getDataGenerator()->create_course();
53 $this->course2
= $this->getDataGenerator()->create_course();
54 $this->context
= \context_course
::instance($this->course1
->id
);
56 $this->teacher1
= $this->getDataGenerator()->create_user();
57 $this->teacher2
= $this->getDataGenerator()->create_user();
58 $this->teacher3
= $this->getDataGenerator()->create_user();
60 $this->getDataGenerator()->enrol_user($this->teacher1
->id
, $this->course1
->id
, 'editingteacher');
61 $this->getDataGenerator()->enrol_user($this->teacher2
->id
, $this->course1
->id
, 'editingteacher');
62 $this->getDataGenerator()->enrol_user($this->teacher3
->id
, $this->course1
->id
, 'editingteacher');
64 // The only relevant fields are modelid, contextid and sampleid. I'm cheating and setting
65 // contextid as the course context so teachers can access these predictions.
66 $pred = new \
stdClass();
67 $pred->modelid
= $this->model
->get_id();
68 $pred->contextid
= $this->context
->id
;
69 $pred->sampleid
= $this->course1
->id
;
70 $pred->rangeindex
= 1;
71 $pred->prediction
= 1;
72 $pred->predictionscore
= 1;
73 $pred->calculations
= json_encode(array('test_indicator_max' => 1));
74 $pred->timecreated
= time();
75 $DB->insert_record('analytics_predictions', $pred);
77 $pred->sampleid
= $this->course2
->id
;
78 $DB->insert_record('analytics_predictions', $pred);
82 * test_get_predictions
84 public function test_action_executed() {
87 $this->assertEquals(0, $DB->count_records('analytics_prediction_actions'));
89 // Teacher 2 flags a prediction (it doesn't matter which one) as fixed.
90 $this->setUser($this->teacher2
);
91 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
92 $prediction = reset($predictions);
93 $prediction->action_executed(\core_analytics\prediction
::ACTION_FIXED
, $this->model
->get_target());
95 $recordset = $this->model
->get_prediction_actions($this->context
);
96 $this->assertCount(1, $recordset);
98 $this->assertEquals(1, $DB->count_records('analytics_prediction_actions'));
99 $action = $DB->get_record('analytics_prediction_actions', array('userid' => $this->teacher2
->id
));
100 $this->assertEquals(\core_analytics\prediction
::ACTION_FIXED
, $action->actionname
);
102 $prediction->action_executed(\core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
, $this->model
->get_target());
103 $recordset = $this->model
->get_prediction_actions($this->context
);
104 $this->assertCount(2, $recordset);
106 $this->assertEquals(2, $DB->count_records('analytics_prediction_actions'));
110 * Data provider for test_get_executed_actions.
114 public function execute_actions_provider(): array {
116 'Empty actions with no filter' => [
121 'Empty actions with filter' => [
123 [\core_analytics\prediction
::ACTION_FIXED
],
126 'Multiple actions with no filter' => [
128 \core_analytics\prediction
::ACTION_FIXED
,
129 \core_analytics\prediction
::ACTION_FIXED
,
130 \core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
135 'Multiple actions applying filter' => [
137 \core_analytics\prediction
::ACTION_FIXED
,
138 \core_analytics\prediction
::ACTION_FIXED
,
139 \core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
141 [\core_analytics\prediction
::ACTION_FIXED
],
144 'Multiple actions not applying filter' => [
146 \core_analytics\prediction
::ACTION_FIXED
,
147 \core_analytics\prediction
::ACTION_FIXED
,
148 \core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
150 [\core_analytics\prediction
::ACTION_NOT_APPLICABLE
],
153 'Multiple actions with multiple filter' => [
155 \core_analytics\prediction
::ACTION_FIXED
,
156 \core_analytics\prediction
::ACTION_FIXED
,
157 \core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
159 [\core_analytics\prediction
::ACTION_FIXED
, \core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
],
166 * Tests for get_executed_actions() function.
168 * @dataProvider execute_actions_provider
169 * @param array $actionstoexecute An array of actions to execute
170 * @param array $actionnamefilter Actions to filter
171 * @param int $returned Number of actions returned
173 * @covers \core_analytics\prediction::get_executed_actions
175 public function test_get_executed_actions(array $actionstoexecute, array $actionnamefilter, int $returned) {
177 $this->setUser($this->teacher2
);
178 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
179 $prediction = reset($predictions);
180 $target = $this->model
->get_target();
181 foreach($actionstoexecute as $action) {
182 $prediction->action_executed($action, $target);
185 $filteredactions = $prediction->get_executed_actions($actionnamefilter);
186 $this->assertCount($returned, $filteredactions);
190 * test_get_predictions
192 public function test_get_predictions() {
195 // Already logged in as admin.
196 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
197 $this->assertCount(2, $predictions);
199 $this->setUser($this->teacher1
);
200 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
201 $this->assertCount(2, $predictions);
203 $this->setUser($this->teacher2
);
204 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, false);
205 $this->assertCount(2, $predictions);
207 // Teacher 2 flags a prediction (it doesn't matter which one).
208 $prediction = reset($predictions);
209 $prediction->action_executed(\core_analytics\prediction
::ACTION_FIXED
, $this->model
->get_target());
210 $prediction->action_executed(\core_analytics\prediction
::ACTION_NOT_APPLICABLE
, $this->model
->get_target());
211 $prediction->action_executed(\core_analytics\prediction
::ACTION_INCORRECTLY_FLAGGED
, $this->model
->get_target());
213 $recordset = $this->model
->get_prediction_actions($this->context
);
214 $this->assertCount(3, $recordset);
217 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
218 $this->assertCount(1, $predictions);
219 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, false);
220 $this->assertCount(2, $predictions);
222 // Teacher 1 can still see both predictions.
223 $this->setUser($this->teacher1
);
224 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, true);
225 $this->assertCount(2, $predictions);
226 list($ignored, $predictions) = $this->model
->get_predictions($this->context
, false);
227 $this->assertCount(2, $predictions);
229 $recordset = $this->model
->get_prediction_actions($this->context
);
230 $this->assertCount(3, $recordset);
233 // Trying with a deleted course.
234 $DB->delete_records('course', ['id' => $this->course2
->id
]);
235 $this->setUser($this->teacher3
);
236 list($ignored, $predictions) = $this->model
->get_predictions($this->context
);
237 $this->assertCount(1, $predictions);
238 reset($predictions)->action_executed(\core_analytics\prediction
::ACTION_FIXED
, $this->model
->get_target());
239 $this->assertEmpty($this->model
->get_predictions($this->context
));