Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 400 and 402] [Versions 401 and 402]

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