MDL-40063 mod_quiz: replaced 'editquestions' add_to_log call with an event
[moodle.git] / mod / quiz / tests / events_test.php
CommitLineData
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
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->dirroot . '/mod/quiz/attemptlib.php');
30require_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 */
40class 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}