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 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  namespace mod_quiz;
  18  
  19  use mod_quiz\external\submit_question_version;
  20  use mod_quiz\question\bank\qbank_helper;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  
  24  require_once (__DIR__ . '/quiz_question_helper_test_trait.php');
  25  
  26  /**
  27   * Question versions test for quiz.
  28   *
  29   * @package    mod_quiz
  30   * @category   test
  31   * @copyright  2021 Catalyst IT Australia Pty Ltd
  32   * @author     Safat Shahin <safatshahin@catalyst-au.net>
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   * @coversDefaultClass \mod_quiz\question\bank\qbank_helper
  35   */
  36  class quiz_question_version_test extends \advanced_testcase {
  37      use \quiz_question_helper_test_trait;
  38  
  39      /**
  40       * Called before every test.
  41       */
  42      public function setUp(): void {
  43          global $USER;
  44          parent::setUp();
  45          $this->setAdminUser();
  46          $this->course = $this->getDataGenerator()->create_course();
  47          $this->student = $this->getDataGenerator()->create_user();
  48          $this->user = $USER;
  49      }
  50  
  51      /**
  52       * Test the quiz question data for changed version in the slots.
  53       *
  54       * @covers ::get_version_options
  55       */
  56      public function test_quiz_questions_for_changed_versions() {
  57          $this->resetAfterTest();
  58          $quiz = $this->create_test_quiz($this->course);
  59          // Test for questions from a different context.
  60          $context = \context_module::instance(get_coursemodule_from_instance("quiz", $quiz->id, $this->course->id)->id);
  61          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
  62          // Create a couple of questions.
  63          $cat = $questiongenerator->create_question_category(['contextid' => $context->id]);
  64          $numq = $questiongenerator->create_question('essay', null,
  65              ['category' => $cat->id, 'name' => 'This is the first version']);
  66          // Create two version.
  67          $questiongenerator->update_question($numq, null, ['name' => 'This is the second version']);
  68          $questiongenerator->update_question($numq, null, ['name' => 'This is the third version']);
  69          quiz_add_quiz_question($numq->id, $quiz);
  70          // Create the quiz object.
  71          $quizobj = \quiz::create($quiz->id);
  72          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
  73          $slots = $structure->get_slots();
  74          $slot = reset($slots);
  75          // Test that the version added is 'always latest'.
  76          $this->assertEquals(3, $slot->version);
  77          $quizobj->preload_questions();
  78          $quizobj->load_questions();
  79          $questions = $quizobj->get_questions();
  80          $question = reset($questions);
  81          $this->assertEquals(3, $question->version);
  82          $this->assertEquals('This is the third version', $question->name);
  83          // Create another version.
  84          $questiongenerator->update_question($numq, null, ['name' => 'This is the latest version']);
  85          // Check that 'Always latest is working'.
  86          $quizobj->preload_questions();
  87          $quizobj->load_questions();
  88          $questions = $quizobj->get_questions();
  89          $question = reset($questions);
  90          $this->assertEquals(4, $question->version);
  91          $this->assertEquals('This is the latest version', $question->name);
  92          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
  93          $slots = $structure->get_slots();
  94          $slot = reset($slots);
  95          $this->assertEquals(4, $slot->version);
  96          // Now change the version using the external service.
  97          $versions = qbank_helper::get_version_options($slot->questionid);
  98          // We don't want the current version.
  99          $selectversions = [];
 100          foreach ($versions as $version) {
 101              if ($version->version === $slot->version) {
 102                  continue;
 103              }
 104              $selectversions [$version->version] = $version;
 105          }
 106          // Change to version 1.
 107          submit_question_version::execute($slot->id, (int)$selectversions[1]->version);
 108          $quizobj->preload_questions();
 109          $quizobj->load_questions();
 110          $questions = $quizobj->get_questions();
 111          $question = reset($questions);
 112          $this->assertEquals(1, $question->version);
 113          $this->assertEquals('This is the first version', $question->name);
 114          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 115          $slots = $structure->get_slots();
 116          $slot = reset($slots);
 117          $this->assertEquals(1, $slot->version);
 118          // Change to version 2.
 119          submit_question_version::execute($slot->id, $selectversions[2]->version);
 120          $quizobj->preload_questions();
 121          $quizobj->load_questions();
 122          $questions = $quizobj->get_questions();
 123          $question = reset($questions);
 124          $this->assertEquals(2, $question->version);
 125          $this->assertEquals('This is the second version', $question->name);
 126          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 127          $slots = $structure->get_slots();
 128          $slot = reset($slots);
 129          $this->assertEquals(2, $slot->version);
 130      }
 131  
 132      /**
 133       * Test if changing the version of the slot changes the attempts.
 134       *
 135       * @covers ::get_version_options
 136       */
 137      public function test_quiz_question_attempts_with_changed_version() {
 138          $this->resetAfterTest();
 139          $quiz = $this->create_test_quiz($this->course);
 140          // Test for questions from a different context.
 141          $context = \context_module::instance(get_coursemodule_from_instance("quiz", $quiz->id, $this->course->id)->id);
 142          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
 143          // Create a couple of questions.
 144          $cat = $questiongenerator->create_question_category(['contextid' => $context->id]);
 145          $numq = $questiongenerator->create_question('numerical', null,
 146              ['category' => $cat->id, 'name' => 'This is the first version']);
 147          // Create two version.
 148          $questiongenerator->update_question($numq, null, ['name' => 'This is the second version']);
 149          $questiongenerator->update_question($numq, null, ['name' => 'This is the third version']);
 150          quiz_add_quiz_question($numq->id, $quiz);
 151          list($quizobj, $quba, $attemptobj) = $this->attempt_quiz($quiz, $this->student);
 152          $this->assertEquals('This is the third version', $attemptobj->get_question_attempt(1)->get_question()->name);
 153          // Create the quiz object.
 154          $quizobj = \quiz::create($quiz->id);
 155          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 156          $slots = $structure->get_slots();
 157          $slot = reset($slots);
 158          // Now change the version using the external service.
 159          $versions = qbank_helper::get_version_options($slot->questionid);
 160          // We dont want the current version.
 161          $selectversions = [];
 162          foreach ($versions as $version) {
 163              if ($version->version === $slot->version) {
 164                  continue;
 165              }
 166              $selectversions [$version->version] = $version;
 167          }
 168          // Change to version 1.
 169          $this->expectException('moodle_exception');
 170          submit_question_version::execute($slot->id, (int)$selectversions[1]->version);
 171          list($quizobj, $quba, $attemptobj) = $this->attempt_quiz($quiz, $this->student, 2);
 172          $this->assertEquals('This is the first version', $attemptobj->get_question_attempt(1)->get_question()->name);
 173          // Change to version 2.
 174          submit_question_version::execute($slot->id, (int)$selectversions[2]->version);
 175          list($quizobj, $quba, $attemptobj) = $this->attempt_quiz($quiz, $this->student, 3);
 176          $this->assertEquals('This is the second version', $attemptobj->get_question_attempt(1)->get_question()->name);
 177          // Create another version.
 178          $questiongenerator->update_question($numq, null, ['name' => 'This is the latest version']);
 179          // Change to always latest.
 180          submit_question_version::execute($slot->id, 0);
 181          list($quizobj, $quba, $attemptobj) = $this->attempt_quiz($quiz, $this->student, 4);
 182          $this->assertEquals('This is the latest version', $attemptobj->get_question_attempt(1)->get_question()->name);
 183      }
 184  }