MDL-65883 mod_quiz: replace all hardcoded urls to proper params
[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');
31 /**
32  * Unit tests for quiz events.
33  *
34  * @package    mod_quiz
35  * @category   phpunit
36  * @copyright  2013 Adrian Greeve
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class mod_quiz_events_testcase extends advanced_testcase {
41     /**
42      * Setup some convenience test data with a single attempt.
43      *
44      * @param bool $ispreview Make the attempt a preview attempt when true.
45      */
46     protected function prepare_quiz_data($ispreview = false) {
48         $this->resetAfterTest(true);
50         // Create a course
51         $course = $this->getDataGenerator()->create_course();
53         // Make a quiz.
54         $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
56         $quiz = $quizgenerator->create_instance(array('course'=>$course->id, 'questionsperpage' => 0,
57             'grade' => 100.0, 'sumgrades' => 2));
59         $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id);
61         // Create a couple of questions.
62         $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
64         $cat = $questiongenerator->create_question_category();
65         $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
66         $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
68         // Add them to the quiz.
69         quiz_add_quiz_question($saq->id, $quiz);
70         quiz_add_quiz_question($numq->id, $quiz);
72         // Make a user to do the quiz.
73         $user1 = $this->getDataGenerator()->create_user();
74         $this->setUser($user1);
76         $quizobj = quiz::create($quiz->id, $user1->id);
78         // Start the attempt.
79         $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
80         $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
82         $timenow = time();
83         $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, $ispreview);
84         quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
85         quiz_attempt_save_started($quizobj, $quba, $attempt);
87         return array($quizobj, $quba, $attempt);
88     }
90     public function test_attempt_submitted() {
92         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
93         $attemptobj = quiz_attempt::create($attempt->id);
95         // Catch the event.
96         $sink = $this->redirectEvents();
98         $timefinish = time();
99         $attemptobj->process_finish($timefinish, false);
100         $events = $sink->get_events();
101         $sink->close();
103         // Validate the event.
104         $this->assertCount(3, $events);
105         $event = $events[2];
106         $this->assertInstanceOf('\mod_quiz\event\attempt_submitted', $event);
107         $this->assertEquals('quiz_attempts', $event->objecttable);
108         $this->assertEquals($quizobj->get_context(), $event->get_context());
109         $this->assertEquals($attempt->userid, $event->relateduserid);
110         $this->assertEquals(null, $event->other['submitterid']); // Should be the user, but PHP Unit complains...
111         $this->assertEquals('quiz_attempt_submitted', $event->get_legacy_eventname());
112         $legacydata = new stdClass();
113         $legacydata->component = 'mod_quiz';
114         $legacydata->attemptid = (string) $attempt->id;
115         $legacydata->timestamp = $timefinish;
116         $legacydata->userid = $attempt->userid;
117         $legacydata->cmid = $quizobj->get_cmid();
118         $legacydata->courseid = $quizobj->get_courseid();
119         $legacydata->quizid = $quizobj->get_quizid();
120         // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid.
121         $legacydata->submitterid = null;
122         $legacydata->timefinish = $timefinish;
123         $this->assertEventLegacyData($legacydata, $event);
124         $this->assertEventContextNotUsed($event);
125     }
127     public function test_attempt_becameoverdue() {
129         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
130         $attemptobj = quiz_attempt::create($attempt->id);
132         // Catch the event.
133         $sink = $this->redirectEvents();
134         $timefinish = time();
135         $attemptobj->process_going_overdue($timefinish, false);
136         $events = $sink->get_events();
137         $sink->close();
139         $this->assertCount(1, $events);
140         $event = $events[0];
141         $this->assertInstanceOf('\mod_quiz\event\attempt_becameoverdue', $event);
142         $this->assertEquals('quiz_attempts', $event->objecttable);
143         $this->assertEquals($quizobj->get_context(), $event->get_context());
144         $this->assertEquals($attempt->userid, $event->relateduserid);
145         $this->assertNotEmpty($event->get_description());
146         // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid.
147         $this->assertEquals(null, $event->other['submitterid']);
148         $this->assertEquals('quiz_attempt_overdue', $event->get_legacy_eventname());
149         $legacydata = new stdClass();
150         $legacydata->component = 'mod_quiz';
151         $legacydata->attemptid = (string) $attempt->id;
152         $legacydata->timestamp = $timefinish;
153         $legacydata->userid = $attempt->userid;
154         $legacydata->cmid = $quizobj->get_cmid();
155         $legacydata->courseid = $quizobj->get_courseid();
156         $legacydata->quizid = $quizobj->get_quizid();
157         $legacydata->submitterid = null; // Should be the user, but PHP Unit complains...
158         $this->assertEventLegacyData($legacydata, $event);
159         $this->assertEventContextNotUsed($event);
160     }
162     public function test_attempt_abandoned() {
164         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
165         $attemptobj = quiz_attempt::create($attempt->id);
167         // Catch the event.
168         $sink = $this->redirectEvents();
169         $timefinish = time();
170         $attemptobj->process_abandon($timefinish, false);
171         $events = $sink->get_events();
172         $sink->close();
174         $this->assertCount(1, $events);
175         $event = $events[0];
176         $this->assertInstanceOf('\mod_quiz\event\attempt_abandoned', $event);
177         $this->assertEquals('quiz_attempts', $event->objecttable);
178         $this->assertEquals($quizobj->get_context(), $event->get_context());
179         $this->assertEquals($attempt->userid, $event->relateduserid);
180         // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid.
181         $this->assertEquals(null, $event->other['submitterid']);
182         $this->assertEquals('quiz_attempt_abandoned', $event->get_legacy_eventname());
183         $legacydata = new stdClass();
184         $legacydata->component = 'mod_quiz';
185         $legacydata->attemptid = (string) $attempt->id;
186         $legacydata->timestamp = $timefinish;
187         $legacydata->userid = $attempt->userid;
188         $legacydata->cmid = $quizobj->get_cmid();
189         $legacydata->courseid = $quizobj->get_courseid();
190         $legacydata->quizid = $quizobj->get_quizid();
191         $legacydata->submitterid = null; // Should be the user, but PHP Unit complains...
192         $this->assertEventLegacyData($legacydata, $event);
193         $this->assertEventContextNotUsed($event);
194     }
196     public function test_attempt_started() {
197         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
199         // Create another attempt.
200         $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2);
202         // Trigger and capture the event.
203         $sink = $this->redirectEvents();
204         quiz_attempt_save_started($quizobj, $quba, $attempt);
205         $events = $sink->get_events();
206         $event = reset($events);
208         // Check that the event data is valid.
209         $this->assertInstanceOf('\mod_quiz\event\attempt_started', $event);
210         $this->assertEquals('quiz_attempts', $event->objecttable);
211         $this->assertEquals($attempt->id, $event->objectid);
212         $this->assertEquals($attempt->userid, $event->relateduserid);
213         $this->assertEquals($quizobj->get_context(), $event->get_context());
214         $this->assertEquals('quiz_attempt_started', $event->get_legacy_eventname());
215         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
216         // Check legacy log data.
217         $expected = array($quizobj->get_courseid(), 'quiz', 'attempt', 'review.php?attempt=' . $attempt->id,
218             $quizobj->get_quizid(), $quizobj->get_cmid());
219         $this->assertEventLegacyLogData($expected, $event);
220         // Check legacy event data.
221         $legacydata = new stdClass();
222         $legacydata->component = 'mod_quiz';
223         $legacydata->attemptid = $attempt->id;
224         $legacydata->timestart = $attempt->timestart;
225         $legacydata->timestamp = $attempt->timestart;
226         $legacydata->userid = $attempt->userid;
227         $legacydata->quizid = $quizobj->get_quizid();
228         $legacydata->cmid = $quizobj->get_cmid();
229         $legacydata->courseid = $quizobj->get_courseid();
230         $this->assertEventLegacyData($legacydata, $event);
231         $this->assertEventContextNotUsed($event);
232     }
234     /**
235      * Test the edit page viewed event.
236      *
237      * There is no external API for updating a quiz, so the unit test will simply
238      * create and trigger the event and ensure the event data is returned as expected.
239      */
240     public function test_edit_page_viewed() {
241         $this->resetAfterTest();
243         $this->setAdminUser();
244         $course = $this->getDataGenerator()->create_course();
245         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
247         $params = array(
248             'courseid' => $course->id,
249             'context' => context_module::instance($quiz->cmid),
250             'other' => array(
251                 'quizid' => $quiz->id
252             )
253         );
254         $event = \mod_quiz\event\edit_page_viewed::create($params);
256         // Trigger and capture the event.
257         $sink = $this->redirectEvents();
258         $event->trigger();
259         $events = $sink->get_events();
260         $event = reset($events);
262         // Check that the event data is valid.
263         $this->assertInstanceOf('\mod_quiz\event\edit_page_viewed', $event);
264         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
265         $expected = array($course->id, 'quiz', 'editquestions', 'view.php?id=' . $quiz->cmid, $quiz->id, $quiz->cmid);
266         $this->assertEventLegacyLogData($expected, $event);
267         $this->assertEventContextNotUsed($event);
268     }
270     /**
271      * Test the attempt deleted event.
272      */
273     public function test_attempt_deleted() {
274         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
276         // Trigger and capture the event.
277         $sink = $this->redirectEvents();
278         quiz_delete_attempt($attempt, $quizobj->get_quiz());
279         $events = $sink->get_events();
280         $event = reset($events);
282         // Check that the event data is valid.
283         $this->assertInstanceOf('\mod_quiz\event\attempt_deleted', $event);
284         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
285         $expected = array($quizobj->get_courseid(), 'quiz', 'delete attempt', 'report.php?id=' . $quizobj->get_cmid(),
286             $attempt->id, $quizobj->get_cmid());
287         $this->assertEventLegacyLogData($expected, $event);
288         $this->assertEventContextNotUsed($event);
289     }
291     /**
292      * Test that preview attempt deletions are not logged.
293      */
294     public function test_preview_attempt_deleted() {
295         // Create quiz with preview attempt.
296         list($quizobj, $quba, $previewattempt) = $this->prepare_quiz_data(true);
298         // Delete a preview attempt, capturing events.
299         $sink = $this->redirectEvents();
300         quiz_delete_attempt($previewattempt, $quizobj->get_quiz());
302         // Verify that no events were generated.
303         $this->assertEmpty($sink->get_events());
304     }
306     /**
307      * Test the report viewed event.
308      *
309      * There is no external API for viewing reports, so the unit test will simply
310      * create and trigger the event and ensure the event data is returned as expected.
311      */
312     public function test_report_viewed() {
313         $this->resetAfterTest();
315         $this->setAdminUser();
316         $course = $this->getDataGenerator()->create_course();
317         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
319         $params = array(
320             'context' => $context = context_module::instance($quiz->cmid),
321             'other' => array(
322                 'quizid' => $quiz->id,
323                 'reportname' => 'overview'
324             )
325         );
326         $event = \mod_quiz\event\report_viewed::create($params);
328         // Trigger and capture the event.
329         $sink = $this->redirectEvents();
330         $event->trigger();
331         $events = $sink->get_events();
332         $event = reset($events);
334         // Check that the event data is valid.
335         $this->assertInstanceOf('\mod_quiz\event\report_viewed', $event);
336         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
337         $expected = array($course->id, 'quiz', 'report', 'report.php?id=' . $quiz->cmid . '&mode=overview',
338             $quiz->id, $quiz->cmid);
339         $this->assertEventLegacyLogData($expected, $event);
340         $this->assertEventContextNotUsed($event);
341     }
343     /**
344      * Test the attempt reviewed event.
345      *
346      * There is no external API for reviewing attempts, so the unit test will simply
347      * create and trigger the event and ensure the event data is returned as expected.
348      */
349     public function test_attempt_reviewed() {
350         $this->resetAfterTest();
352         $this->setAdminUser();
353         $course = $this->getDataGenerator()->create_course();
354         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
356         $params = array(
357             'objectid' => 1,
358             'relateduserid' => 2,
359             'courseid' => $course->id,
360             'context' => context_module::instance($quiz->cmid),
361             'other' => array(
362                 'quizid' => $quiz->id
363             )
364         );
365         $event = \mod_quiz\event\attempt_reviewed::create($params);
367         // Trigger and capture the event.
368         $sink = $this->redirectEvents();
369         $event->trigger();
370         $events = $sink->get_events();
371         $event = reset($events);
373         // Check that the event data is valid.
374         $this->assertInstanceOf('\mod_quiz\event\attempt_reviewed', $event);
375         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
376         $expected = array($course->id, 'quiz', 'review', 'review.php?attempt=1', $quiz->id, $quiz->cmid);
377         $this->assertEventLegacyLogData($expected, $event);
378         $this->assertEventContextNotUsed($event);
379     }
381     /**
382      * Test the attempt summary viewed event.
383      *
384      * There is no external API for viewing the attempt summary, so the unit test will simply
385      * create and trigger the event and ensure the event data is returned as expected.
386      */
387     public function test_attempt_summary_viewed() {
388         $this->resetAfterTest();
390         $this->setAdminUser();
391         $course = $this->getDataGenerator()->create_course();
392         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
394         $params = array(
395             'objectid' => 1,
396             'relateduserid' => 2,
397             'courseid' => $course->id,
398             'context' => context_module::instance($quiz->cmid),
399             'other' => array(
400                 'quizid' => $quiz->id
401             )
402         );
403         $event = \mod_quiz\event\attempt_summary_viewed::create($params);
405         // Trigger and capture the event.
406         $sink = $this->redirectEvents();
407         $event->trigger();
408         $events = $sink->get_events();
409         $event = reset($events);
411         // Check that the event data is valid.
412         $this->assertInstanceOf('\mod_quiz\event\attempt_summary_viewed', $event);
413         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
414         $expected = array($course->id, 'quiz', 'view summary', 'summary.php?attempt=1', $quiz->id, $quiz->cmid);
415         $this->assertEventLegacyLogData($expected, $event);
416         $this->assertEventContextNotUsed($event);
417     }
419     /**
420      * Test the user override created event.
421      *
422      * There is no external API for creating a user override, so the unit test will simply
423      * create and trigger the event and ensure the event data is returned as expected.
424      */
425     public function test_user_override_created() {
426         $this->resetAfterTest();
428         $this->setAdminUser();
429         $course = $this->getDataGenerator()->create_course();
430         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
432         $params = array(
433             'objectid' => 1,
434             'relateduserid' => 2,
435             'context' => context_module::instance($quiz->cmid),
436             'other' => array(
437                 'quizid' => $quiz->id
438             )
439         );
440         $event = \mod_quiz\event\user_override_created::create($params);
442         // Trigger and capture the event.
443         $sink = $this->redirectEvents();
444         $event->trigger();
445         $events = $sink->get_events();
446         $event = reset($events);
448         // Check that the event data is valid.
449         $this->assertInstanceOf('\mod_quiz\event\user_override_created', $event);
450         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
451         $this->assertEventContextNotUsed($event);
452     }
454     /**
455      * Test the group override created event.
456      *
457      * There is no external API for creating a group override, so the unit test will simply
458      * create and trigger the event and ensure the event data is returned as expected.
459      */
460     public function test_group_override_created() {
461         $this->resetAfterTest();
463         $this->setAdminUser();
464         $course = $this->getDataGenerator()->create_course();
465         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
467         $params = array(
468             'objectid' => 1,
469             'context' => context_module::instance($quiz->cmid),
470             'other' => array(
471                 'quizid' => $quiz->id,
472                 'groupid' => 2
473             )
474         );
475         $event = \mod_quiz\event\group_override_created::create($params);
477         // Trigger and capture the event.
478         $sink = $this->redirectEvents();
479         $event->trigger();
480         $events = $sink->get_events();
481         $event = reset($events);
483         // Check that the event data is valid.
484         $this->assertInstanceOf('\mod_quiz\event\group_override_created', $event);
485         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
486         $this->assertEventContextNotUsed($event);
487     }
489     /**
490      * Test the user override updated event.
491      *
492      * There is no external API for updating a user override, so the unit test will simply
493      * create and trigger the event and ensure the event data is returned as expected.
494      */
495     public function test_user_override_updated() {
496         $this->resetAfterTest();
498         $this->setAdminUser();
499         $course = $this->getDataGenerator()->create_course();
500         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
502         $params = array(
503             'objectid' => 1,
504             'relateduserid' => 2,
505             'context' => context_module::instance($quiz->cmid),
506             'other' => array(
507                 'quizid' => $quiz->id
508             )
509         );
510         $event = \mod_quiz\event\user_override_updated::create($params);
512         // Trigger and capture the event.
513         $sink = $this->redirectEvents();
514         $event->trigger();
515         $events = $sink->get_events();
516         $event = reset($events);
518         // Check that the event data is valid.
519         $this->assertInstanceOf('\mod_quiz\event\user_override_updated', $event);
520         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
521         $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid);
522         $this->assertEventLegacyLogData($expected, $event);
523         $this->assertEventContextNotUsed($event);
524     }
526     /**
527      * Test the group override updated event.
528      *
529      * There is no external API for updating a group override, so the unit test will simply
530      * create and trigger the event and ensure the event data is returned as expected.
531      */
532     public function test_group_override_updated() {
533         $this->resetAfterTest();
535         $this->setAdminUser();
536         $course = $this->getDataGenerator()->create_course();
537         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
539         $params = array(
540             'objectid' => 1,
541             'context' => context_module::instance($quiz->cmid),
542             'other' => array(
543                 'quizid' => $quiz->id,
544                 'groupid' => 2
545             )
546         );
547         $event = \mod_quiz\event\group_override_updated::create($params);
549         // Trigger and capture the event.
550         $sink = $this->redirectEvents();
551         $event->trigger();
552         $events = $sink->get_events();
553         $event = reset($events);
555         // Check that the event data is valid.
556         $this->assertInstanceOf('\mod_quiz\event\group_override_updated', $event);
557         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
558         $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid);
559         $this->assertEventLegacyLogData($expected, $event);
560         $this->assertEventContextNotUsed($event);
561     }
563     /**
564      * Test the user override deleted event.
565      */
566     public function test_user_override_deleted() {
567         global $DB;
569         $this->resetAfterTest();
571         $this->setAdminUser();
572         $course = $this->getDataGenerator()->create_course();
573         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
575         // Create an override.
576         $override = new stdClass();
577         $override->quiz = $quiz->id;
578         $override->userid = 2;
579         $override->id = $DB->insert_record('quiz_overrides', $override);
581         // Trigger and capture the event.
582         $sink = $this->redirectEvents();
583         quiz_delete_override($quiz, $override->id);
584         $events = $sink->get_events();
585         $event = reset($events);
587         // Check that the event data is valid.
588         $this->assertInstanceOf('\mod_quiz\event\user_override_deleted', $event);
589         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
590         $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid);
591         $this->assertEventLegacyLogData($expected, $event);
592         $this->assertEventContextNotUsed($event);
593     }
595     /**
596      * Test the group override deleted event.
597      */
598     public function test_group_override_deleted() {
599         global $DB;
601         $this->resetAfterTest();
603         $this->setAdminUser();
604         $course = $this->getDataGenerator()->create_course();
605         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
607         // Create an override.
608         $override = new stdClass();
609         $override->quiz = $quiz->id;
610         $override->groupid = 2;
611         $override->id = $DB->insert_record('quiz_overrides', $override);
613         // Trigger and capture the event.
614         $sink = $this->redirectEvents();
615         quiz_delete_override($quiz, $override->id);
616         $events = $sink->get_events();
617         $event = reset($events);
619         // Check that the event data is valid.
620         $this->assertInstanceOf('\mod_quiz\event\group_override_deleted', $event);
621         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
622         $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid);
623         $this->assertEventLegacyLogData($expected, $event);
624         $this->assertEventContextNotUsed($event);
625     }
627     /**
628      * Test the attempt viewed event.
629      *
630      * There is no external API for continuing an attempt, so the unit test will simply
631      * create and trigger the event and ensure the event data is returned as expected.
632      */
633     public function test_attempt_viewed() {
634         $this->resetAfterTest();
636         $this->setAdminUser();
637         $course = $this->getDataGenerator()->create_course();
638         $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
640         $params = array(
641             'objectid' => 1,
642             'relateduserid' => 2,
643             'courseid' => $course->id,
644             'context' => context_module::instance($quiz->cmid),
645             'other' => array(
646                 'quizid' => $quiz->id
647             )
648         );
649         $event = \mod_quiz\event\attempt_viewed::create($params);
651         // Trigger and capture the event.
652         $sink = $this->redirectEvents();
653         $event->trigger();
654         $events = $sink->get_events();
655         $event = reset($events);
657         // Check that the event data is valid.
658         $this->assertInstanceOf('\mod_quiz\event\attempt_viewed', $event);
659         $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
660         $expected = array($course->id, 'quiz', 'continue attempt', 'review.php?attempt=1', $quiz->id, $quiz->cmid);
661         $this->assertEventLegacyLogData($expected, $event);
662         $this->assertEventContextNotUsed($event);
663     }
665     /**
666      * Test the attempt previewed event.
667      */
668     public function test_attempt_preview_started() {
669         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
671         // We want to preview this attempt.
672         $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2);
673         $attempt->preview = 1;
675         // Trigger and capture the event.
676         $sink = $this->redirectEvents();
677         quiz_attempt_save_started($quizobj, $quba, $attempt);
678         $events = $sink->get_events();
679         $event = reset($events);
681         // Check that the event data is valid.
682         $this->assertInstanceOf('\mod_quiz\event\attempt_preview_started', $event);
683         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
684         $expected = array($quizobj->get_courseid(), 'quiz', 'preview', 'view.php?id=' . $quizobj->get_cmid(),
685             $quizobj->get_quizid(), $quizobj->get_cmid());
686         $this->assertEventLegacyLogData($expected, $event);
687         $this->assertEventContextNotUsed($event);
688     }
690     /**
691      * Test the question manually graded event.
692      *
693      * There is no external API for manually grading a question, so the unit test will simply
694      * create and trigger the event and ensure the event data is returned as expected.
695      */
696     public function test_question_manually_graded() {
697         list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
699         $params = array(
700             'objectid' => 1,
701             'courseid' => $quizobj->get_courseid(),
702             'context' => context_module::instance($quizobj->get_cmid()),
703             'other' => array(
704                 'quizid' => $quizobj->get_quizid(),
705                 'attemptid' => 2,
706                 'slot' => 3
707             )
708         );
709         $event = \mod_quiz\event\question_manually_graded::create($params);
711         // Trigger and capture the event.
712         $sink = $this->redirectEvents();
713         $event->trigger();
714         $events = $sink->get_events();
715         $event = reset($events);
717         // Check that the event data is valid.
718         $this->assertInstanceOf('\mod_quiz\event\question_manually_graded', $event);
719         $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
720         $expected = array($quizobj->get_courseid(), 'quiz', 'manualgrade', 'comment.php?attempt=2&slot=3',
721             $quizobj->get_quizid(), $quizobj->get_cmid());
722         $this->assertEventLegacyLogData($expected, $event);
723         $this->assertEventContextNotUsed($event);
724     }