Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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.
   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_course indicators.
  19   *
  20   * @package   core_course
  21   * @category  analytics
  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  global $CFG;
  29  require_once (__DIR__ . '/../../lib/completionlib.php');
  30  require_once (__DIR__ . '/../../completion/criteria/completion_criteria_self.php');
  31  require_once (__DIR__ . '/../../analytics/tests/fixtures/test_target_course_users.php');
  32  
  33  /**
  34   * Unit tests for core_course indicators.
  35   *
  36   * @package   core_course
  37   * @category  analytics
  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_course_indicators_testcase extends advanced_testcase {
  42  
  43      /**
  44       * test_no_teacher
  45       *
  46       * @return void
  47       */
  48      public function test_no_teacher() {
  49          global $DB;
  50  
  51          $this->resetAfterTest(true);
  52  
  53          $course1 = $this->getDataGenerator()->create_course();
  54          $course2 = $this->getDataGenerator()->create_course();
  55          $coursecontext1 = \context_course::instance($course1->id);
  56          $coursecontext2 = \context_course::instance($course2->id);
  57  
  58          $user = $this->getDataGenerator()->create_user();
  59  
  60          $this->getDataGenerator()->enrol_user($user->id, $course1->id, 'student');
  61          $this->getDataGenerator()->enrol_user($user->id, $course2->id, 'teacher');
  62  
  63          $indicator = new \core_course\analytics\indicator\no_teacher();
  64  
  65          $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id);
  66          $data = array(
  67              $course1->id => array(
  68                  'context' => $coursecontext1,
  69                  'course' => $course1,
  70              ),
  71              $course2->id => array(
  72                  'context' => $coursecontext2,
  73                  'course' => $course2,
  74              ));
  75          $indicator->add_sample_data($data);
  76  
  77          list($values, $ignored) = $indicator->calculate($sampleids, 'course');
  78          $this->assertEquals($indicator::get_min_value(), $values[$course1->id][0]);
  79          $this->assertEquals($indicator::get_max_value(), $values[$course2->id][0]);
  80      }
  81  
  82      /**
  83       * test_completion_enabled
  84       *
  85       * @return void
  86       */
  87      public function test_completion_enabled() {
  88          global $DB;
  89  
  90          $this->resetAfterTest(true);
  91  
  92          $course1 = $this->getDataGenerator()->create_course(array('enablecompletion' => 0));
  93          $course2 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
  94          $course3 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
  95  
  96          // Criteria only for the last one.
  97          $criteriadata = new stdClass();
  98          $criteriadata->id = $course3->id;
  99          $criteriadata->criteria_self = 1;
 100          $criterion = new completion_criteria_self();
 101          $criterion->update_config($criteriadata);
 102  
 103          $indicator = new \core_course\analytics\indicator\completion_enabled();
 104  
 105          $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id, $course3->id => $course3->id);
 106          $data = array(
 107              $course1->id => array(
 108                  'course' => $course1,
 109              ),
 110              $course2->id => array(
 111                  'course' => $course2,
 112              ),
 113              $course3->id => array(
 114                  'course' => $course3,
 115              ));
 116          $indicator->add_sample_data($data);
 117  
 118          // Calculate using course samples.
 119          list($values, $ignored) = $indicator->calculate($sampleids, 'course');
 120          $this->assertEquals($indicator::get_min_value(), $values[$course1->id][0]);
 121          $this->assertEquals($indicator::get_min_value(), $values[$course2->id][0]);
 122          $this->assertEquals($indicator::get_max_value(), $values[$course3->id][0]);
 123  
 124          // Calculate using course_modules samples.
 125          $indicator->clear_sample_data();
 126          $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course3->id),
 127                                                               array('completion' => 0));
 128          $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course3->id),
 129                                                               array('completion' => 1));
 130  
 131          $sampleids = array($data1->cmid => $data1->cmid, $data2->cmid => $data2->cmid);
 132          $cm1 = $DB->get_record('course_modules', array('id' => $data1->cmid));
 133          $cm2 = $DB->get_record('course_modules', array('id' => $data2->cmid));
 134          $data = array(
 135              $cm1->id => array(
 136                  'course' => $course3,
 137                  'course_modules' => $cm1,
 138              ),
 139              $cm2->id => array(
 140                  'course' => $course3,
 141                  'course_modules' => $cm2,
 142              ));
 143          $indicator->add_sample_data($data);
 144  
 145          list($values, $ignored) = $indicator->calculate($sampleids, 'course_modules');
 146          $this->assertEquals($indicator::get_min_value(), $values[$cm1->id][0]);
 147          $this->assertEquals($indicator::get_max_value(), $values[$cm2->id][0]);
 148      }
 149  
 150      /**
 151       * test_potential_cognitive
 152       *
 153       * @return void
 154       */
 155      public function test_potential_cognitive() {
 156          global $DB;
 157  
 158          $this->resetAfterTest(true);
 159  
 160          $course1 = $this->getDataGenerator()->create_course();
 161  
 162          $course2 = $this->getDataGenerator()->create_course();
 163          $page = $this->getDataGenerator()->create_module('page', array('course' => $course2->id));
 164  
 165          $course3 = $this->getDataGenerator()->create_course();
 166          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course3->id));
 167          $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course3->id));
 168  
 169          $course4 = $this->getDataGenerator()->create_course();
 170          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course4->id));
 171          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course4->id));
 172  
 173          $indicator = new \core_course\analytics\indicator\potential_cognitive_depth();
 174  
 175          $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id, $course3->id => $course3->id,
 176              $course4->id => $course4->id);
 177          $data = array(
 178              $course1->id => array(
 179                  'course' => $course1,
 180              ),
 181              $course2->id => array(
 182                  'course' => $course2,
 183              ),
 184              $course3->id => array(
 185                  'course' => $course3,
 186              ),
 187              $course4->id => array(
 188                  'course' => $course4,
 189              ));
 190          $indicator->add_sample_data($data);
 191  
 192          list($values, $ignored) = $indicator->calculate($sampleids, 'course');
 193          $this->assertEquals($indicator::get_min_value(), $values[$course1->id][0]);
 194  
 195          // General explanation about the points, the max level is 5 so level 1 is -1, level 2 is -0.5, level 3 is 0,
 196          // level 4 is 0.5 and level 5 is 1.
 197  
 198          // Page cognitive is level 1 (the lower one).
 199          $this->assertEquals($indicator::get_min_value(), $values[$course2->id][0]);
 200  
 201          // The maximum cognitive depth level is 5, assign level is 5 therefore the potential cognitive depth is the max.
 202          $this->assertEquals($indicator::get_max_value(), $values[$course3->id][0]);
 203  
 204          // Forum level is 4.
 205          $this->assertEquals(0.5, $values[$course4->id][0]);
 206  
 207          // Calculate using course_modules samples.
 208          $course5 = $this->getDataGenerator()->create_course();
 209          $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course5->id));
 210          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course5->id));
 211  
 212          $sampleids = array($assign->cmid => $assign->cmid, $forum->cmid => $forum->cmid);
 213          $cm1 = $DB->get_record('course_modules', array('id' => $assign->cmid));
 214          $cm2 = $DB->get_record('course_modules', array('id' => $forum->cmid));
 215          $data = array(
 216              $cm1->id => array(
 217                  'course' => $course5,
 218                  'course_modules' => $cm1,
 219              ),
 220              $cm2->id => array(
 221                  'course' => $course5,
 222                  'course_modules' => $cm2,
 223              ));
 224          $indicator->clear_sample_data();
 225          $indicator->add_sample_data($data);
 226  
 227          list($values, $ignored) = $indicator->calculate($sampleids, 'course_modules');
 228          // Assign level is 5, the maximum level.
 229          $this->assertEquals($indicator::get_max_value(), $values[$cm1->id][0]);
 230          // Forum level is 4.
 231          $this->assertEquals(0.5, $values[$cm2->id][0]);
 232  
 233      }
 234  
 235      /**
 236       * test_potential_social
 237       *
 238       * @return void
 239       */
 240      public function test_potential_social() {
 241          global $DB;
 242  
 243          $this->resetAfterTest(true);
 244  
 245          $course1 = $this->getDataGenerator()->create_course();
 246  
 247          $course2 = $this->getDataGenerator()->create_course();
 248          $page = $this->getDataGenerator()->create_module('page', array('course' => $course2->id));
 249  
 250          $course3 = $this->getDataGenerator()->create_course();
 251          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course3->id));
 252          $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course3->id));
 253  
 254          $course4 = $this->getDataGenerator()->create_course();
 255          $page = $this->getDataGenerator()->create_module('page', array('course' => $course4->id));
 256          $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course4->id));
 257  
 258          $indicator = new \core_course\analytics\indicator\potential_social_breadth();
 259  
 260          $sampleids = array($course1->id => $course1->id, $course2->id => $course2->id, $course3->id => $course3->id,
 261              $course4->id => $course4->id);
 262          $data = array(
 263              $course1->id => array(
 264                  'course' => $course1,
 265              ),
 266              $course2->id => array(
 267                  'course' => $course2,
 268              ),
 269              $course3->id => array(
 270                  'course' => $course3,
 271              ),
 272              $course4->id => array(
 273                  'course' => $course4,
 274              ));
 275          $indicator->add_sample_data($data);
 276  
 277          list($values, $ignored) = $indicator->calculate($sampleids, 'course');
 278          $this->assertEquals($indicator::get_min_value(), $values[$course1->id][0]);
 279  
 280          // General explanation about the points, the max level is 2 so level 1 is -1, level 2 is 1.
 281  
 282          // Page social is level 1 (the lower level).
 283          $this->assertEquals($indicator::get_min_value(), $values[$course2->id][0]);
 284  
 285          // Forum is level 2 and assign is level 2.
 286          $this->assertEquals($indicator::get_max_value(), $values[$course3->id][0]);
 287  
 288          // Page is level 1 and assign is level 2, so potential level is the max one.
 289          $this->assertEquals($indicator::get_max_value(), $values[$course4->id][0]);
 290  
 291          // Calculate using course_modules samples.
 292          $course5 = $this->getDataGenerator()->create_course();
 293          $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course5->id));
 294          $page = $this->getDataGenerator()->create_module('page', array('course' => $course5->id));
 295  
 296          $sampleids = array($assign->cmid => $assign->cmid, $page->cmid => $page->cmid);
 297          $cm1 = $DB->get_record('course_modules', array('id' => $assign->cmid));
 298          $cm2 = $DB->get_record('course_modules', array('id' => $page->cmid));
 299          $data = array(
 300              $cm1->id => array(
 301                  'course' => $course5,
 302                  'course_modules' => $cm1,
 303              ),
 304              $cm2->id => array(
 305                  'course' => $course5,
 306                  'course_modules' => $cm2,
 307              ));
 308          $indicator->clear_sample_data();
 309          $indicator->add_sample_data($data);
 310  
 311          list($values, $ignored) = $indicator->calculate($sampleids, 'course_modules');
 312          // Assign social is level 2 (the max level).
 313          $this->assertEquals($indicator::get_max_value(), $values[$cm1->id][0]);
 314          // Page social is level 1 (the lower level).
 315          $this->assertEquals($indicator::get_min_value(), $values[$cm2->id][0]);
 316      }
 317  
 318      /**
 319       * test_activities_due
 320       *
 321       * @return void
 322       */
 323      public function test_activities_due() {
 324          global $DB;
 325  
 326          $this->resetAfterTest(true);
 327          $this->setAdminuser();
 328  
 329          $course1 = $this->getDataGenerator()->create_course();
 330          $user1 = $this->getDataGenerator()->create_user();
 331          $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
 332  
 333          $target = \core_analytics\manager::get_target('test_target_course_users');
 334          $indicators = array('\core_course\analytics\indicator\activities_due');
 335          foreach ($indicators as $key => $indicator) {
 336              $indicators[$key] = \core_analytics\manager::get_indicator($indicator);
 337          }
 338  
 339          $model = \core_analytics\model::create($target, $indicators);
 340          $model->enable('\core\analytics\time_splitting\single_range');
 341          $model->train();
 342      }
 343  }