[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/mod/quiz/tests/ -> structure_test.php (source)

   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   * Quiz events tests.
  19   *
  20   * @package   mod_quiz
  21   * @category  test
  22   * @copyright 2013 Adrian Greeve
  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($CFG->dirroot . '/mod/quiz/attemptlib.php');
  30  
  31  /**
  32   * Unit tests for quiz events.
  33   *
  34   * @copyright  2013 Adrian Greeve
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class mod_quiz_structure_testcase extends advanced_testcase {
  38  
  39      /**
  40       * Prepare the quiz object with standard data. Ready for testing.
  41       */
  42      protected function prepare_quiz_data() {
  43  
  44          $this->resetAfterTest(true);
  45  
  46          // Create a course.
  47          $course = $this->getDataGenerator()->create_course();
  48  
  49          // Make a quiz.
  50          $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
  51  
  52          $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'questionsperpage' => 0,
  53              'grade' => 100.0, 'sumgrades' => 2));
  54  
  55          $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id);
  56  
  57          return array($quiz, $cm, $course);
  58      }
  59  
  60      /**
  61       * Test getting the quiz slots.
  62       */
  63      public function test_get_quiz_slots() {
  64          // Get basic quiz.
  65          list($quiz, $cm, $course) = $this->prepare_quiz_data();
  66          $quizobj = new quiz($quiz, $cm, $course);
  67          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
  68  
  69          // When no slots exist or slots propery is not set.
  70          $slots = $structure->get_slots();
  71          $this->assertInternalType('array', $slots);
  72          $this->assertCount(0, $slots);
  73  
  74          // Append slots to the quiz.
  75          $this->add_eight_questions_to_the_quiz($quiz);
  76          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
  77  
  78          // Are the correct slots returned?
  79          $slots = $structure->get_slots();
  80          $this->assertCount(8, $slots);
  81      }
  82  
  83      /**
  84       * Test getting the quiz sections.
  85       */
  86      public function test_get_quiz_sections() {
  87          // Get basic quiz.
  88          list($quiz, $cm, $course) = $this->prepare_quiz_data();
  89          $quizobj = new quiz($quiz, $cm, $course);
  90          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
  91  
  92          // Are the correct sections returned?
  93          $sections = $structure->get_quiz_sections();
  94          $this->assertCount(1, $sections);
  95      }
  96  
  97      /**
  98       * Verify that the given layout matches that expected.
  99       * @param array $expectedlayout
 100       * @param \mod_quiz\structure $structure
 101       */
 102      protected function assert_quiz_layout($expectedlayout, \mod_quiz\structure $structure) {
 103          $slotnumber = 0;
 104          foreach ($expectedlayout as $slotid => $page) {
 105              $slotnumber += 1;
 106              $this->assertEquals($slotid, $structure->get_question_in_slot($slotnumber)->slotid,
 107                      'Wrong question in slot ' . $slotnumber);
 108              $this->assertEquals($page, $structure->get_question_in_slot($slotnumber)->page,
 109                      'Wrong page number for slot ' . $slotnumber);
 110          }
 111      }
 112  
 113      /**
 114       * Test moving slots in the quiz.
 115       */
 116      public function test_move_slot() {
 117          // Create a test quiz with 8 questions.
 118          list($quiz, $cm, $course) = $this->prepare_quiz_data();
 119          $this->add_eight_questions_to_the_quiz($quiz);
 120          $quizobj = new quiz($quiz, $cm, $course);
 121          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 122  
 123          // Store the original order of slots, so we can assert what has changed.
 124          $originalslotids = array();
 125          foreach ($structure->get_slots() as $slot) {
 126              $originalslotids[$slot->slot] = $slot->id;
 127          }
 128  
 129          // Don't actually move anything. Check the layout is unchanged.
 130          $idmove = $structure->get_question_in_slot(2)->slotid;
 131          $idbefore = $structure->get_question_in_slot(1)->slotid;
 132          $structure->move_slot($idmove, $idbefore, 2);
 133  
 134          // Having called move, we need to reload $structure.
 135          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 136          $this->assert_quiz_layout(array(
 137                      $originalslotids[1] => 1,
 138                      $originalslotids[2] => 2,
 139                      $originalslotids[3] => 2,
 140                      $originalslotids[4] => 2,
 141                      $originalslotids[5] => 2,
 142                      $originalslotids[6] => 2,
 143                      $originalslotids[7] => 3,
 144                      $originalslotids[8] => 4,
 145                  ), $structure);
 146  
 147          // Slots don't move. Page changed.
 148          $idmove = $structure->get_question_in_slot(2)->slotid;
 149          $idbefore = $structure->get_question_in_slot(1)->slotid;
 150          $structure->move_slot($idmove, $idbefore, 1);
 151  
 152          // Having called move, we need to reload $structure.
 153          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 154          $this->assert_quiz_layout(array(
 155                      $originalslotids[1] => 1,
 156                      $originalslotids[2] => 1,
 157                      $originalslotids[3] => 2,
 158                      $originalslotids[4] => 2,
 159                      $originalslotids[5] => 2,
 160                      $originalslotids[6] => 2,
 161                      $originalslotids[7] => 3,
 162                      $originalslotids[8] => 4,
 163                  ), $structure);
 164  
 165          // Slots move 2 > 3. Page unchanged. Pages not reordered.
 166          $idmove = $structure->get_question_in_slot(2)->slotid;
 167          $idbefore = $structure->get_question_in_slot(3)->slotid;
 168          $structure->move_slot($idmove, $idbefore, '2');
 169  
 170          // Having called move, we need to reload $structure.
 171          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 172          $this->assert_quiz_layout(array(
 173                  $originalslotids[1] => 1,
 174                  $originalslotids[3] => 2,
 175                  $originalslotids[2] => 2,
 176                  $originalslotids[4] => 2,
 177                  $originalslotids[5] => 2,
 178                  $originalslotids[6] => 2,
 179                  $originalslotids[7] => 3,
 180                  $originalslotids[8] => 4,
 181          ), $structure);
 182  
 183          // Slots move 6 > 7. Page changed. Pages not reordered.
 184          $idmove = $structure->get_question_in_slot(6)->slotid;
 185          $idbefore = $structure->get_question_in_slot(7)->slotid;
 186          $structure->move_slot($idmove, $idbefore, '3');
 187  
 188          // Having called move, we need to reload $structure.
 189          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 190          $this->assert_quiz_layout(array(
 191                  $originalslotids[1] => 1,
 192                  $originalslotids[3] => 2,
 193                  $originalslotids[2] => 2,
 194                  $originalslotids[4] => 2,
 195                  $originalslotids[5] => 2,
 196                  $originalslotids[7] => 3,
 197                  $originalslotids[6] => 3,
 198                  $originalslotids[8] => 4,
 199          ), $structure);
 200  
 201          // Page changed slot 6 . Pages not reordered.
 202          $idmove = $structure->get_question_in_slot(6)->slotid;
 203          $idbefore = $structure->get_question_in_slot(5)->slotid;
 204          $structure->move_slot($idmove, $idbefore, 2);
 205  
 206          // Having called move, we need to reload $structure.
 207          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 208          $this->assert_quiz_layout(array(
 209                  $originalslotids[1] => 1,
 210                  $originalslotids[3] => 2,
 211                  $originalslotids[2] => 2,
 212                  $originalslotids[4] => 2,
 213                  $originalslotids[5] => 2,
 214                  $originalslotids[7] => 2,
 215                  $originalslotids[6] => 3,
 216                  $originalslotids[8] => 4,
 217          ), $structure);
 218  
 219          // Slots move 1 > 2. Page changed. Page 2 becomes page 1. Pages reordered.
 220          $idmove = $structure->get_question_in_slot(1)->slotid;
 221          $idbefore = $structure->get_question_in_slot(2)->slotid;
 222          $structure->move_slot($idmove, $idbefore, 2);
 223  
 224          // Having called move, we need to reload $structure.
 225          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 226          $this->assert_quiz_layout(array(
 227                  $originalslotids[3] => 1,
 228                  $originalslotids[1] => 1,
 229                  $originalslotids[2] => 1,
 230                  $originalslotids[4] => 1,
 231                  $originalslotids[5] => 1,
 232                  $originalslotids[7] => 1,
 233                  $originalslotids[6] => 2,
 234                  $originalslotids[8] => 3,
 235          ), $structure);
 236  
 237          // Slots move 7 > 3. Page changed. Page 3 becomes page 2. Pages reordered.
 238          $idmove = $structure->get_question_in_slot(7)->slotid;
 239          $idbefore = $structure->get_question_in_slot(2)->slotid;
 240          $structure->move_slot($idmove, $idbefore, 1);
 241  
 242          // Having called move, we need to reload $structure.
 243          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 244          $this->assert_quiz_layout(array(
 245                  $originalslotids[3] => 1,
 246                  $originalslotids[1] => 1,
 247                  $originalslotids[6] => 1,
 248                  $originalslotids[2] => 1,
 249                  $originalslotids[4] => 1,
 250                  $originalslotids[5] => 1,
 251                  $originalslotids[7] => 1,
 252                  $originalslotids[8] => 2,
 253          ), $structure);
 254  
 255          // Slots move 2 > top. No page changes.
 256          $idmove = $structure->get_question_in_slot(2)->slotid;
 257          $structure->move_slot($idmove, 0, 1);
 258  
 259          // Having called move, we need to reload $structure.
 260          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 261          $this->assert_quiz_layout(array(
 262                  $originalslotids[1] => 1,
 263                  $originalslotids[3] => 1,
 264                  $originalslotids[6] => 1,
 265                  $originalslotids[2] => 1,
 266                  $originalslotids[4] => 1,
 267                  $originalslotids[5] => 1,
 268                  $originalslotids[7] => 1,
 269                  $originalslotids[8] => 2,
 270          ), $structure);
 271      }
 272  
 273      /**
 274       * Test removing slots from a quiz.
 275       */
 276      public function test_quiz_remove_slot() {
 277          global $SITE, $DB;
 278  
 279          $this->resetAfterTest(true);
 280          $this->setAdminUser();
 281  
 282          // Setup a quiz with 1 standard and 1 random question.
 283          $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
 284          $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0));
 285          $cm = get_coursemodule_from_instance('quiz', $quiz->id, $SITE->id);
 286  
 287          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
 288          $cat = $questiongenerator->create_question_category();
 289          $standardq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
 290  
 291          quiz_add_quiz_question($standardq->id, $quiz);
 292          quiz_add_random_questions($quiz, 0, $cat->id, 1, false);
 293  
 294          // Get the random question.
 295          $randomq = $DB->get_record('question', array('qtype' => 'random'));
 296  
 297          $quizobj = new quiz($quiz, $cm, $SITE);
 298          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 299  
 300          // Check that the setup looks right.
 301          $this->assertEquals(2, $structure->get_question_count());
 302          $this->assertEquals($standardq->id, $structure->get_question_in_slot(1)->questionid);
 303          $this->assertEquals($randomq->id, $structure->get_question_in_slot(2)->questionid);
 304  
 305          // Remove the standard question.
 306          $structure->remove_slot($quiz, 1);
 307  
 308          $alteredstructure = \mod_quiz\structure::create_for_quiz($quizobj);
 309  
 310          // Check the new ordering, and that the slot number was updated.
 311          $this->assertEquals(1, $alteredstructure->get_question_count());
 312          $this->assertEquals($randomq->id, $alteredstructure->get_question_in_slot(1)->questionid);
 313  
 314          // Check that the ordinary question was not deleted.
 315          $this->assertTrue($DB->record_exists('question', array('id' => $standardq->id)));
 316  
 317          // Remove the random question.
 318          $structure->remove_slot($quiz, 1);
 319          $alteredstructure = \mod_quiz\structure::create_for_quiz($quizobj);
 320  
 321          // Check that new ordering.
 322          $this->assertEquals(0, $alteredstructure->get_question_count());
 323  
 324          // Check that the random question was deleted.
 325          $this->assertFalse($DB->record_exists('question', array('id' => $randomq->id)));
 326      }
 327  
 328      /**
 329       * Test updating pagebreaks in the quiz.
 330       */
 331      public function test_update_page_break() {
 332          // Create a test quiz with 8 questions.
 333          list($quiz, $cm, $course) = $this->prepare_quiz_data();
 334          $this->add_eight_questions_to_the_quiz($quiz);
 335          $quizobj = new quiz($quiz, $cm, $course);
 336          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 337  
 338          // Store the original order of slots, so we can assert what has changed.
 339          $originalslotids = array();
 340          foreach ($structure->get_slots() as $slot) {
 341              $originalslotids[$slot->slot] = $slot->id;
 342          }
 343  
 344          // Test removing a page break.
 345          $slotid = $structure->get_question_in_slot(2)->slotid;
 346          $type = \mod_quiz\repaginate::LINK;
 347          $slots = $structure->update_page_break($quiz, $slotid, $type);
 348  
 349          // Having called update page break, we need to reload $structure.
 350          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 351          $this->assert_quiz_layout(array(
 352                      $originalslotids[1] => 1,
 353                      $originalslotids[2] => 1,
 354                      $originalslotids[3] => 1,
 355                      $originalslotids[4] => 1,
 356                      $originalslotids[5] => 1,
 357                      $originalslotids[6] => 1,
 358                      $originalslotids[7] => 2,
 359                      $originalslotids[8] => 3,
 360                  ), $structure);
 361  
 362          // Test adding a page break.
 363          $slotid = $structure->get_question_in_slot(2)->slotid;
 364          $type = \mod_quiz\repaginate::UNLINK;
 365          $slots = $structure->update_page_break($quiz, $slotid, $type);
 366  
 367          // Having called update page break, we need to reload $structure.
 368          $structure = \mod_quiz\structure::create_for_quiz($quizobj);
 369          $this->assert_quiz_layout(array(
 370                      $originalslotids[1] => 1,
 371                      $originalslotids[2] => 2,
 372                      $originalslotids[3] => 2,
 373                      $originalslotids[4] => 2,
 374                      $originalslotids[5] => 2,
 375                      $originalslotids[6] => 2,
 376                      $originalslotids[7] => 3,
 377                      $originalslotids[8] => 4,
 378                  ), $structure);
 379      }
 380  
 381      /**
 382       * Populate quiz with eight questions.
 383       * @param stdClass $quiz the quiz to add to.
 384       */
 385      public function add_eight_questions_to_the_quiz($quiz) {
 386          // We add 8 numerical questions with this layout:
 387          // Slot 1 2 3 4 5 6 7 8
 388          // Page 1 2 2 2 2 2 3 4.
 389  
 390          // Create slots.
 391          $pagenumber = 1;
 392          $pagenumberdefaults = array(2, 7, 8);
 393  
 394          // Create a couple of questions.
 395          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
 396  
 397          $cat = $questiongenerator->create_question_category();
 398          for ($i = 0; $i < 8; $i ++) {
 399              $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
 400  
 401              if (in_array($i + 1, $pagenumberdefaults)) {
 402                  $pagenumber++;
 403              }
 404              // Add them to the quiz.
 405              quiz_add_quiz_question($numq->id, $quiz, $pagenumber);
 406          }
 407      }
 408  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1