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] [Versions 401 and 402] [Versions 401 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 the {@link \mod_quiz\repaginate} class.
  19   * @package   mod_quiz
  20   * @category  test
  21   * @copyright 2014 The Open Univsersity
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_quiz;
  26  
  27  use quiz;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  global $CFG;
  32  require_once($CFG->dirroot . '/mod/quiz/locallib.php');
  33  require_once($CFG->dirroot . '/mod/quiz/classes/repaginate.php');
  34  
  35  /**
  36   * Testable subclass, giving access to the protected methods of {@link \mod_quiz\repaginate}
  37   * @copyright 2014 The Open Univsersity
  38   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class mod_quiz_repaginate_testable extends repaginate {
  41  
  42      public function __construct($quizid = 0, $slots = null) {
  43          return parent::__construct($quizid, $slots);
  44      }
  45      public function get_this_slot($slots, $slotnumber) {
  46          return parent::get_this_slot($slots, $slotnumber);
  47      }
  48      public function get_slots_by_slotid($slots = null) {
  49          return parent::get_slots_by_slotid($slots);
  50      }
  51      public function get_slots_by_slot_number($slots = null) {
  52          return parent::get_slots_by_slot_number($slots);
  53      }
  54      public function repaginate_this_slot($slot, $newpagenumber) {
  55          return parent::repaginate_this_slot($slot, $newpagenumber);
  56      }
  57      public function repaginate_next_slot($nextslotnumber, $type) {
  58          return parent::repaginate_next_slot($nextslotnumber, $type);
  59      }
  60  }
  61  
  62  /**
  63   * Test for some parts of the repaginate class.
  64   * @copyright 2014 The Open University
  65   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  66   */
  67  class repaginate_test extends \advanced_testcase {
  68  
  69      /** @var array stores the slots. */
  70      private $quizslots;
  71      /** @var mod_quiz_repaginate_testable the object being tested. */
  72      private $repaginate = null;
  73  
  74      public function setUp(): void {
  75          $this->set_quiz_slots($this->get_quiz_object()->get_slots());
  76          $this->repaginate = new mod_quiz_repaginate_testable(0, $this->quizslots);
  77      }
  78  
  79      public function tearDown(): void {
  80          $this->repaginate = null;
  81      }
  82  
  83      /**
  84       * Create a quiz, add five questions to the quiz
  85       * which are all on one page and return the quiz object.
  86       */
  87      private function get_quiz_object() {
  88          global $SITE;
  89          $this->resetAfterTest(true);
  90  
  91          // Make a quiz.
  92          $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
  93  
  94          $quiz = $quizgenerator->create_instance(array(
  95                  'course' => $SITE->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2));
  96          $cm = get_coursemodule_from_instance('quiz', $quiz->id, $SITE->id);
  97  
  98          // Create five questions.
  99          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
 100          $cat = $questiongenerator->create_question_category();
 101  
 102          $shortanswer = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
 103          $numerical = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
 104          $essay = $questiongenerator->create_question('essay', null, array('category' => $cat->id));
 105          $truefalse = $questiongenerator->create_question('truefalse', null, array('category' => $cat->id));
 106          $match = $questiongenerator->create_question('match', null, array('category' => $cat->id));
 107  
 108          // Add them to the quiz.
 109          quiz_add_quiz_question($shortanswer->id, $quiz);
 110          quiz_add_quiz_question($numerical->id, $quiz);
 111          quiz_add_quiz_question($essay->id, $quiz);
 112          quiz_add_quiz_question($truefalse->id, $quiz);
 113          quiz_add_quiz_question($match->id, $quiz);
 114  
 115          // Return the quiz object.
 116          $quizobj = new quiz($quiz, $cm, $SITE);
 117          return structure::create_for_quiz($quizobj);
 118      }
 119  
 120      /**
 121       * Set the quiz slots
 122       * @param string $slots
 123       */
 124      private function set_quiz_slots($slots = null) {
 125          if (!$slots) {
 126              $this->quizslots = $this->get_quiz_object()->get_slots();
 127          } else {
 128              $this->quizslots = $slots;
 129          }
 130      }
 131  
 132      /**
 133       * Test the get_this_slot() method
 134       */
 135      public function test_get_this_slot() {
 136          $this->set_quiz_slots();
 137          $actual = array();
 138          $expected = $this->repaginate->get_slots_by_slot_number();
 139          $this->assertEquals($expected, $actual);
 140  
 141          $slotsbyno = $this->repaginate->get_slots_by_slot_number($this->quizslots);
 142          $slotnumber = 5;
 143          $thisslot = $this->repaginate->get_this_slot($this->quizslots, $slotnumber);
 144          $this->assertEquals($slotsbyno[$slotnumber], $thisslot);
 145      }
 146  
 147      public function test_get_slots_by_slotnumber() {
 148          $this->set_quiz_slots();
 149          $expected = array();
 150          $actual = $this->repaginate->get_slots_by_slot_number();
 151          $this->assertEquals($expected, $actual);
 152  
 153          foreach ($this->quizslots as $slot) {
 154              $expected[$slot->slot] = $slot;
 155          }
 156          $actual = $this->repaginate->get_slots_by_slot_number($this->quizslots);
 157          $this->assertEquals($expected, $actual);
 158      }
 159  
 160      public function test_get_slots_by_slotid() {
 161          $this->set_quiz_slots();
 162          $actual = $this->repaginate->get_slots_by_slotid();
 163          $this->assertEquals(array(), $actual);
 164  
 165          $slotsbyno = $this->repaginate->get_slots_by_slot_number($this->quizslots);
 166          $actual = $this->repaginate->get_slots_by_slotid($slotsbyno);
 167          $this->assertEquals($this->quizslots, $actual);
 168      }
 169  
 170      public function test_repaginate_n_questions_per_page() {
 171          $this->set_quiz_slots();
 172  
 173          // Expect 2 questions per page.
 174          $expected = array();
 175          foreach ($this->quizslots as $slot) {
 176              // Page 1 contains Slots 1 and 2.
 177              if ($slot->slot >= 1 && $slot->slot <= 2) {
 178                  $slot->page = 1;
 179              }
 180              // Page 2 contains slots 3 and 4.
 181              if ($slot->slot >= 3 && $slot->slot <= 4) {
 182                  $slot->page = 2;
 183              }
 184              // Page 3 contains slots 5.
 185              if ($slot->slot >= 5 && $slot->slot <= 6) {
 186                  $slot->page = 3;
 187              }
 188              $expected[$slot->id] = $slot;
 189          }
 190          $actual = $this->repaginate->repaginate_n_question_per_page($this->quizslots, 2);
 191          $this->assertEquals($expected, $actual);
 192  
 193          // Expect 3 questions per page.
 194          $expected = array();
 195          foreach ($this->quizslots as $slot) {
 196              // Page 1 contains Slots 1, 2 and 3.
 197              if ($slot->slot >= 1 && $slot->slot <= 3) {
 198                  $slot->page = 1;
 199              }
 200              // Page 2 contains slots 4 and 5.
 201              if ($slot->slot >= 4 && $slot->slot <= 6) {
 202                  $slot->page = 2;
 203              }
 204              $expected[$slot->id] = $slot;
 205          }
 206          $actual = $this->repaginate->repaginate_n_question_per_page($this->quizslots, 3);
 207          $this->assertEquals($expected, $actual);
 208  
 209          // Expect 5 questions per page.
 210          $expected = array();
 211          foreach ($this->quizslots as $slot) {
 212              // Page 1 contains Slots 1, 2, 3, 4 and 5.
 213              if ($slot->slot > 0 && $slot->slot < 6) {
 214                  $slot->page = 1;
 215              }
 216              // Page 2 contains slots 6, 7, 8, 9 and 10.
 217              if ($slot->slot > 5 && $slot->slot < 11) {
 218                  $slot->page = 2;
 219              }
 220              $expected[$slot->id] = $slot;
 221          }
 222          $actual = $this->repaginate->repaginate_n_question_per_page($this->quizslots, 5);
 223          $this->assertEquals($expected, $actual);
 224  
 225          // Expect 10 questions per page.
 226          $expected = array();
 227          foreach ($this->quizslots as $slot) {
 228              // Page 1 contains Slots 1 to 10.
 229              if ($slot->slot >= 1 && $slot->slot <= 10) {
 230                  $slot->page = 1;
 231              }
 232              // Page 2 contains slots 11 to 20.
 233              if ($slot->slot >= 11 && $slot->slot <= 20) {
 234                  $slot->page = 2;
 235              }
 236              $expected[$slot->id] = $slot;
 237          }
 238          $actual = $this->repaginate->repaginate_n_question_per_page($this->quizslots, 10);
 239          $this->assertEquals($expected, $actual);
 240  
 241          // Expect 1 questions per page.
 242          $expected = array();
 243          $page = 1;
 244          foreach ($this->quizslots as $slot) {
 245              $slot->page = $page++;
 246              $expected[$slot->id] = $slot;
 247          }
 248          $actual = $this->repaginate->repaginate_n_question_per_page($this->quizslots, 1);
 249          $this->assertEquals($expected, $actual);
 250      }
 251  
 252      public function test_repaginate_this_slot() {
 253          $this->set_quiz_slots();
 254          $slotsbyslotno = $this->repaginate->get_slots_by_slot_number($this->quizslots);
 255          $slotnumber = 3;
 256          $newpagenumber = 2;
 257          $thisslot = $slotsbyslotno[3];
 258          $thisslot->page = $newpagenumber;
 259          $expected = $thisslot;
 260          $actual = $this->repaginate->repaginate_this_slot($slotsbyslotno[3], $newpagenumber);
 261          $this->assertEquals($expected, $actual);
 262      }
 263  
 264      public function test_repaginate_the_rest() {
 265          $this->set_quiz_slots();
 266          $slotfrom = 1;
 267          $type = repaginate::LINK;
 268          $expected = array();
 269          foreach ($this->quizslots as $slot) {
 270              if ($slot->slot > $slotfrom) {
 271                  $slot->page = $slot->page - 1;
 272                  $expected[$slot->id] = $slot;
 273              }
 274          }
 275          $actual = $this->repaginate->repaginate_the_rest($this->quizslots, $slotfrom, $type, false);
 276          $this->assertEquals($expected, $actual);
 277  
 278          $slotfrom = 2;
 279          $newslots = array();
 280          foreach ($this->quizslots as $s) {
 281              if ($s->slot === $slotfrom) {
 282                  $s->page = $s->page - 1;
 283              }
 284              $newslots[$s->id] = $s;
 285          }
 286  
 287          $type = repaginate::UNLINK;
 288          $expected = array();
 289          foreach ($this->quizslots as $slot) {
 290              if ($slot->slot > ($slotfrom - 1)) {
 291                  $slot->page = $slot->page - 1;
 292                  $expected[$slot->id] = $slot;
 293              }
 294          }
 295          $actual = $this->repaginate->repaginate_the_rest($newslots, $slotfrom, $type, false);
 296          $this->assertEquals($expected, $actual);
 297      }
 298  
 299  }