Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

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