Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 namespace core_analytics; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 require_once (__DIR__ . '/fixtures/test_indicator_max.php'); 22 require_once (__DIR__ . '/fixtures/test_target_shortname.php'); 23 24 /** 25 * Unit tests for prediction actions. 26 * 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 30 */ 31 class prediction_actions_test extends \advanced_testcase { 32 33 /** @var model Store Model. */ 34 protected $model; 35 36 /** @var \stdClass Store model object. */ 37 protected $modelobj; 38 39 /** @var \stdClass Course 1 record. */ 40 protected $course1; 41 42 /** @var \stdClass Course 2 record. */ 43 protected $course2; 44 45 /** @var \context_course Store Model. */ 46 protected $context; 47 48 /** @var \stdClass Teacher 1 user record. */ 49 protected $teacher1; 50 51 /** @var \stdClass Teacher 2 user record. */ 52 protected $teacher2; 53 54 /** @var \stdClass Teacher 3 user record. */ 55 protected $teacher3; 56 57 /** 58 * Common startup tasks 59 */ 60 public function setUp(): void { 61 global $DB; 62 63 $this->setAdminUser(); 64 $target = \core_analytics\manager::get_target('test_target_shortname'); 65 $indicators = array('test_indicator_max'); 66 foreach ($indicators as $key => $indicator) { 67 $indicators[$key] = \core_analytics\manager::get_indicator($indicator); 68 } 69 70 $this->model = \core_analytics\model::create($target, $indicators); 71 $this->modelobj = $this->model->get_model_obj(); 72 $this->model->enable('\core\analytics\time_splitting\single_range'); 73 74 $this->resetAfterTest(true); 75 76 $this->course1 = $this->getDataGenerator()->create_course(); 77 $this->course2 = $this->getDataGenerator()->create_course(); 78 $this->context = \context_course::instance($this->course1->id); 79 80 $this->teacher1 = $this->getDataGenerator()->create_user(); 81 $this->teacher2 = $this->getDataGenerator()->create_user(); 82 $this->teacher3 = $this->getDataGenerator()->create_user(); 83 84 $this->getDataGenerator()->enrol_user($this->teacher1->id, $this->course1->id, 'editingteacher'); 85 $this->getDataGenerator()->enrol_user($this->teacher2->id, $this->course1->id, 'editingteacher'); 86 $this->getDataGenerator()->enrol_user($this->teacher3->id, $this->course1->id, 'editingteacher'); 87 88 // The only relevant fields are modelid, contextid and sampleid. I'm cheating and setting 89 // contextid as the course context so teachers can access these predictions. 90 $pred = new \stdClass(); 91 $pred->modelid = $this->model->get_id(); 92 $pred->contextid = $this->context->id; 93 $pred->sampleid = $this->course1->id; 94 $pred->rangeindex = 1; 95 $pred->prediction = 1; 96 $pred->predictionscore = 1; 97 $pred->calculations = json_encode(array('test_indicator_max' => 1)); 98 $pred->timecreated = time(); 99 $DB->insert_record('analytics_predictions', $pred); 100 101 $pred->sampleid = $this->course2->id; 102 $DB->insert_record('analytics_predictions', $pred); 103 } 104 105 /** 106 * test_get_predictions 107 */ 108 public function test_action_executed() { 109 global $DB; 110 111 $this->assertEquals(0, $DB->count_records('analytics_prediction_actions')); 112 113 // Teacher 2 flags a prediction (it doesn't matter which one) as fixed. 114 $this->setUser($this->teacher2); 115 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 116 $prediction = reset($predictions); 117 $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target()); 118 119 $recordset = $this->model->get_prediction_actions($this->context); 120 $this->assertCount(1, $recordset); 121 $recordset->close(); 122 $this->assertEquals(1, $DB->count_records('analytics_prediction_actions')); 123 $action = $DB->get_record('analytics_prediction_actions', array('userid' => $this->teacher2->id)); 124 $this->assertEquals(\core_analytics\prediction::ACTION_FIXED, $action->actionname); 125 126 $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target()); 127 $recordset = $this->model->get_prediction_actions($this->context); 128 $this->assertCount(2, $recordset); 129 $recordset->close(); 130 $this->assertEquals(2, $DB->count_records('analytics_prediction_actions')); 131 } 132 133 /** 134 * Data provider for test_get_executed_actions. 135 * 136 * @return array 137 */ 138 public function execute_actions_provider(): array { 139 return [ 140 'Empty actions with no filter' => [ 141 [], 142 [], 143 0 144 ], 145 'Empty actions with filter' => [ 146 [], 147 [\core_analytics\prediction::ACTION_FIXED], 148 0 149 ], 150 'Multiple actions with no filter' => [ 151 [ 152 \core_analytics\prediction::ACTION_FIXED, 153 \core_analytics\prediction::ACTION_FIXED, 154 \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED 155 ], 156 [], 157 3 158 ], 159 'Multiple actions applying filter' => [ 160 [ 161 \core_analytics\prediction::ACTION_FIXED, 162 \core_analytics\prediction::ACTION_FIXED, 163 \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED 164 ], 165 [\core_analytics\prediction::ACTION_FIXED], 166 2 167 ], 168 'Multiple actions not applying filter' => [ 169 [ 170 \core_analytics\prediction::ACTION_FIXED, 171 \core_analytics\prediction::ACTION_FIXED, 172 \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED 173 ], 174 [\core_analytics\prediction::ACTION_NOT_APPLICABLE], 175 0 176 ], 177 'Multiple actions with multiple filter' => [ 178 [ 179 \core_analytics\prediction::ACTION_FIXED, 180 \core_analytics\prediction::ACTION_FIXED, 181 \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED 182 ], 183 [\core_analytics\prediction::ACTION_FIXED, \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED], 184 3 185 ], 186 ]; 187 } 188 189 /** 190 * Tests for get_executed_actions() function. 191 * 192 * @dataProvider execute_actions_provider 193 * @param array $actionstoexecute An array of actions to execute 194 * @param array $actionnamefilter Actions to filter 195 * @param int $returned Number of actions returned 196 * 197 * @covers \core_analytics\prediction::get_executed_actions 198 */ 199 public function test_get_executed_actions(array $actionstoexecute, array $actionnamefilter, int $returned) { 200 201 $this->setUser($this->teacher2); 202 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 203 $prediction = reset($predictions); 204 $target = $this->model->get_target(); 205 foreach($actionstoexecute as $action) { 206 $prediction->action_executed($action, $target); 207 } 208 209 $filteredactions = $prediction->get_executed_actions($actionnamefilter); 210 $this->assertCount($returned, $filteredactions); 211 } 212 213 /** 214 * test_get_predictions 215 */ 216 public function test_get_predictions() { 217 global $DB; 218 219 // Already logged in as admin. 220 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 221 $this->assertCount(2, $predictions); 222 223 $this->setUser($this->teacher1); 224 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 225 $this->assertCount(2, $predictions); 226 227 $this->setUser($this->teacher2); 228 list($ignored, $predictions) = $this->model->get_predictions($this->context, false); 229 $this->assertCount(2, $predictions); 230 231 // Teacher 2 flags a prediction (it doesn't matter which one). 232 $prediction = reset($predictions); 233 $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target()); 234 $prediction->action_executed(\core_analytics\prediction::ACTION_NOT_APPLICABLE, $this->model->get_target()); 235 $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target()); 236 237 $recordset = $this->model->get_prediction_actions($this->context); 238 $this->assertCount(3, $recordset); 239 $recordset->close(); 240 241 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 242 $this->assertCount(1, $predictions); 243 list($ignored, $predictions) = $this->model->get_predictions($this->context, false); 244 $this->assertCount(2, $predictions); 245 246 // Teacher 1 can still see both predictions. 247 $this->setUser($this->teacher1); 248 list($ignored, $predictions) = $this->model->get_predictions($this->context, true); 249 $this->assertCount(2, $predictions); 250 list($ignored, $predictions) = $this->model->get_predictions($this->context, false); 251 $this->assertCount(2, $predictions); 252 253 $recordset = $this->model->get_prediction_actions($this->context); 254 $this->assertCount(3, $recordset); 255 $recordset->close(); 256 257 // Trying with a deleted course. 258 $DB->delete_records('course', ['id' => $this->course2->id]); 259 $this->setUser($this->teacher3); 260 list($ignored, $predictions) = $this->model->get_predictions($this->context); 261 $this->assertCount(1, $predictions); 262 reset($predictions)->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target()); 263 $this->assertEmpty($this->model->get_predictions($this->context)); 264 } 265 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body