PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/analytics/tests/prediction_actions_test.php

https://github.com/mackensen/moodle
PHP | 247 lines | 156 code | 32 blank | 59 comment | 1 complexity | 5aa23bd6a6d9804d1b89346a5a597622 MD5 | raw file
  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. * Unit tests for prediction actions.
  18. *
  19. * @package core_analytics
  20. * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. defined('MOODLE_INTERNAL') || die();
  24. require_once(__DIR__ . '/fixtures/test_indicator_max.php');
  25. require_once(__DIR__ . '/fixtures/test_target_shortname.php');
  26. /**
  27. * Unit tests for prediction actions.
  28. *
  29. * @package core_analytics
  30. * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
  31. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32. */
  33. class analytics_prediction_actions_testcase extends advanced_testcase {
  34. /**
  35. * Common startup tasks
  36. */
  37. public function setUp(): void {
  38. 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);
  44. }
  45. $this->model = \core_analytics\model::create($target, $indicators);
  46. $this->modelobj = $this->model->get_model_obj();
  47. $this->model->enable('\core\analytics\time_splitting\single_range');
  48. $this->resetAfterTest(true);
  49. $this->course1 = $this->getDataGenerator()->create_course();
  50. $this->course2 = $this->getDataGenerator()->create_course();
  51. $this->context = \context_course::instance($this->course1->id);
  52. $this->teacher1 = $this->getDataGenerator()->create_user();
  53. $this->teacher2 = $this->getDataGenerator()->create_user();
  54. $this->teacher3 = $this->getDataGenerator()->create_user();
  55. $this->getDataGenerator()->enrol_user($this->teacher1->id, $this->course1->id, 'editingteacher');
  56. $this->getDataGenerator()->enrol_user($this->teacher2->id, $this->course1->id, 'editingteacher');
  57. $this->getDataGenerator()->enrol_user($this->teacher3->id, $this->course1->id, 'editingteacher');
  58. // The only relevant fields are modelid, contextid and sampleid. I'm cheating and setting
  59. // contextid as the course context so teachers can access these predictions.
  60. $pred = new \stdClass();
  61. $pred->modelid = $this->model->get_id();
  62. $pred->contextid = $this->context->id;
  63. $pred->sampleid = $this->course1->id;
  64. $pred->rangeindex = 1;
  65. $pred->prediction = 1;
  66. $pred->predictionscore = 1;
  67. $pred->calculations = json_encode(array('test_indicator_max' => 1));
  68. $pred->timecreated = time();
  69. $DB->insert_record('analytics_predictions', $pred);
  70. $pred->sampleid = $this->course2->id;
  71. $DB->insert_record('analytics_predictions', $pred);
  72. }
  73. /**
  74. * test_get_predictions
  75. */
  76. public function test_action_executed() {
  77. global $DB;
  78. $this->assertEquals(0, $DB->count_records('analytics_prediction_actions'));
  79. // Teacher 2 flags a prediction (it doesn't matter which one) as fixed.
  80. $this->setUser($this->teacher2);
  81. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  82. $prediction = reset($predictions);
  83. $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
  84. $recordset = $this->model->get_prediction_actions($this->context);
  85. $this->assertCount(1, $recordset);
  86. $recordset->close();
  87. $this->assertEquals(1, $DB->count_records('analytics_prediction_actions'));
  88. $action = $DB->get_record('analytics_prediction_actions', array('userid' => $this->teacher2->id));
  89. $this->assertEquals(\core_analytics\prediction::ACTION_FIXED, $action->actionname);
  90. $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target());
  91. $recordset = $this->model->get_prediction_actions($this->context);
  92. $this->assertCount(2, $recordset);
  93. $recordset->close();
  94. $this->assertEquals(2, $DB->count_records('analytics_prediction_actions'));
  95. }
  96. /**
  97. * Data provider for test_get_executed_actions.
  98. *
  99. * @return array
  100. */
  101. public function execute_actions_provider(): array {
  102. return [
  103. 'Empty actions with no filter' => [
  104. [],
  105. [],
  106. 0
  107. ],
  108. 'Empty actions with filter' => [
  109. [],
  110. [\core_analytics\prediction::ACTION_FIXED],
  111. 0
  112. ],
  113. 'Multiple actions with no filter' => [
  114. [
  115. \core_analytics\prediction::ACTION_FIXED,
  116. \core_analytics\prediction::ACTION_FIXED,
  117. \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
  118. ],
  119. [],
  120. 3
  121. ],
  122. 'Multiple actions applying filter' => [
  123. [
  124. \core_analytics\prediction::ACTION_FIXED,
  125. \core_analytics\prediction::ACTION_FIXED,
  126. \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
  127. ],
  128. [\core_analytics\prediction::ACTION_FIXED],
  129. 2
  130. ],
  131. 'Multiple actions not applying filter' => [
  132. [
  133. \core_analytics\prediction::ACTION_FIXED,
  134. \core_analytics\prediction::ACTION_FIXED,
  135. \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
  136. ],
  137. [\core_analytics\prediction::ACTION_NOT_APPLICABLE],
  138. 0
  139. ],
  140. 'Multiple actions with multiple filter' => [
  141. [
  142. \core_analytics\prediction::ACTION_FIXED,
  143. \core_analytics\prediction::ACTION_FIXED,
  144. \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
  145. ],
  146. [\core_analytics\prediction::ACTION_FIXED, \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED],
  147. 3
  148. ],
  149. ];
  150. }
  151. /**
  152. * Tests for get_executed_actions() function.
  153. *
  154. * @dataProvider execute_actions_provider
  155. * @param array $actionstoexecute An array of actions to execute
  156. * @param array $actionnamefilter Actions to filter
  157. * @param int $returned Number of actions returned
  158. *
  159. * @covers \core_analytics\prediction::get_executed_actions
  160. */
  161. public function test_get_executed_actions(array $actionstoexecute, array $actionnamefilter, int $returned) {
  162. $this->setUser($this->teacher2);
  163. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  164. $prediction = reset($predictions);
  165. $target = $this->model->get_target();
  166. foreach($actionstoexecute as $action) {
  167. $prediction->action_executed($action, $target);
  168. }
  169. $filteredactions = $prediction->get_executed_actions($actionnamefilter);
  170. $this->assertCount($returned, $filteredactions);
  171. }
  172. /**
  173. * test_get_predictions
  174. */
  175. public function test_get_predictions() {
  176. global $DB;
  177. // Already logged in as admin.
  178. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  179. $this->assertCount(2, $predictions);
  180. $this->setUser($this->teacher1);
  181. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  182. $this->assertCount(2, $predictions);
  183. $this->setUser($this->teacher2);
  184. list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
  185. $this->assertCount(2, $predictions);
  186. // Teacher 2 flags a prediction (it doesn't matter which one).
  187. $prediction = reset($predictions);
  188. $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
  189. $prediction->action_executed(\core_analytics\prediction::ACTION_NOT_APPLICABLE, $this->model->get_target());
  190. $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target());
  191. $recordset = $this->model->get_prediction_actions($this->context);
  192. $this->assertCount(3, $recordset);
  193. $recordset->close();
  194. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  195. $this->assertCount(1, $predictions);
  196. list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
  197. $this->assertCount(2, $predictions);
  198. // Teacher 1 can still see both predictions.
  199. $this->setUser($this->teacher1);
  200. list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
  201. $this->assertCount(2, $predictions);
  202. list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
  203. $this->assertCount(2, $predictions);
  204. $recordset = $this->model->get_prediction_actions($this->context);
  205. $this->assertCount(3, $recordset);
  206. $recordset->close();
  207. // Trying with a deleted course.
  208. $DB->delete_records('course', ['id' => $this->course2->id]);
  209. $this->setUser($this->teacher3);
  210. list($ignored, $predictions) = $this->model->get_predictions($this->context);
  211. $this->assertCount(1, $predictions);
  212. reset($predictions)->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
  213. $this->assertEmpty($this->model->get_predictions($this->context));
  214. }
  215. }