Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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  /**
  18   * Unit tests for core analysers.
  19   *
  20   * @package   core
  21   * @category  test
  22   * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  require_once (__DIR__ . '/../../analytics/tests/fixtures/test_target_course_level_shortname.php');
  29  require_once (__DIR__ . '/../../analytics/tests/fixtures/test_target_shortname.php');
  30  require_once (__DIR__ . '/fixtures/deprecated_analyser.php');
  31  require_once (__DIR__ . '/../../lib/enrollib.php');
  32  
  33  /**
  34   * Unit tests for core analysers.
  35   *
  36   * @package   core
  37   * @category  test
  38   * @copyright 2017 David MonllaĆ³ {@link http://www.davidmonllao.com}
  39   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  40   */
  41  class core_analytics_analysers_testcase extends advanced_testcase {
  42  
  43      /**
  44       * test_courses_analyser
  45       *
  46       * @return void
  47       */
  48      public function test_courses_analyser() {
  49          $this->resetAfterTest(true);
  50  
  51          $course1 = $this->getDataGenerator()->create_course();
  52          $coursecontext = \context_course::instance($course1->id);
  53  
  54          $target = new test_target_shortname();
  55          $analyser = new \core\analytics\analyser\courses(1, $target, [], [], []);
  56          $analysable = new \core_analytics\course($course1);
  57  
  58          $this->assertInstanceOf('\core_analytics\course', $analyser->get_sample_analysable($course1->id));
  59  
  60          $this->assertInstanceOf('\context_course', $analyser->sample_access_context($course1->id));
  61  
  62          // Just 1 sample per course.
  63          $class = new ReflectionClass('\core\analytics\analyser\courses');
  64          $method = $class->getMethod('get_all_samples');
  65          $method->setAccessible(true);
  66          list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable);
  67          $this->assertCount(1, $sampleids);
  68          $sampleid = reset($sampleids);
  69          $this->assertEquals($course1->id, $sampleid);
  70          $this->assertEquals($course1->fullname, $samplesdata[$sampleid]['course']->fullname);
  71          $this->assertEquals($coursecontext, $samplesdata[$sampleid]['context']);
  72  
  73          // To compare it later.
  74          $prevsampledata = $samplesdata[$sampleid];
  75          list($sampleids, $samplesdata) = $analyser->get_samples(array($sampleid));
  76          $this->assertEquals($prevsampledata['context'], $samplesdata[$sampleid]['context']);
  77          $this->assertEquals($prevsampledata['course']->shortname, $samplesdata[$sampleid]['course']->shortname);
  78  
  79          // Context restriction.
  80          $category1 = $this->getDataGenerator()->create_category();
  81          $category1context = \context_coursecat::instance($category1->id);
  82          $category2 = $this->getDataGenerator()->create_category();
  83          $category2context = \context_coursecat::instance($category2->id);
  84          $course2 = $this->getDataGenerator()->create_course(['category' => $category1->id]);
  85          $course3 = $this->getDataGenerator()->create_course(['category' => $category2->id]);
  86          $this->assertCount(2, $analyser->get_analysables_iterator(false, [$category1context, $category2context]));
  87  
  88      }
  89  
  90      /**
  91       * test_site_courses_analyser
  92       *
  93       * @return void
  94       */
  95      public function test_site_courses_analyser() {
  96          $this->resetAfterTest(true);
  97  
  98          $course1 = $this->getDataGenerator()->create_course();
  99          $course2 = $this->getDataGenerator()->create_course();
 100          $course3 = $this->getDataGenerator()->create_course();
 101          $course1context = \context_course::instance($course1->id);
 102  
 103          $target = new test_target_shortname();
 104          $analyser = new \core\analytics\analyser\site_courses(1, $target, [], [], []);
 105          $analysable = new \core_analytics\site();
 106  
 107          $this->assertInstanceOf('\core_analytics\site', $analyser->get_sample_analysable($course1->id));
 108          $this->assertInstanceOf('\core_analytics\site', $analyser->get_sample_analysable($course2->id));
 109  
 110          $this->assertInstanceOf('\context_system', $analyser->sample_access_context($course1->id));
 111          $this->assertInstanceOf('\context_system', $analyser->sample_access_context($course3->id));
 112  
 113          $class = new ReflectionClass('\core\analytics\analyser\site_courses');
 114          $method = $class->getMethod('get_all_samples');
 115          $method->setAccessible(true);
 116          list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable);
 117          $this->assertCount(3, $sampleids);
 118  
 119          // Use course1 it does not really matter.
 120          $this->assertArrayHasKey($course1->id, $sampleids);
 121          $sampleid = $course1->id;
 122          $this->assertEquals($course1->id, $sampleid);
 123          $this->assertEquals($course1->fullname, $samplesdata[$sampleid]['course']->fullname);
 124          $this->assertEquals($course1context, $samplesdata[$sampleid]['context']);
 125  
 126          // To compare it later.
 127          $prevsampledata = $samplesdata[$sampleid];
 128          list($sampleids, $samplesdata) = $analyser->get_samples(array($sampleid));
 129          $this->assertEquals($prevsampledata['context'], $samplesdata[$sampleid]['context']);
 130          $this->assertEquals($prevsampledata['course']->shortname, $samplesdata[$sampleid]['course']->shortname);
 131      }
 132  
 133      /**
 134       * test_student_enrolments_analyser
 135       *
 136       * @return void
 137       */
 138      public function test_student_enrolments_analyser() {
 139          global $DB;
 140  
 141          $this->resetAfterTest(true);
 142  
 143          $course1 = $this->getDataGenerator()->create_course();
 144          $course1context = \context_course::instance($course1->id);
 145  
 146          $user1 = $this->getDataGenerator()->create_user();
 147          $user2 = $this->getDataGenerator()->create_user();
 148          $user3 = $this->getDataGenerator()->create_user();
 149  
 150          // Checking that suspended users are also included.
 151          $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
 152          $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student', 'manual', 0, 0, ENROL_USER_SUSPENDED);
 153          $this->getDataGenerator()->enrol_user($user3->id, $course1->id, 'editingteacher');
 154          $enrol = $DB->get_record('enrol', array('courseid' => $course1->id, 'enrol' => 'manual'));
 155          $ue1 = $DB->get_record('user_enrolments', array('userid' => $user1->id, 'enrolid' => $enrol->id));
 156          $ue2 = $DB->get_record('user_enrolments', array('userid' => $user2->id, 'enrolid' => $enrol->id));
 157  
 158          $target = new test_target_shortname();
 159          $analyser = new \core\analytics\analyser\student_enrolments(1, $target, [], [], []);
 160          $analysable = new \core_analytics\course($course1);
 161  
 162          $this->assertInstanceOf('\core_analytics\course', $analyser->get_sample_analysable($ue1->id));
 163          $this->assertInstanceOf('\context_course', $analyser->sample_access_context($ue1->id));
 164  
 165          $class = new ReflectionClass('\core\analytics\analyser\student_enrolments');
 166          $method = $class->getMethod('get_all_samples');
 167          $method->setAccessible(true);
 168          list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable);
 169          // Only students.
 170          $this->assertCount(2, $sampleids);
 171  
 172          $this->assertArrayHasKey($ue1->id, $sampleids);
 173          $this->assertArrayHasKey($ue2->id, $sampleids);
 174  
 175          // Shouldn't matter which one we select.
 176          $sampleid = $ue1->id;
 177          $this->assertEquals($ue1, $samplesdata[$sampleid]['user_enrolments']);
 178          $this->assertEquals($course1->fullname, $samplesdata[$sampleid]['course']->fullname);
 179          $this->assertEquals($course1context, $samplesdata[$sampleid]['context']);
 180          $this->assertEquals($user1->firstname, $samplesdata[$sampleid]['user']->firstname);
 181  
 182          // To compare it later.
 183          $prevsampledata = $samplesdata[$sampleid];
 184          list($sampleids, $samplesdata) = $analyser->get_samples(array($sampleid));
 185          $this->assertEquals($prevsampledata['user_enrolments'], $samplesdata[$sampleid]['user_enrolments']);
 186          $this->assertEquals($prevsampledata['context'], $samplesdata[$sampleid]['context']);
 187          $this->assertEquals($prevsampledata['course']->shortname, $samplesdata[$sampleid]['course']->shortname);
 188          $this->assertEquals($prevsampledata['user']->firstname, $samplesdata[$sampleid]['user']->firstname);
 189  
 190          // Context restriction.
 191          $category1 = $this->getDataGenerator()->create_category();
 192          $category1context = \context_coursecat::instance($category1->id);
 193          $category2 = $this->getDataGenerator()->create_category();
 194          $category2context = \context_coursecat::instance($category2->id);
 195          $course2 = $this->getDataGenerator()->create_course(['category' => $category1->id]);
 196          $course3 = $this->getDataGenerator()->create_course(['category' => $category2->id]);
 197          $this->assertCount(2, $analyser->get_analysables_iterator(false, [$category1context, $category2context]));
 198      }
 199  
 200      /**
 201       * test_deprecated_analyser
 202       *
 203       * @return void
 204       */
 205      public function test_deprecated_analyser() {
 206  
 207          $target = new test_target_shortname();
 208          $analyser = new deprecated_analyser(1, $target, [], [], []);
 209  
 210          $analysables = $analyser->get_analysables_iterator();
 211          $this->assertDebuggingCalled();
 212      }
 213  
 214      /**
 215       * test_get_analysables_iterator description
 216       *
 217       * @return null
 218       */
 219      public function test_get_analysables_iterator() {
 220          global $DB;
 221  
 222          $this->resetAfterTest(true);
 223  
 224          $courses = array();
 225          for ($i = 0; $i < 2; $i++) {
 226              $course = $this->getDataGenerator()->create_course();
 227              $analysable = new \core_analytics\course($course);
 228              $courses[$analysable->get_id()] = $course;
 229          }
 230  
 231          // Check that the analysis performs as expected.
 232          $modelid = 1;
 233          $includetarget = false;
 234  
 235          $target = new test_target_course_level_shortname();
 236          $analyser = new \core\analytics\analyser\courses($modelid, $target, [], [], []);
 237  
 238          $result = new \core_analytics\local\analysis\result_array($modelid, $includetarget, []);
 239          $analysis = new \core_analytics\analysis($analyser, $includetarget, $result);
 240          $analysis->run();
 241          $params = array('modelid' => $modelid, 'action' => 'prediction');
 242          $this->assertEquals(2, $DB->count_records('analytics_used_analysables', $params));
 243  
 244          // Check that the previous records do not conflict with the includetarget == false ones.
 245          $includetarget = true;
 246  
 247          $target = new test_target_course_level_shortname();
 248          $analyser = new \core\analytics\analyser\courses($modelid, $target, [], [], []);
 249  
 250          $result = new \core_analytics\local\analysis\result_array($modelid, $includetarget, []);
 251          $analysis = new \core_analytics\analysis($analyser, $includetarget, $result);
 252          $analysis->run();
 253          $params = array('modelid' => $modelid, 'action' => 'prediction');
 254          $this->assertEquals(2, $DB->count_records('analytics_used_analysables', $params));
 255          $params = array('modelid' => $modelid, 'action' => 'training');
 256          $this->assertEquals(2, $DB->count_records('analytics_used_analysables', $params));
 257          $params = array('modelid' => $modelid);
 258          $this->assertEquals(4, $DB->count_records('analytics_used_analysables', $params));
 259  
 260          // Check that other models' records do not conflict with previous records.
 261          $prevmodelid = 1;
 262          $modelid = 2;
 263          $includetarget = false;
 264  
 265          $target = new test_target_course_level_shortname();
 266          $analyser = new \core\analytics\analyser\courses($modelid, $target, [], [], []);
 267  
 268          $result = new \core_analytics\local\analysis\result_array($modelid, $includetarget, []);
 269          $analysis = new \core_analytics\analysis($analyser, $includetarget, $result);
 270          $analysis->run();
 271          $params = array('modelid' => $prevmodelid);
 272          $this->assertEquals(4, $DB->count_records('analytics_used_analysables', $params));
 273          $params = array('modelid' => $modelid, 'action' => 'prediction');
 274          $this->assertEquals(2, $DB->count_records('analytics_used_analysables', $params));
 275          $this->assertEquals(6, $DB->count_records('analytics_used_analysables'));
 276  
 277          $includetarget = true;
 278  
 279          $target = new test_target_course_level_shortname();
 280          $analyser = new \core\analytics\analyser\courses($modelid, $target, [], [], []);
 281  
 282          $result = new \core_analytics\local\analysis\result_array($modelid, $includetarget, []);
 283          $analysis = new \core_analytics\analysis($analyser, $includetarget, $result);
 284          $analysis->run();
 285          $params = array('modelid' => $prevmodelid);
 286          $this->assertEquals(4, $DB->count_records('analytics_used_analysables', $params));
 287          $params = array('modelid' => $modelid, 'action' => 'training');
 288          $this->assertEquals(2, $DB->count_records('analytics_used_analysables', $params));
 289          $this->assertEquals(8, $DB->count_records('analytics_used_analysables'));
 290      }
 291  }