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