on-demand release 2.8beta+
[moodle.git] / mod / quiz / tests / attempt_walkthrough_test.php
CommitLineData
2baf8e8a
JP
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 attempt walk through tests.
19 *
20 * @package mod_quiz
21 * @category phpunit
22 * @copyright 2013 The Open University
23 * @author Jamie Pratt <me@jamiep.org>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
2baf8e8a
JP
30require_once($CFG->dirroot . '/mod/quiz/locallib.php');
31
32/**
33 * Quiz attempt walk through.
34 *
35 * @package mod_quiz
36 * @category phpunit
37 * @copyright 2013 The Open University
38 * @author Jamie Pratt <me@jamiep.org>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class mod_quiz_attempt_walkthrough_testcase extends advanced_testcase {
42
43 /**
44 * Create a quiz with questions and walk through a quiz attempt.
45 */
46 public function test_quiz_attempt_walkthrough() {
47 global $SITE;
48
49 $this->resetAfterTest(true);
50
51 // Make a quiz.
52 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
53
54 $quiz = $quizgenerator->create_instance(array('course'=>$SITE->id, 'questionsperpage' => 0, 'grade' => 100.0,
55 'sumgrades' => 2));
56
57 // Create a couple of questions.
58 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
59
60 $cat = $questiongenerator->create_question_category();
61 $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
62 $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
63
64 // Add them to the quiz.
65 quiz_add_quiz_question($saq->id, $quiz);
66 quiz_add_quiz_question($numq->id, $quiz);
67
68 // Make a user to do the quiz.
69 $user1 = $this->getDataGenerator()->create_user();
2baf8e8a
JP
70
71 $quizobj = quiz::create($quiz->id, $user1->id);
72
73 // Start the attempt.
74 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
75 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
76
77 $timenow = time();
70782526 78 $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $user1->id);
2baf8e8a
JP
79
80 quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
ccba5b88 81 $this->assertEquals('1,2,0', $attempt->layout);
2baf8e8a
JP
82
83 quiz_attempt_save_started($quizobj, $quba, $attempt);
84
85 // Process some responses from the student.
86 $attemptobj = quiz_attempt::create($attempt->id);
87 $prefix1 = $quba->get_field_prefix(1);
88 $prefix2 = $quba->get_field_prefix(2);
89
388f0473
JP
90 $tosubmit = array(1 => array('answer' => 'frog'),
91 2 => array('answer' => '3.14'));
2baf8e8a
JP
92
93 $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
94
95 // Finish the attempt.
96 $attemptobj = quiz_attempt::create($attempt->id);
97 $attemptobj->process_finish($timenow, false);
98
99 // Re-load quiz attempt data.
100 $attemptobj = quiz_attempt::create($attempt->id);
101
102 // Check that results are stored as expected.
103 $this->assertEquals(1, $attemptobj->get_attempt_number());
104 $this->assertEquals(2, $attemptobj->get_sum_marks());
105 $this->assertEquals(true, $attemptobj->is_finished());
106 $this->assertEquals($timenow, $attemptobj->get_submitted_date());
107 $this->assertEquals($user1->id, $attemptobj->get_userid());
108
109 // Check quiz grades.
110 $grades = quiz_get_user_grades($quiz, $user1->id);
111 $grade = array_shift($grades);
112 $this->assertEquals(100.0, $grade->rawgrade);
113
114 // Check grade book.
115 $gradebookgrades = grade_get_grades($SITE->id, 'mod', 'quiz', $quiz->id, $user1->id);
116 $gradebookitem = array_shift($gradebookgrades->items);
117 $gradebookgrade = array_shift($gradebookitem->grades);
118 $this->assertEquals(100, $gradebookgrade->grade);
119 }
388f0473
JP
120
121 /**
c2f2e7f0 122 * Create a quiz with a random as well as other questions and walk through quiz attempts.
388f0473
JP
123 */
124 public function test_quiz_with_random_question_attempt_walkthrough() {
125 global $SITE;
126
127 $this->resetAfterTest(true);
128 question_bank::get_qtype('random')->clear_caches_before_testing();
129
130 $this->setAdminUser();
131
132 // Make a quiz.
133 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
134
ccba5b88 135 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 2, 'grade' => 100.0,
388f0473
JP
136 'sumgrades' => 4));
137
138 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
139
140 // Add two questions to question category.
141 $cat = $questiongenerator->create_question_category();
142 $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
143 $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
144
145 // Add random question to the quiz.
146 quiz_add_random_questions($quiz, 0, $cat->id, 1, false);
147
148 // Make another category.
149 $cat2 = $questiongenerator->create_question_category();
150 $match = $questiongenerator->create_question('match', null, array('category' => $cat->id));
151
152 quiz_add_quiz_question($match->id, $quiz, 0);
153
154 $multichoicemulti = $questiongenerator->create_question('multichoice', 'two_of_four', array('category' => $cat->id));
155
156 quiz_add_quiz_question($multichoicemulti->id, $quiz, 0);
157
158 $multichoicesingle = $questiongenerator->create_question('multichoice', 'one_of_four', array('category' => $cat->id));
159
160 quiz_add_quiz_question($multichoicesingle->id, $quiz, 0);
161
c2f2e7f0
JP
162 foreach (array($saq->id => 'frog', $numq->id => '3.14') as $randomqidtoselect => $randqanswer) {
163 // Make a new user to do the quiz each loop.
164 $user1 = $this->getDataGenerator()->create_user();
165 $this->setUser($user1);
388f0473 166
c2f2e7f0 167 $quizobj = quiz::create($quiz->id, $user1->id);
388f0473 168
c2f2e7f0
JP
169 // Start the attempt.
170 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
171 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
388f0473 172
c2f2e7f0
JP
173 $timenow = time();
174 $attempt = quiz_create_attempt($quizobj, 1, false, $timenow);
388f0473 175
c2f2e7f0 176 quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow, array(1 => $randomqidtoselect));
ccba5b88 177 $this->assertEquals('1,2,0,3,4,0', $attempt->layout);
388f0473 178
c2f2e7f0 179 quiz_attempt_save_started($quizobj, $quba, $attempt);
388f0473 180
c2f2e7f0
JP
181 // Process some responses from the student.
182 $attemptobj = quiz_attempt::create($attempt->id);
388f0473 183
c2f2e7f0
JP
184 $tosubmit = array();
185 $selectedquestionid = $quba->get_question_attempt(1)->get_question()->id;
186 $tosubmit[1] = array('answer' => $randqanswer);
187 $tosubmit[2] = array(
49dda8fe
JP
188 'frog' => 'amphibian',
189 'cat' => 'mammal',
190 'newt' => 'amphibian');
191 $tosubmit[3] = array('One' => '1', 'Two' => '0', 'Three' => '1', 'Four' => '0'); // First and third choice.
192 $tosubmit[4] = array('answer' => 'One'); // The first choice.
388f0473 193
c2f2e7f0 194 $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
388f0473 195
c2f2e7f0
JP
196 // Finish the attempt.
197 $attemptobj = quiz_attempt::create($attempt->id);
198 $attemptobj->process_finish($timenow, false);
388f0473 199
c2f2e7f0
JP
200 // Re-load quiz attempt data.
201 $attemptobj = quiz_attempt::create($attempt->id);
388f0473 202
c2f2e7f0
JP
203 // Check that results are stored as expected.
204 $this->assertEquals(1, $attemptobj->get_attempt_number());
205 $this->assertEquals(4, $attemptobj->get_sum_marks());
206 $this->assertEquals(true, $attemptobj->is_finished());
207 $this->assertEquals($timenow, $attemptobj->get_submitted_date());
208 $this->assertEquals($user1->id, $attemptobj->get_userid());
388f0473 209
c2f2e7f0
JP
210 // Check quiz grades.
211 $grades = quiz_get_user_grades($quiz, $user1->id);
212 $grade = array_shift($grades);
213 $this->assertEquals(100.0, $grade->rawgrade);
388f0473 214
c2f2e7f0
JP
215 // Check grade book.
216 $gradebookgrades = grade_get_grades($SITE->id, 'mod', 'quiz', $quiz->id, $user1->id);
217 $gradebookitem = array_shift($gradebookgrades->items);
218 $gradebookgrade = array_shift($gradebookitem->grades);
219 $this->assertEquals(100, $gradebookgrade->grade);
220 }
388f0473 221 }
c2b051c7
JP
222
223
224 public function get_correct_response_for_variants() {
225 return array(array(1, 9.9), array(2, 8.5), array(5, 14.2), array(10, 6.8, true));
226 }
227
228 protected $quizwithvariants = null;
229
230 /**
231 * Create a quiz with a single question with variants and walk through quiz attempts.
232 *
233 * @dataProvider get_correct_response_for_variants
234 */
235 public function test_quiz_with_question_with_variants_attempt_walkthrough($variantno, $correctresponse, $done = false) {
236 global $SITE;
237
238 $this->resetAfterTest($done);
239
240 $this->setAdminUser();
241
242 if ($this->quizwithvariants === null) {
243 // Make a quiz.
244 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
245
246 $this->quizwithvariants = $quizgenerator->create_instance(array('course'=>$SITE->id,
247 'questionsperpage' => 0,
248 'grade' => 100.0,
249 'sumgrades' => 1));
250
251 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
252
253 $cat = $questiongenerator->create_question_category();
254 $calc = $questiongenerator->create_question('calculatedsimple', 'sumwithvariants', array('category' => $cat->id));
255 quiz_add_quiz_question($calc->id, $this->quizwithvariants, 0);
256 }
257
258
259 // Make a new user to do the quiz.
260 $user1 = $this->getDataGenerator()->create_user();
261 $this->setUser($user1);
262 $quizobj = quiz::create($this->quizwithvariants->id, $user1->id);
263
264 // Start the attempt.
265 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
266 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
267
268 $timenow = time();
269 $attempt = quiz_create_attempt($quizobj, 1, false, $timenow);
ccba5b88 270
c2b051c7
JP
271 // Select variant.
272 quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow, array(), array(1 => $variantno));
ccba5b88 273 $this->assertEquals('1,0', $attempt->layout);
c2b051c7
JP
274 quiz_attempt_save_started($quizobj, $quba, $attempt);
275
276 // Process some responses from the student.
277 $attemptobj = quiz_attempt::create($attempt->id);
278 $tosubmit = array(1 => array('answer' => $correctresponse));
279 $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
280
281 // Finish the attempt.
282 $attemptobj = quiz_attempt::create($attempt->id);
283 $attemptobj->process_finish($timenow, false);
284
285 // Re-load quiz attempt data.
286 $attemptobj = quiz_attempt::create($attempt->id);
287
288 // Check that results are stored as expected.
289 $this->assertEquals(1, $attemptobj->get_attempt_number());
290 $this->assertEquals(1, $attemptobj->get_sum_marks());
291 $this->assertEquals(true, $attemptobj->is_finished());
292 $this->assertEquals($timenow, $attemptobj->get_submitted_date());
293 $this->assertEquals($user1->id, $attemptobj->get_userid());
294
295 // Check quiz grades.
296 $grades = quiz_get_user_grades($this->quizwithvariants, $user1->id);
297 $grade = array_shift($grades);
298 $this->assertEquals(100.0, $grade->rawgrade);
299
300 // Check grade book.
301 $gradebookgrades = grade_get_grades($SITE->id, 'mod', 'quiz', $this->quizwithvariants->id, $user1->id);
302 $gradebookitem = array_shift($gradebookgrades->items);
303 $gradebookgrade = array_shift($gradebookitem->grades);
304 $this->assertEquals(100, $gradebookgrade->grade);
305 }
306
2baf8e8a 307}