░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/var/www/moodle/public/mod/quiz/tests/event
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: events_test.php
<?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Quiz events tests. * * @package mod_quiz * @category phpunit * @copyright 2013 Adrian Greeve * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_quiz\event; use mod_quiz\quiz_attempt; use mod_quiz\quiz_settings; use context_module; use mod_quiz\external\submit_question_version; /** * Unit tests for quiz events. * * @package mod_quiz * @category phpunit * @copyright 2013 Adrian Greeve * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \mod_quiz\external\submit_question_version */ final class events_test extends \advanced_testcase { /** * Set up a quiz. * * The quiz contains two questions, a short-answer one and a numerical one. * * @return quiz_settings the generated quiz. */ protected function prepare_quiz() { $this->resetAfterTest(true); // Create a course $course = $this->getDataGenerator()->create_course(); // Make a quiz. $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $quiz = $quizgenerator->create_instance(['course' => $course->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2]); get_coursemodule_from_instance('quiz', $quiz->id, $course->id); // Create a couple of questions. $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); $cat = $questiongenerator->create_question_category(); $saq = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]); $numq = $questiongenerator->create_question('numerical', null, ['category' => $cat->id]); // Update the numq question so it has multiple versions. Needed to test // the version updated event. $questiongenerator->update_question($numq, null, ['name' => 'Second version of numq']); // Add them to the quiz. quiz_add_quiz_question($saq->id, $quiz); quiz_add_quiz_question($numq->id, $quiz); // Make a user to do the quiz. $user1 = $this->getDataGenerator()->create_user(); $this->setUser($user1); return quiz_settings::create($quiz->id, $user1->id); } /** * Setup a quiz attempt at the quiz created by {@link prepare_quiz()}. * * @param \mod_quiz\quiz_settings $quizobj the generated quiz. * @param bool $ispreview Make the attempt a preview attempt when true. * @return array with three elements, array($quizobj, $quba, $attempt) */ protected function prepare_quiz_attempt($quizobj, $ispreview = false) { // Start the attempt. $quba = \question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, $ispreview); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj, $quba, $attempt); return [$quizobj, $quba, $attempt]; } /** * Setup some convenience test data with a single attempt. * * @param bool $ispreview Make the attempt a preview attempt when true. * @return array with three elements, array($quizobj, $quba, $attempt) */ protected function prepare_quiz_data($ispreview = false) { $quizobj = $this->prepare_quiz(); return $this->prepare_quiz_attempt($quizobj, $ispreview); } public function test_attempt_submitted(): void { [$quizobj, , $attempt] = $this->prepare_quiz_data(); $attemptobj = quiz_attempt::create($attempt->id); // Catch the event. $sink = $this->redirectEvents(); $timefinish = time(); $attemptobj->process_submit($timefinish, false); $events = $sink->get_events(); $sink->close(); // Validate the event. $this->assertCount(1, $events); $event = $events[0]; $this->assertInstanceOf('\mod_quiz\event\attempt_submitted', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($attempt->userid, $event->relateduserid); $this->assertEquals(null, $event->other['submitterid']); // Should be the user, but PHP Unit complains... $this->assertEventContextNotUsed($event); } /** * The \mod_quiz\event\attempt_graded event should be fired when an attempt is graded. * * @return void * @covers \mod_quiz\quiz_attempt::process_grade_submission */ public function test_attempt_graded(): void { [$quizobj, , $attempt] = $this->prepare_quiz_data(); $attemptobj = quiz_attempt::create($attempt->id); $timefinish = time(); $attemptobj->process_submit($timefinish, false); // Catch the event. $sink = $this->redirectEvents(); $attemptobj->process_grade_submission($timefinish); $events = $sink->get_events(); $sink->close(); // Validate the event. $this->assertCount(3, $events); $event = $events[2]; $this->assertInstanceOf('\mod_quiz\event\attempt_graded', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($attempt->userid, $event->relateduserid); $this->assertEquals(null, $event->other['submitterid']); // Should be the user, but PHP Unit complains... $this->assertEventContextNotUsed($event); } public function test_attempt_becameoverdue(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $attemptobj = quiz_attempt::create($attempt->id); // Catch the event. $sink = $this->redirectEvents(); $timefinish = time(); $attemptobj->process_going_overdue($timefinish, false); $events = $sink->get_events(); $sink->close(); $this->assertCount(1, $events); $event = $events[0]; $this->assertInstanceOf('\mod_quiz\event\attempt_becameoverdue', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($attempt->userid, $event->relateduserid); $this->assertNotEmpty($event->get_description()); // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid. $this->assertEquals(null, $event->other['submitterid']); $this->assertEventContextNotUsed($event); } public function test_attempt_abandoned(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $attemptobj = quiz_attempt::create($attempt->id); // Catch the event. $sink = $this->redirectEvents(); $timefinish = time(); $attemptobj->process_abandon($timefinish, false); $events = $sink->get_events(); $sink->close(); $this->assertCount(1, $events); $event = $events[0]; $this->assertInstanceOf('\mod_quiz\event\attempt_abandoned', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($attempt->userid, $event->relateduserid); // Submitterid should be the user, but as we are in PHP Unit, CLI_SCRIPT is set to true which sets null in submitterid. $this->assertEquals(null, $event->other['submitterid']); $this->assertEventContextNotUsed($event); } public function test_attempt_started(): void { $quizobj = $this->prepare_quiz(); $quba = \question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); // Trigger and capture the event. $sink = $this->redirectEvents(); quiz_attempt_save_started($quizobj, $quba, $attempt); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_started', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($attempt->id, $event->objectid); $this->assertEquals($attempt->userid, $event->relateduserid); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); } /** * Test the attempt question restarted event. * * There is no external API for replacing a question, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_question_restarted(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $quizobj->get_courseid(), 'context' => \context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'page' => 2, 'slot' => 3, 'newquestionid' => 2 ] ]; $event = \mod_quiz\event\attempt_question_restarted::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_question_restarted', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt updated event. * * There is no external API for updating an attempt, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_updated(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $quizobj->get_courseid(), 'context' => \context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'page' => 0 ] ]; $event = \mod_quiz\event\attempt_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_updated', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt auto-saved event. * * There is no external API for auto-saving an attempt, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_autosaved(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $quizobj->get_courseid(), 'context' => \context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'page' => 0 ] ]; $event = \mod_quiz\event\attempt_autosaved::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_autosaved', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the edit page viewed event. * * There is no external API for updating a quiz, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_edit_page_viewed(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'courseid' => $course->id, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\edit_page_viewed::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\edit_page_viewed', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt deleted event. */ public function test_attempt_deleted(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); // Trigger and capture the event. $sink = $this->redirectEvents(); quiz_delete_attempt($attempt, $quizobj->get_quiz()); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_deleted', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test that preview attempt deletions are not logged. */ public function test_preview_attempt_deleted(): void { // Create quiz with preview attempt. list($quizobj, $quba, $previewattempt) = $this->prepare_quiz_data(true); // Delete a preview attempt, capturing events. $sink = $this->redirectEvents(); quiz_delete_attempt($previewattempt, $quizobj->get_quiz()); // Verify that no events were generated. $this->assertEmpty($sink->get_events()); } /** * Test the report viewed event. * * There is no external API for viewing reports, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_report_viewed(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'context' => $context = \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id, 'reportname' => 'overview' ] ]; $event = \mod_quiz\event\report_viewed::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\report_viewed', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt reviewed event. * * There is no external API for reviewing attempts, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_reviewed(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $course->id, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\attempt_reviewed::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_reviewed', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt summary viewed event. * * There is no external API for viewing the attempt summary, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_summary_viewed(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $course->id, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\attempt_summary_viewed::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_summary_viewed', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the user override created event. * * There is no external API for creating a user override, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_user_override_created(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\user_override_created::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\user_override_created', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the group override created event. * * There is no external API for creating a group override, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_group_override_created(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id, 'groupid' => 2 ] ]; $event = \mod_quiz\event\group_override_created::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\group_override_created', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the user override updated event. * * There is no external API for updating a user override, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_user_override_updated(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\user_override_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\user_override_updated', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the group override updated event. * * There is no external API for updating a group override, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_group_override_updated(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id, 'groupid' => 2 ] ]; $event = \mod_quiz\event\group_override_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\group_override_updated', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the user override deleted event. */ public function test_user_override_deleted(): void { global $DB; $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $quizsettings = quiz_settings::create($quiz->id); // Create an override. $override = new \stdClass(); $override->quiz = $quiz->id; $override->userid = 2; $override->id = $DB->insert_record('quiz_overrides', $override); // Trigger and capture the event. $sink = $this->redirectEvents(); $quizsettings->get_override_manager()->delete_overrides(overrides: [$override]); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\user_override_deleted', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the group override deleted event. */ public function test_group_override_deleted(): void { global $DB; $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $quizsettings = quiz_settings::create($quiz->id); // Create an override. $override = new \stdClass(); $override->quiz = $quiz->id; $override->groupid = 2; $override->id = $DB->insert_record('quiz_overrides', $override); // Trigger and capture the event. $sink = $this->redirectEvents(); $quizsettings->get_override_manager()->delete_overrides(overrides: [$override]); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\group_override_deleted', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt viewed event. * * There is no external API for continuing an attempt, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_viewed(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $course->id, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id, 'page' => 0 ] ]; $event = \mod_quiz\event\attempt_viewed::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_viewed', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt previewed event. */ public function test_attempt_preview_started(): void { $quizobj = $this->prepare_quiz(); $quba = \question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, true); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); // Trigger and capture the event. $sink = $this->redirectEvents(); quiz_attempt_save_started($quizobj, $quba, $attempt); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_preview_started', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the question manually graded event. * * There is no external API for manually grading a question, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_question_manually_graded(): void { list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $params = [ 'objectid' => 1, 'courseid' => $quizobj->get_courseid(), 'context' => \context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'attemptid' => 2, 'slot' => 3 ] ]; $event = \mod_quiz\event\question_manually_graded::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\question_manually_graded', $event); $this->assertEquals(\context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt regraded event. * * There is no external API for regrading attempts, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_regraded(): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); $params = [ 'objectid' => 1, 'relateduserid' => 2, 'courseid' => $course->id, 'context' => \context_module::instance($quiz->cmid), 'other' => [ 'quizid' => $quiz->id ] ]; $event = \mod_quiz\event\attempt_regraded::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\attempt_regraded', $event); $this->assertEquals(\context_module::instance($quiz->cmid), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the attempt notify manual graded event. * There is no external API for notification email when manual grading of user's attempt is completed, * so the unit test will simply create and trigger the event and ensure the event data is returned as expected. */ public function test_attempt_manual_grading_completed(): void { $this->resetAfterTest(); list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); $attemptobj = quiz_attempt::create($attempt->id); $params = [ 'objectid' => $attemptobj->get_attemptid(), 'relateduserid' => $attemptobj->get_userid(), 'courseid' => $attemptobj->get_course()->id, 'context' => \context_module::instance($attemptobj->get_cmid()), 'other' => [ 'quizid' => $attemptobj->get_quizid() ] ]; $event = \mod_quiz\event\attempt_manual_grading_completed::create($params); // Catch the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $sink->close(); // Validate the event. $this->assertCount(1, $events); $event = reset($events); $this->assertInstanceOf('\mod_quiz\event\attempt_manual_grading_completed', $event); $this->assertEquals('quiz_attempts', $event->objecttable); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($attempt->userid, $event->relateduserid); $this->assertNotEmpty($event->get_description()); $this->assertEventContextNotUsed($event); } /** * Test the page break created event. * * There is no external API for creating page break, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_page_break_created(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'slotnumber' => 3, ] ]; $event = \mod_quiz\event\page_break_created::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\page_break_created', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the page break deleted event. * * There is no external API for deleting page break, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_page_deleted_created(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'slotnumber' => 3, ] ]; $event = \mod_quiz\event\page_break_deleted::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\page_break_deleted', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the quiz grade updated event. * * There is no external API for updating quiz grade, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_quiz_grade_updated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => $quizobj->get_quizid(), 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'oldgrade' => 1, 'newgrade' => 3, ] ]; $event = \mod_quiz\event\quiz_grade_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\quiz_grade_updated', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the quiz re-paginated event. * * There is no external API for re-paginating quiz, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_quiz_repaginated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => $quizobj->get_quizid(), 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'slotsperpage' => 3, ] ]; $event = \mod_quiz\event\quiz_repaginated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\quiz_repaginated', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the section break created event. * * There is no external API for creating section break, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_section_break_created(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'firstslotid' => 1, 'firstslotnumber' => 2, 'title' => 'New title' ] ]; $event = \mod_quiz\event\section_break_created::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\section_break_created', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertStringContainsString($params['other']['title'], $event->get_description()); $this->assertEventContextNotUsed($event); } /** * Test the section break deleted event. * * There is no external API for deleting section break, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_section_break_deleted(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'firstslotid' => 1, 'firstslotnumber' => 2 ] ]; $event = \mod_quiz\event\section_break_deleted::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\section_break_deleted', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the section shuffle updated event. * * There is no external API for updating section shuffle, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_section_shuffle_updated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'firstslotnumber' => 2, 'shuffle' => true ] ]; $event = \mod_quiz\event\section_shuffle_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\section_shuffle_updated', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the section title updated event. * * There is no external API for updating section title, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_section_title_updated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'firstslotid' => 1, 'firstslotnumber' => 2, 'newtitle' => 'New title' ] ]; $event = \mod_quiz\event\section_title_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\section_title_updated', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertStringContainsString($params['other']['newtitle'], $event->get_description()); $this->assertEventContextNotUsed($event); } /** * Test the slot created event. * * There is no external API for creating slot, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_slot_created(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'slotnumber' => 1, 'page' => 1 ] ]; $event = \mod_quiz\event\slot_created::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\slot_created', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the slot deleted event. * * There is no external API for deleting slot, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_slot_deleted(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'slotnumber' => 1, ] ]; $event = \mod_quiz\event\slot_deleted::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\slot_deleted', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the slot mark updated event. * * There is no external API for updating slot mark, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_slot_mark_updated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'previousmaxmark' => 1, 'newmaxmark' => 2, ] ]; $event = \mod_quiz\event\slot_mark_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\slot_mark_updated', $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEventContextNotUsed($event); } public function test_slot_version_updated(): void { $quizobj = $this->prepare_quiz(); $this->setAdminUser(); $quizobj->preload_questions(); [, $numqslotid] = array_column($quizobj->get_questions(null, false), 'slotid'); $sink = $this->redirectEvents(); submit_question_version::execute($numqslotid, 2); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $expecteddesc = "The user with id '2' updated the slot with id '$numqslotid' " . "belonging to the quiz with course module id '{$quizobj->get_cmid()}'. " . "Its question version was changed from 'Always latest' to '2'."; $this->assertInstanceOf('\mod_quiz\event\slot_version_updated', $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEquals($expecteddesc, $event->get_description()); $this->assertEventContextNotUsed($event); } /** * Test quiz_grade_item_created. * * @covers \mod_quiz\event\quiz_grade_item_created */ public function test_quiz_grade_item_created(): void { global $USER; $quizobj = $this->prepare_quiz(); $stucture = $quizobj->get_structure(); // Trigger and capture the event. $sink = $this->redirectEvents(); $stucture->create_grade_item((object) ['quizid' => $quizobj->get_quizid(), 'name' => 'Test']); $events = $sink->get_events(); /** @var slot_grade_item_updated $event */ $event = reset($events); // Check that the event data is valid. $stucture = $quizobj->get_structure(); $gradeitem = array_values($stucture->get_grade_items())[0]; $this->assertInstanceOf(quiz_grade_item_created::class, $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEventContextNotUsed($event); $this->assertEquals(new \moodle_url('/mod/quiz/editgrading.php', ['cmid' => $quizobj->get_cmid()]), $event->get_url()); $this->assertEquals("The user with id '$USER->id' created quiz grade item with id '$gradeitem->id' " . "for the quiz with course module id '{$quizobj->get_cmid()}'.", $event->get_description()); } /** * Test quiz_grade_item_updated. * * @covers \mod_quiz\event\quiz_grade_item_updated */ public function test_quiz_grade_item_updated(): void { global $USER; $quizobj = $this->prepare_quiz(); /** @var \mod_quiz_generator $quizgenerator */ $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $gradeitem = $quizgenerator->create_grade_item( ['quizid' => $quizobj->get_quizid(), 'name' => 'Awesomeness!']); $stucture = $quizobj->get_structure(); // Trigger and capture the event. $sink = $this->redirectEvents(); $stucture->update_grade_item((object) ['id' => $gradeitem->id, 'name' => 'Test']); $events = $sink->get_events(); /** @var slot_grade_item_updated $event */ $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf(quiz_grade_item_updated::class, $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEventContextNotUsed($event); $this->assertEquals(new \moodle_url('/mod/quiz/editgrading.php', ['cmid' => $quizobj->get_cmid()]), $event->get_url()); $this->assertEquals("The user with id '$USER->id' updated quiz grade item with id '$gradeitem->id' " . "for the quiz with course module id '{$quizobj->get_cmid()}'.", $event->get_description()); } /** * Test quiz_grade_item_deleted. * * @covers \mod_quiz\event\quiz_grade_item_deleted */ public function test_quiz_grade_item_deleted(): void { global $USER; $quizobj = $this->prepare_quiz(); /** @var \mod_quiz_generator $quizgenerator */ $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $gradeitem = $quizgenerator->create_grade_item( ['quizid' => $quizobj->get_quizid(), 'name' => 'Awesomeness!']); $stucture = $quizobj->get_structure(); // Trigger and capture the event. $sink = $this->redirectEvents(); $stucture->delete_grade_item($gradeitem->id); $events = $sink->get_events(); /** @var slot_grade_item_updated $event */ $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf(quiz_grade_item_deleted::class, $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEventContextNotUsed($event); $this->assertEquals(new \moodle_url('/mod/quiz/editgrading.php', ['cmid' => $quizobj->get_cmid()]), $event->get_url()); $this->assertEquals("The user with id '$USER->id' deleted quiz grade item with id '$gradeitem->id' " . "for the quiz with course module id '{$quizobj->get_cmid()}'.", $event->get_description()); } /** * Test slot_grade_item_updated. * * @covers \mod_quiz\event\slot_grade_item_updated */ public function test_slot_grade_item_updated(): void { global $USER; $quizobj = $this->prepare_quiz(); /** @var \mod_quiz_generator $quizgenerator */ $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $gradeitem = $quizgenerator->create_grade_item( ['quizid' => $quizobj->get_quizid(), 'name' => 'Awesomeness!']); $stucture = $quizobj->get_structure(); $slot = $stucture->get_slot_by_number(1); // Trigger and capture the event. $sink = $this->redirectEvents(); $stucture->update_slot_grade_item($slot, $gradeitem->id); $events = $sink->get_events(); /** @var slot_grade_item_updated $event */ $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf(slot_grade_item_updated::class, $event); $this->assertEquals($quizobj->get_context(), $event->get_context()); $this->assertEventContextNotUsed($event); $this->assertEquals(new \moodle_url('/mod/quiz/editgrading.php', ['cmid' => $quizobj->get_cmid()]), $event->get_url()); $this->assertEquals("The user with id '$USER->id' updated the slot with id '{$slot->id}' " . "belonging to the quiz with course module id '{$quizobj->get_cmid()}'. " . "The grade item this slot contributes to was changed from '' to '$gradeitem->id'.", $event->get_description()); // Check nothing logged if the value is not changed. $sink = $this->redirectEvents(); $stucture->update_slot_grade_item($slot, $gradeitem->id); $events = $sink->get_events(); $this->assertCount(0, $events); } /** * Test the slot moved event. * * There is no external API for moving slot, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_slot_moved(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'previousslotnumber' => 1, 'afterslotnumber' => 2, 'page' => 1 ] ]; $event = \mod_quiz\event\slot_moved::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\slot_moved', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } /** * Test the slot require previous updated event. * * There is no external API for updating slot require previous option, so the unit test will simply * create and trigger the event and ensure the event data is returned as expected. */ public function test_slot_requireprevious_updated(): void { $quizobj = $this->prepare_quiz(); $params = [ 'objectid' => 1, 'context' => context_module::instance($quizobj->get_cmid()), 'other' => [ 'quizid' => $quizobj->get_quizid(), 'requireprevious' => true ] ]; $event = \mod_quiz\event\slot_requireprevious_updated::create($params); // Trigger and capture the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $event = reset($events); // Check that the event data is valid. $this->assertInstanceOf('\mod_quiz\event\slot_requireprevious_updated', $event); $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); $this->assertEventContextNotUsed($event); } }
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 events_test.php
PHP
55 KB
2026-02-11 01:44
EDIT