MDL-45803 mod_quiz: removed usage of the function quiz_fire_attempt_started_event
[moodle.git] / mod / quiz / tests / events_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  * 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  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/mod/quiz/attemptlib.php');
30 require_once($CFG->dirroot . '/mod/quiz/editlib.php');
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 {
42     protected function prepare_quiz_data() {
44         $this->resetAfterTest(true);
46         // Create a course
47         $course = $this->getDataGenerator()->create_course();
49         // Make a quiz.
50         $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
52         $quiz = $quizgenerator->create_instance(array('course'=>$course->id, 'questionsperpage' => 0,
53             'grade' => 100.0, 'sumgrades' => 2));
55         $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id);
57         // Create a couple of questions.
58         $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
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));
64         // Add them to the quiz.
65         quiz_add_quiz_question($saq->id, $quiz);
66         quiz_add_quiz_question($numq->id, $quiz);
68         // Make a user to do the quiz.
69         $user1 = $this->getDataGenerator()->create_user();
70         $this->setUser($user1);
72         $quizobj = quiz::create($quiz->id, $user1->id);
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);
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);
83         return array($quizobj, $quba, $attempt);
84     }
86     public function test_attempt_submitted() {
88         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
89         $attemptobj = quiz_attempt::create($attempt->id);
91         // Catch the event.
92         $sink = $this->redirectEvents();
94         $timefinish = time();
95         $attemptobj->process_finish($timefinish, false);
96         $events = $sink->get_events();
97         $sink->close();
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);
120         $this->assertEventContextNotUsed($event);
121     }
123     public function test_attempt_becameoverdue() {
125         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
126         $attemptobj = quiz_attempt::create($attempt->id);
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();
135         $this->assertCount(1, $events);
136         $event = $events[0];
137         $this->assertInstanceOf('\mod_quiz\event\attempt_becameoverdue', $event);
138         $this->assertEquals('quiz_attempts', $event->objecttable);
139         $this->assertEquals($quizobj->get_context(), $event->get_context());
140         $this->assertEquals($attempt->userid, $event->relateduserid);
141         $this->assertNotEmpty($event->get_description());
142         // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid.
143         $this->assertEquals(null, $event->other['submitterid']);
144         $this->assertEquals('quiz_attempt_overdue', $event->get_legacy_eventname());
145         $legacydata = new stdClass();
146         $legacydata->component = 'mod_quiz';
147         $legacydata->attemptid = (string) $attempt->id;
148         $legacydata->timestamp = $timefinish;
149         $legacydata->userid = $attempt->userid;
150         $legacydata->cmid = $quizobj->get_cmid();
151         $legacydata->courseid = $quizobj->get_courseid();
152         $legacydata->quizid = $quizobj->get_quizid();
153         $legacydata->submitterid = null; // Should be the user, but PHP Unit complains...
154         $this->assertEventLegacyData($legacydata, $event);
155         $this->assertEventContextNotUsed($event);
156     }
158     public function test_attempt_abandoned() {
160         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
161         $attemptobj = quiz_attempt::create($attempt->id);
163         // Catch the event.
164         $sink = $this->redirectEvents();
165         $timefinish = time();
166         $attemptobj->process_abandon($timefinish, false);
167         $events = $sink->get_events();
168         $sink->close();
170         $this->assertCount(1, $events);
171         $event = $events[0];
172         $this->assertInstanceOf('\mod_quiz\event\attempt_abandoned', $event);
173         $this->assertEquals('quiz_attempts', $event->objecttable);
174         $this->assertEquals($quizobj->get_context(), $event->get_context());
175         $this->assertEquals($attempt->userid, $event->relateduserid);
176         // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid.
177         $this->assertEquals(null, $event->other['submitterid']);
178         $this->assertEquals('quiz_attempt_abandoned', $event->get_legacy_eventname());
179         $legacydata = new stdClass();
180         $legacydata->component = 'mod_quiz';
181         $legacydata->attemptid = (string) $attempt->id;
182         $legacydata->timestamp = $timefinish;
183         $legacydata->userid = $attempt->userid;
184         $legacydata->cmid = $quizobj->get_cmid();
185         $legacydata->courseid = $quizobj->get_courseid();
186         $legacydata->quizid = $quizobj->get_quizid();
187         $legacydata->submitterid = null; // Should be the user, but PHP Unit complains...
188         $this->assertEventLegacyData($legacydata, $event);
189         $this->assertEventContextNotUsed($event);
190     }
192     public function test_attempt_started() {
193         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
195         // Create another attempt.
196         $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2);
198         // Trigger and capture the event.
199         $sink = $this->redirectEvents();
200         quiz_attempt_save_started($quizobj, $quba, $attempt);
201         $events = $sink->get_events();
202         $event = reset($events);
204         // Check that the event data is valid.
205         $this->assertInstanceOf('\mod_quiz\event\attempt_started', $event);
206         $this->assertEquals('quiz_attempts', $event->objecttable);
207         $this->assertEquals($attempt->id, $event->objectid);
208         $this->assertEquals($attempt->userid, $event->relateduserid);
209         $this->assertEquals($quizobj->get_context(), $event->get_context());
210         $this->assertEquals('quiz_attempt_started', $event->get_legacy_eventname());
211         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
212         // Check legacy log data.
213         $expected = array($quizobj->get_courseid(), 'quiz', 'attempt', 'review.php?attempt=' . $attempt->id,
214             $quizobj->get_quizid(), $quizobj->get_cmid());
215         $this->assertEventLegacyLogData($expected, $event);
216         // Check legacy event data.
217         $legacydata = new stdClass();
218         $legacydata->component = 'mod_quiz';
219         $legacydata->attemptid = $attempt->id;
220         $legacydata->timestart = $attempt->timestart;
221         $legacydata->timestamp = $attempt->timestart;
222         $legacydata->userid = $attempt->userid;
223         $legacydata->quizid = $quizobj->get_quizid();
224         $legacydata->cmid = $quizobj->get_cmid();
225         $legacydata->courseid = $quizobj->get_courseid();
226         $this->assertEventLegacyData($legacydata, $event);
227         $this->assertEventContextNotUsed($event);
228     }
230     /**
231      * Test the edit page viewed event.
232      *
233      * There is no external API for updating a quiz, so the unit test will simply
234      * create and trigger the event and ensure the event data is returned as expected.
235      */
236     public function test_edit_page_viewed() {
237         $this->resetAfterTest();
239         $this->setAdminUser();
240         $course = $this->getDataGenerator()->create_course();
241         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
243         $params = array(
244             'courseid' => $course->id,
245             'context' => context_module::instance($quiz->cmid),
246             'other' => array(
247                 'quizid' => $quiz->id
248             )
249         );
250         $event = \mod_quiz\event\edit_page_viewed::create($params);
252         // Trigger and capture the event.
253         $sink = $this->redirectEvents();
254         $event->trigger();
255         $events = $sink->get_events();
256         $event = reset($events);
258         // Check that the event data is valid.
259         $this->assertInstanceOf('\mod_quiz\event\edit_page_viewed', $event);
260         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
261         $expected = array($course->id, 'quiz', 'editquestions', 'view.php?id=' . $quiz->cmid, $quiz->id, $quiz->cmid);
262         $this->assertEventLegacyLogData($expected, $event);
263         $this->assertEventContextNotUsed($event);
264     }
266     /**
267      * Test the attempt deleted event.
268      */
269     public function test_attempt_deleted() {
270         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
272         // Trigger and capture the event.
273         $sink = $this->redirectEvents();
274         quiz_delete_attempt($attempt, $quizobj->get_quiz());
275         $events = $sink->get_events();
276         $event = reset($events);
278         // Check that the event data is valid.
279         $this->assertInstanceOf('\mod_quiz\event\attempt_deleted', $event);
280         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
281         $expected = array($quizobj->get_courseid(), 'quiz', 'delete attempt', 'report.php?id=' . $quizobj->get_cmid(),
282             $attempt->id, $quizobj->get_cmid());
283         $this->assertEventLegacyLogData($expected, $event);
284         $this->assertEventContextNotUsed($event);
285     }
287     /**
288      * Test the report viewed event.
289      *
290      * There is no external API for viewing reports, so the unit test will simply
291      * create and trigger the event and ensure the event data is returned as expected.
292      */
293     public function test_report_viewed() {
294         $this->resetAfterTest();
296         $this->setAdminUser();
297         $course = $this->getDataGenerator()->create_course();
298         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
300         $params = array(
301             'context' => $context = context_module::instance($quiz->cmid),
302             'other' => array(
303                 'quizid' => $quiz->id,
304                 'reportname' => 'overview'
305             )
306         );
307         $event = \mod_quiz\event\report_viewed::create($params);
309         // Trigger and capture the event.
310         $sink = $this->redirectEvents();
311         $event->trigger();
312         $events = $sink->get_events();
313         $event = reset($events);
315         // Check that the event data is valid.
316         $this->assertInstanceOf('\mod_quiz\event\report_viewed', $event);
317         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
318         $expected = array($course->id, 'quiz', 'report', 'report.php?id=' . $quiz->cmid . '&mode=overview',
319             $quiz->id, $quiz->cmid);
320         $this->assertEventLegacyLogData($expected, $event);
321         $this->assertEventContextNotUsed($event);
322     }
324     /**
325      * Test the attempt reviewed event.
326      *
327      * There is no external API for reviewing attempts, so the unit test will simply
328      * create and trigger the event and ensure the event data is returned as expected.
329      */
330     public function test_attempt_reviewed() {
331         $this->resetAfterTest();
333         $this->setAdminUser();
334         $course = $this->getDataGenerator()->create_course();
335         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
337         $params = array(
338             'objectid' => 1,
339             'relateduserid' => 2,
340             'courseid' => $course->id,
341             'context' => context_module::instance($quiz->cmid),
342             'other' => array(
343                 'quizid' => $quiz->id
344             )
345         );
346         $event = \mod_quiz\event\attempt_reviewed::create($params);
348         // Trigger and capture the event.
349         $sink = $this->redirectEvents();
350         $event->trigger();
351         $events = $sink->get_events();
352         $event = reset($events);
354         // Check that the event data is valid.
355         $this->assertInstanceOf('\mod_quiz\event\attempt_reviewed', $event);
356         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
357         $expected = array($course->id, 'quiz', 'review', 'review.php?attempt=1', $quiz->id, $quiz->cmid);
358         $this->assertEventLegacyLogData($expected, $event);
359         $this->assertEventContextNotUsed($event);
360     }
362     /**
363      * Test the attempt summary viewed event.
364      *
365      * There is no external API for viewing the attempt summary, so the unit test will simply
366      * create and trigger the event and ensure the event data is returned as expected.
367      */
368     public function test_attempt_summary_viewed() {
369         $this->resetAfterTest();
371         $this->setAdminUser();
372         $course = $this->getDataGenerator()->create_course();
373         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
375         $params = array(
376             'objectid' => 1,
377             'relateduserid' => 2,
378             'courseid' => $course->id,
379             'context' => context_module::instance($quiz->cmid),
380             'other' => array(
381                 'quizid' => $quiz->id
382             )
383         );
384         $event = \mod_quiz\event\attempt_summary_viewed::create($params);
386         // Trigger and capture the event.
387         $sink = $this->redirectEvents();
388         $event->trigger();
389         $events = $sink->get_events();
390         $event = reset($events);
392         // Check that the event data is valid.
393         $this->assertInstanceOf('\mod_quiz\event\attempt_summary_viewed', $event);
394         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
395         $expected = array($course->id, 'quiz', 'view summary', 'summary.php?attempt=1', $quiz->id, $quiz->cmid);
396         $this->assertEventLegacyLogData($expected, $event);
397         $this->assertEventContextNotUsed($event);
398     }
400     /**
401      * Test the user override created event.
402      *
403      * There is no external API for creating a user override, so the unit test will simply
404      * create and trigger the event and ensure the event data is returned as expected.
405      */
406     public function test_user_override_created() {
407         $this->resetAfterTest();
409         $this->setAdminUser();
410         $course = $this->getDataGenerator()->create_course();
411         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
413         $params = array(
414             'objectid' => 1,
415             'relateduserid' => 2,
416             'context' => context_module::instance($quiz->cmid),
417             'other' => array(
418                 'quizid' => $quiz->id
419             )
420         );
421         $event = \mod_quiz\event\user_override_created::create($params);
423         // Trigger and capture the event.
424         $sink = $this->redirectEvents();
425         $event->trigger();
426         $events = $sink->get_events();
427         $event = reset($events);
429         // Check that the event data is valid.
430         $this->assertInstanceOf('\mod_quiz\event\user_override_created', $event);
431         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
432         $this->assertEventContextNotUsed($event);
433     }
435     /**
436      * Test the group override created event.
437      *
438      * There is no external API for creating a group override, so the unit test will simply
439      * create and trigger the event and ensure the event data is returned as expected.
440      */
441     public function test_group_override_created() {
442         $this->resetAfterTest();
444         $this->setAdminUser();
445         $course = $this->getDataGenerator()->create_course();
446         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
448         $params = array(
449             'objectid' => 1,
450             'context' => context_module::instance($quiz->cmid),
451             'other' => array(
452                 'quizid' => $quiz->id,
453                 'groupid' => 2
454             )
455         );
456         $event = \mod_quiz\event\group_override_created::create($params);
458         // Trigger and capture the event.
459         $sink = $this->redirectEvents();
460         $event->trigger();
461         $events = $sink->get_events();
462         $event = reset($events);
464         // Check that the event data is valid.
465         $this->assertInstanceOf('\mod_quiz\event\group_override_created', $event);
466         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
467         $this->assertEventContextNotUsed($event);
468     }
470     /**
471      * Test the user override updated event.
472      *
473      * There is no external API for updating a user override, so the unit test will simply
474      * create and trigger the event and ensure the event data is returned as expected.
475      */
476     public function test_user_override_updated() {
477         $this->resetAfterTest();
479         $this->setAdminUser();
480         $course = $this->getDataGenerator()->create_course();
481         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
483         $params = array(
484             'objectid' => 1,
485             'relateduserid' => 2,
486             'context' => context_module::instance($quiz->cmid),
487             'other' => array(
488                 'quizid' => $quiz->id
489             )
490         );
491         $event = \mod_quiz\event\user_override_updated::create($params);
493         // Trigger and capture the event.
494         $sink = $this->redirectEvents();
495         $event->trigger();
496         $events = $sink->get_events();
497         $event = reset($events);
499         // Check that the event data is valid.
500         $this->assertInstanceOf('\mod_quiz\event\user_override_updated', $event);
501         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
502         $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid);
503         $this->assertEventLegacyLogData($expected, $event);
504         $this->assertEventContextNotUsed($event);
505     }
507     /**
508      * Test the group override updated event.
509      *
510      * There is no external API for updating a group override, so the unit test will simply
511      * create and trigger the event and ensure the event data is returned as expected.
512      */
513     public function test_group_override_updated() {
514         $this->resetAfterTest();
516         $this->setAdminUser();
517         $course = $this->getDataGenerator()->create_course();
518         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
520         $params = array(
521             'objectid' => 1,
522             'context' => context_module::instance($quiz->cmid),
523             'other' => array(
524                 'quizid' => $quiz->id,
525                 'groupid' => 2
526             )
527         );
528         $event = \mod_quiz\event\group_override_updated::create($params);
530         // Trigger and capture the event.
531         $sink = $this->redirectEvents();
532         $event->trigger();
533         $events = $sink->get_events();
534         $event = reset($events);
536         // Check that the event data is valid.
537         $this->assertInstanceOf('\mod_quiz\event\group_override_updated', $event);
538         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
539         $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid);
540         $this->assertEventLegacyLogData($expected, $event);
541         $this->assertEventContextNotUsed($event);
542     }
544     /**
545      * Test the user override deleted event.
546      */
547     public function test_user_override_deleted() {
548         global $DB;
550         $this->resetAfterTest();
552         $this->setAdminUser();
553         $course = $this->getDataGenerator()->create_course();
554         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
556         // Create an override.
557         $override = new stdClass();
558         $override->quiz = $quiz->id;
559         $override->userid = 2;
560         $override->id = $DB->insert_record('quiz_overrides', $override);
562         // Trigger and capture the event.
563         $sink = $this->redirectEvents();
564         quiz_delete_override($quiz, $override->id);
565         $events = $sink->get_events();
566         $event = reset($events);
568         // Check that the event data is valid.
569         $this->assertInstanceOf('\mod_quiz\event\user_override_deleted', $event);
570         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
571         $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid);
572         $this->assertEventLegacyLogData($expected, $event);
573         $this->assertEventContextNotUsed($event);
574     }
576     /**
577      * Test the group override deleted event.
578      */
579     public function test_group_override_deleted() {
580         global $DB;
582         $this->resetAfterTest();
584         $this->setAdminUser();
585         $course = $this->getDataGenerator()->create_course();
586         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
588         // Create an override.
589         $override = new stdClass();
590         $override->quiz = $quiz->id;
591         $override->groupid = 2;
592         $override->id = $DB->insert_record('quiz_overrides', $override);
594         // Trigger and capture the event.
595         $sink = $this->redirectEvents();
596         quiz_delete_override($quiz, $override->id);
597         $events = $sink->get_events();
598         $event = reset($events);
600         // Check that the event data is valid.
601         $this->assertInstanceOf('\mod_quiz\event\group_override_deleted', $event);
602         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
603         $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid);
604         $this->assertEventLegacyLogData($expected, $event);
605         $this->assertEventContextNotUsed($event);
606     }
608     /**
609      * Test the attempt viewed event.
610      *
611      * There is no external API for continuing an attempt, so the unit test will simply
612      * create and trigger the event and ensure the event data is returned as expected.
613      */
614     public function test_attempt_viewed() {
615         $this->resetAfterTest();
617         $this->setAdminUser();
618         $course = $this->getDataGenerator()->create_course();
619         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
621         $params = array(
622             'objectid' => 1,
623             'relateduserid' => 2,
624             'courseid' => $course->id,
625             'context' => context_module::instance($quiz->cmid),
626             'other' => array(
627                 'quizid' => $quiz->id
628             )
629         );
630         $event = \mod_quiz\event\attempt_viewed::create($params);
632         // Trigger and capture the event.
633         $sink = $this->redirectEvents();
634         $event->trigger();
635         $events = $sink->get_events();
636         $event = reset($events);
638         // Check that the event data is valid.
639         $this->assertInstanceOf('\mod_quiz\event\attempt_viewed', $event);
640         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
641         $expected = array($course->id, 'quiz', 'continue attempt', 'review.php?attempt=1', $quiz->id, $quiz->cmid);
642         $this->assertEventLegacyLogData($expected, $event);
643         $this->assertEventContextNotUsed($event);
644     }
646     /**
647      * Test the attempt previewed event.
648      */
649     public function test_attempt_preview_started() {
650         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
652         // We want to preview this attempt.
653         $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2);
654         $attempt->preview = 1;
656         // Trigger and capture the event.
657         $sink = $this->redirectEvents();
658         quiz_attempt_save_started($quizobj, $quba, $attempt);
659         $events = $sink->get_events();
660         $event = reset($events);
662         // Check that the event data is valid.
663         $this->assertInstanceOf('\mod_quiz\event\attempt_preview_started', $event);
664         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
665         $expected = array($quizobj->get_courseid(), 'quiz', 'preview', 'view.php?id=' . $quizobj->get_cmid(),
666             $quizobj->get_quizid(), $quizobj->get_cmid());
667         $this->assertEventLegacyLogData($expected, $event);
668         $this->assertEventContextNotUsed($event);
669     }
671     /**
672      * Test the question manually graded event.
673      *
674      * There is no external API for manually grading a question, so the unit test will simply
675      * create and trigger the event and ensure the event data is returned as expected.
676      */
677     public function test_question_manually_graded() {
678         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
680         $params = array(
681             'objectid' => 1,
682             'courseid' => $quizobj->get_courseid(),
683             'context' => context_module::instance($quizobj->get_cmid()),
684             'other' => array(
685                 'quizid' => $quizobj->get_quizid(),
686                 'attemptid' => 2,
687                 'slot' => 3
688             )
689         );
690         $event = \mod_quiz\event\question_manually_graded::create($params);
692         // Trigger and capture the event.
693         $sink = $this->redirectEvents();
694         $event->trigger();
695         $events = $sink->get_events();
696         $event = reset($events);
698         // Check that the event data is valid.
699         $this->assertInstanceOf('\mod_quiz\event\question_manually_graded', $event);
700         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
701         $expected = array($quizobj->get_courseid(), 'quiz', 'manualgrade', 'comment.php?attempt=2&slot=3',
702             $quizobj->get_quizid(), $quizobj->get_cmid());
703         $this->assertEventLegacyLogData($expected, $event);
704         $this->assertEventContextNotUsed($event);
705     }