Moodle release 3.11.12
[moodle.git] / analytics / tests / prediction_actions_test.php
blobadfd8fe19bb6ffb806dcc9438ac38448ae19a0fb
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 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');
24 /**
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 {
33 /**
34 * Common startup tasks
36 public function setUp(): void {
37 global $DB;
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);
81 /**
82 * test_get_predictions
84 public function test_action_executed() {
85 global $DB;
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);
97 $recordset->close();
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);
105 $recordset->close();
106 $this->assertEquals(2, $DB->count_records('analytics_prediction_actions'));
110 * Data provider for test_get_executed_actions.
112 * @return array
114 public function execute_actions_provider(): array {
115 return [
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() {
193 global $DB;
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);
215 $recordset->close();
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);
231 $recordset->close();
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));