Commit | Line | Data |
---|---|---|
d900f1dc FM |
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 phpunit | |
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 | require_once($CFG->dirroot . '/mod/quiz/editlib.php'); | |
31 | ||
32 | /** | |
33 | * Unit tests for quiz events. | |
34 | * | |
35 | * @package mod_quiz | |
36 | * @category phpunit | |
37 | * @copyright 2013 Adrian Greeve | |
38 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
39 | */ | |
40 | class mod_quiz_events_testcase extends advanced_testcase { | |
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 | // 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(); | |
70 | $this->setUser($user1); | |
71 | ||
72 | $quizobj = quiz::create($quiz->id, $user1->id); | |
73 | ||
74 | // Start the attempt. | |
75 | $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); | |
76 | $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); | |
77 | ||
78 | $timenow = time(); | |
79 | $attempt = quiz_create_attempt($quizobj, 1, false, $timenow); | |
80 | quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); | |
81 | quiz_attempt_save_started($quizobj, $quba, $attempt); | |
82 | ||
83 | return array($quizobj, $quba, $attempt); | |
84 | } | |
85 | ||
86 | public function test_attempt_submitted() { | |
87 | ||
88 | list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); | |
89 | $attemptobj = quiz_attempt::create($attempt->id); | |
90 | ||
91 | // Catch the event. | |
92 | $sink = $this->redirectEvents(); | |
93 | ||
94 | $timefinish = time(); | |
95 | $attemptobj->process_finish($timefinish, false); | |
96 | $events = $sink->get_events(); | |
97 | $sink->close(); | |
98 | ||
99 | // Validate the event. | |
100 | $this->assertCount(1, $events); | |
101 | $event = $events[0]; | |
102 | $this->assertInstanceOf('\mod_quiz\event\attempt_submitted', $event); | |
103 | $this->assertEquals('quiz_attempts', $event->objecttable); | |
104 | $this->assertEquals($quizobj->get_context(), $event->get_context()); | |
105 | $this->assertEquals($attempt->userid, $event->relateduserid); | |
106 | $this->assertEquals(null, $event->other['submitterid']); // Should be the user, but PHP Unit complains... | |
107 | $this->assertEquals('quiz_attempt_submitted', $event->get_legacy_eventname()); | |
108 | $legacydata = new stdClass(); | |
109 | $legacydata->component = 'mod_quiz'; | |
110 | $legacydata->attemptid = (string) $attempt->id; | |
111 | $legacydata->timestamp = $timefinish; | |
112 | $legacydata->userid = $attempt->userid; | |
113 | $legacydata->cmid = $quizobj->get_cmid(); | |
114 | $legacydata->courseid = $quizobj->get_courseid(); | |
115 | $legacydata->quizid = $quizobj->get_quizid(); | |
116 | // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid. | |
117 | $legacydata->submitterid = null; | |
118 | $legacydata->timefinish = $timefinish; | |
119 | $this->assertEventLegacyData($legacydata, $event); | |
623a32e5 | 120 | $this->assertEventContextNotUsed($event); |
d900f1dc FM |
121 | } |
122 | ||
0a8b091d | 123 | public function test_attempt_becameoverdue() { |
d900f1dc FM |
124 | |
125 | list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); | |
126 | $attemptobj = quiz_attempt::create($attempt->id); | |
127 | ||
128 | // Catch the event. | |
129 | $sink = $this->redirectEvents(); | |
130 | $timefinish = time(); | |
131 | $attemptobj->process_going_overdue($timefinish, false); | |
132 | $events = $sink->get_events(); | |
133 | $sink->close(); | |
134 | ||
135 | $this->assertCount(1, $events); | |
136 | $event = $events[0]; | |
0a8b091d | 137 | $this->assertInstanceOf('\mod_quiz\event\attempt_becameoverdue', $event); |
d900f1dc FM |
138 | $this->assertEquals('quiz_attempts', $event->objecttable); |
139 | $this->assertEquals($quizobj->get_context(), $event->get_context()); | |
140 | $this->assertEquals($attempt->userid, $event->relateduserid); | |
141 | // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid. | |
142 | $this->assertEquals(null, $event->other['submitterid']); | |
143 | $this->assertEquals('quiz_attempt_overdue', $event->get_legacy_eventname()); | |
144 | $legacydata = new stdClass(); | |
145 | $legacydata->component = 'mod_quiz'; | |
146 | $legacydata->attemptid = (string) $attempt->id; | |
147 | $legacydata->timestamp = $timefinish; | |
148 | $legacydata->userid = $attempt->userid; | |
149 | $legacydata->cmid = $quizobj->get_cmid(); | |
150 | $legacydata->courseid = $quizobj->get_courseid(); | |
151 | $legacydata->quizid = $quizobj->get_quizid(); | |
152 | $legacydata->submitterid = null; // Should be the user, but PHP Unit complains... | |
153 | $this->assertEventLegacyData($legacydata, $event); | |
623a32e5 | 154 | $this->assertEventContextNotUsed($event); |
d900f1dc FM |
155 | } |
156 | ||
157 | public function test_attempt_abandoned() { | |
158 | ||
159 | list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); | |
160 | $attemptobj = quiz_attempt::create($attempt->id); | |
161 | ||
162 | // Catch the event. | |
163 | $sink = $this->redirectEvents(); | |
164 | $timefinish = time(); | |
165 | $attemptobj->process_abandon($timefinish, false); | |
166 | $events = $sink->get_events(); | |
167 | $sink->close(); | |
168 | ||
169 | $this->assertCount(1, $events); | |
170 | $event = $events[0]; | |
171 | $this->assertInstanceOf('\mod_quiz\event\attempt_abandoned', $event); | |
172 | $this->assertEquals('quiz_attempts', $event->objecttable); | |
173 | $this->assertEquals($quizobj->get_context(), $event->get_context()); | |
174 | $this->assertEquals($attempt->userid, $event->relateduserid); | |
175 | // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid. | |
176 | $this->assertEquals(null, $event->other['submitterid']); | |
177 | $this->assertEquals('quiz_attempt_abandoned', $event->get_legacy_eventname()); | |
178 | $legacydata = new stdClass(); | |
179 | $legacydata->component = 'mod_quiz'; | |
180 | $legacydata->attemptid = (string) $attempt->id; | |
181 | $legacydata->timestamp = $timefinish; | |
182 | $legacydata->userid = $attempt->userid; | |
183 | $legacydata->cmid = $quizobj->get_cmid(); | |
184 | $legacydata->courseid = $quizobj->get_courseid(); | |
185 | $legacydata->quizid = $quizobj->get_quizid(); | |
186 | $legacydata->submitterid = null; // Should be the user, but PHP Unit complains... | |
187 | $this->assertEventLegacyData($legacydata, $event); | |
623a32e5 | 188 | $this->assertEventContextNotUsed($event); |
d900f1dc FM |
189 | } |
190 | ||
191 | public function test_attempt_started() { | |
192 | global $USER; | |
193 | ||
194 | list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); | |
195 | $attemptobj = quiz_attempt::create($attempt->id); | |
196 | ||
197 | // Catch the event. | |
198 | $sink = $this->redirectEvents(); | |
199 | quiz_fire_attempt_started_event($attempt, $quizobj); | |
200 | $events = $sink->get_events(); | |
201 | $sink->close(); | |
202 | ||
203 | // Legacy event data. | |
204 | $legacydata = new stdClass(); | |
205 | $legacydata->component = 'mod_quiz'; | |
206 | $legacydata->attemptid = $attempt->id; | |
207 | $legacydata->timestart = $attempt->timestart; | |
208 | $legacydata->timestamp = $attempt->timestart; | |
209 | $legacydata->userid = $attempt->userid; | |
210 | $legacydata->quizid = $quizobj->get_quizid(); | |
211 | $legacydata->cmid = $quizobj->get_cmid(); | |
212 | $legacydata->courseid = $quizobj->get_courseid(); | |
213 | ||
214 | // Validate the event. | |
215 | $this->assertCount(1, $events); | |
216 | $event = $events[0]; | |
217 | $this->assertInstanceOf('\mod_quiz\event\attempt_started', $event); | |
218 | $this->assertEquals('quiz_attempts', $event->objecttable); | |
219 | $this->assertEquals($attempt->id, $event->objectid); | |
220 | $this->assertEquals($attempt->userid, $event->relateduserid); | |
221 | $this->assertEquals($quizobj->get_context(), $event->get_context()); | |
222 | $this->assertEquals('quiz_attempt_started', $event->get_legacy_eventname()); | |
223 | $this->assertEventLegacyData($legacydata, $event); | |
623a32e5 | 224 | $this->assertEventContextNotUsed($event); |
d900f1dc | 225 | } |
5e8f7365 MN |
226 | |
227 | /** | |
228 | * Test the edit page viewed event. | |
229 | * | |
230 | * There is no external API for updating a quiz, so the unit test will simply | |
231 | * create and trigger the event and ensure the event data is returned as expected. | |
232 | */ | |
233 | public function test_edit_page_viewed() { | |
234 | $this->resetAfterTest(); | |
235 | ||
236 | $this->setAdminUser(); | |
237 | $course = $this->getDataGenerator()->create_course(); | |
238 | $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); | |
239 | ||
240 | $params = array( | |
241 | 'courseid' => $course->id, | |
242 | 'context' => context_module::instance($quiz->cmid), | |
243 | 'other' => array( | |
244 | 'quizid' => $quiz->id | |
245 | ) | |
246 | ); | |
247 | $event = \mod_quiz\event\edit_page_viewed::create($params); | |
248 | ||
249 | // Trigger and capture the event. | |
250 | $sink = $this->redirectEvents(); | |
251 | $event->trigger(); | |
252 | $events = $sink->get_events(); | |
253 | $event = reset($events); | |
254 | ||
255 | // Check that the event data is valid. | |
256 | $this->assertInstanceOf('\mod_quiz\event\edit_page_viewed', $event); | |
257 | $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); | |
258 | $expected = array($course->id, 'quiz', 'editquestions', 'view.php?id=' . $quiz->cmid, $quiz->id, $quiz->cmid); | |
259 | $this->assertEventLegacyLogData($expected, $event); | |
260 | $this->assertEventContextNotUsed($event); | |
261 | } | |
d900f1dc | 262 | } |