Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 311 and 403] [Versions 400 and 403] [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Events tests.
  19   *
  20   * @package    mod_choice
  21   * @copyright  2013 Adrian Greeve <adrian@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_choice\event;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once($CFG->dirroot . '/mod/choice/lib.php');
  31  
  32  /**
  33   * Events tests class.
  34   *
  35   * @package    mod_choice
  36   * @copyright  2013 Adrian Greeve <adrian@moodle.com>
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class events_test extends \advanced_testcase {
  40      /** @var choice_object */
  41      protected $choice;
  42  
  43      /** @var course_object */
  44      protected $course;
  45  
  46      /** @var cm_object Course module object. */
  47      protected $cm;
  48  
  49      /** @var context_object */
  50      protected $context;
  51  
  52      /**
  53       * Setup often used objects for the following tests.
  54       */
  55      protected function setUp(): void {
  56          global $DB;
  57  
  58          $this->resetAfterTest();
  59  
  60          $this->course = $this->getDataGenerator()->create_course();
  61          $this->choice = $this->getDataGenerator()->create_module('choice', array('course' => $this->course->id));
  62          $this->cm = $DB->get_record('course_modules', array('id' => $this->choice->cmid));
  63          $this->context = \context_module::instance($this->choice->cmid);
  64      }
  65  
  66      /**
  67       * Test to ensure that event data is being stored correctly.
  68       */
  69      public function test_answer_created() {
  70          global $DB;
  71          // Generate user data.
  72          $user = $this->getDataGenerator()->create_user();
  73          $this->setUser($user);
  74  
  75          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
  76          // Redirect event.
  77          $sink = $this->redirectEvents();
  78          choice_user_submit_response($optionids[3], $this->choice, $user->id, $this->course, $this->cm);
  79          $events = $sink->get_events();
  80          $answer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
  81  
  82          // Data checking.
  83          $this->assertCount(1, $events);
  84          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[0]);
  85          $this->assertEquals($user->id, $events[0]->userid);
  86          $this->assertEquals($user->id, $events[0]->relateduserid);
  87          $this->assertEquals(\context_module::instance($this->choice->cmid), $events[0]->get_context());
  88          $this->assertEquals($answer->id, $events[0]->objectid);
  89          $this->assertEquals($this->choice->id, $events[0]->other['choiceid']);
  90          $this->assertEquals($optionids[3], $events[0]->other['optionid']);
  91          $this->assertEventContextNotUsed($events[0]);
  92          $sink->close();
  93      }
  94  
  95      /**
  96       * Test to ensure that event data is being stored correctly.
  97       */
  98      public function test_answer_submitted_by_another_user() {
  99          global $DB, $USER;
 100          // Generate user data.
 101          $user = $this->getDataGenerator()->create_user();
 102  
 103          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
 104          // Redirect event.
 105          $sink = $this->redirectEvents();
 106          choice_user_submit_response($optionids[3], $this->choice, $user->id, $this->course, $this->cm);
 107          $events = $sink->get_events();
 108          $answer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
 109  
 110          // Data checking.
 111          $this->assertCount(1, $events);
 112          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[0]);
 113          $this->assertEquals($USER->id, $events[0]->userid);
 114          $this->assertEquals($user->id, $events[0]->relateduserid);
 115          $this->assertEquals(\context_module::instance($this->choice->cmid), $events[0]->get_context());
 116          $this->assertEquals($answer->id, $events[0]->objectid);
 117          $this->assertEquals($this->choice->id, $events[0]->other['choiceid']);
 118          $this->assertEquals($optionids[3], $events[0]->other['optionid']);
 119          $this->assertEventContextNotUsed($events[0]);
 120          $sink->close();
 121      }
 122  
 123      /**
 124       * Test to ensure that multiple choice data is being stored correctly.
 125       */
 126      public function test_answer_created_multiple() {
 127          global $DB;
 128  
 129          // Generate user data.
 130          $user = $this->getDataGenerator()->create_user();
 131          $this->setUser($user);
 132  
 133          // Create multiple choice.
 134          $choice = $this->getDataGenerator()->create_module('choice', array('course' => $this->course->id,
 135              'allowmultiple' => 1));
 136          $cm = $DB->get_record('course_modules', array('id' => $choice->cmid));
 137          $context = \context_module::instance($choice->cmid);
 138  
 139          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $choice->id)));
 140          $submittedoptionids = array($optionids[1], $optionids[3]);
 141  
 142          // Redirect event.
 143          $sink = $this->redirectEvents();
 144          choice_user_submit_response($submittedoptionids, $choice, $user->id, $this->course, $cm);
 145          $events = $sink->get_events();
 146          $answers = $DB->get_records('choice_answers', ['userid' => $user->id, 'choiceid' => $choice->id], 'id');
 147          $answers = array_values($answers);
 148  
 149          // Data checking.
 150          $this->assertCount(2, $events);
 151          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[0]);
 152          $this->assertEquals($user->id, $events[0]->userid);
 153          $this->assertEquals($user->id, $events[0]->relateduserid);
 154          $this->assertEquals(\context_module::instance($choice->cmid), $events[0]->get_context());
 155          $this->assertEquals($answers[0]->id, $events[0]->objectid);
 156          $this->assertEquals($choice->id, $events[0]->other['choiceid']);
 157          $this->assertEquals($optionids[1], $events[0]->other['optionid']);
 158          $this->assertEventContextNotUsed($events[0]);
 159  
 160          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[1]);
 161          $this->assertEquals($user->id, $events[1]->userid);
 162          $this->assertEquals($user->id, $events[1]->relateduserid);
 163          $this->assertEquals(\context_module::instance($choice->cmid), $events[1]->get_context());
 164          $this->assertEquals($answers[1]->id, $events[1]->objectid);
 165          $this->assertEquals($choice->id, $events[1]->other['choiceid']);
 166          $this->assertEquals($optionids[3], $events[1]->other['optionid']);
 167          $this->assertEventContextNotUsed($events[1]);
 168          $sink->close();
 169      }
 170  
 171      /**
 172       * Test custom validations.
 173       */
 174      public function test_answer_created_other_exception() {
 175          // Generate user data.
 176          $user = $this->getDataGenerator()->create_user();
 177  
 178          $eventdata = array();
 179          $eventdata['context'] = $this->context;
 180          $eventdata['objectid'] = 2;
 181          $eventdata['userid'] = $user->id;
 182          $eventdata['courseid'] = $this->course->id;
 183          $eventdata['other'] = array();
 184  
 185          // Make sure content identifier is always set.
 186          $this->expectException(\coding_exception::class);
 187          $event = \mod_choice\event\answer_created::create($eventdata);
 188          $event->trigger();
 189          $this->assertEventContextNotUsed($event);
 190      }
 191  
 192      /**
 193       * Test to ensure that event data is being stored correctly.
 194       */
 195      public function test_answer_updated() {
 196          global $DB;
 197          // Generate user data.
 198          $user = $this->getDataGenerator()->create_user();
 199          $this->setUser($user);
 200  
 201          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
 202  
 203          // Create the first answer.
 204          choice_user_submit_response($optionids[2], $this->choice, $user->id, $this->course, $this->cm);
 205          $oldanswer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
 206  
 207          // Redirect event.
 208          $sink = $this->redirectEvents();
 209          // Now choose a different answer.
 210          choice_user_submit_response($optionids[3], $this->choice, $user->id, $this->course, $this->cm);
 211          $newanswer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
 212  
 213          $events = $sink->get_events();
 214  
 215          // Data checking.
 216          $this->assertCount(2, $events);
 217          $this->assertInstanceOf('\mod_choice\event\answer_deleted', $events[0]);
 218          $this->assertEquals($user->id, $events[0]->userid);
 219          $this->assertEquals(\context_module::instance($this->choice->cmid), $events[0]->get_context());
 220          $this->assertEquals($oldanswer->id, $events[0]->objectid);
 221          $this->assertEquals($this->choice->id, $events[0]->other['choiceid']);
 222          $this->assertEquals($optionids[2], $events[0]->other['optionid']);
 223          $this->assertEventContextNotUsed($events[0]);
 224  
 225          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[1]);
 226          $this->assertEquals($user->id, $events[1]->userid);
 227          $this->assertEquals(\context_module::instance($this->choice->cmid), $events[1]->get_context());
 228          $this->assertEquals($newanswer->id, $events[1]->objectid);
 229          $this->assertEquals($this->choice->id, $events[1]->other['choiceid']);
 230          $this->assertEquals($optionids[3], $events[1]->other['optionid']);
 231          $this->assertEventContextNotUsed($events[1]);
 232  
 233          $sink->close();
 234      }
 235  
 236      /**
 237       * Test to ensure that event data is being stored correctly.
 238       */
 239      public function test_answer_deleted() {
 240          global $DB, $USER;
 241          // Generate user data.
 242          $user = $this->getDataGenerator()->create_user();
 243  
 244          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
 245  
 246          // Create the first answer.
 247          choice_user_submit_response($optionids[2], $this->choice, $user->id, $this->course, $this->cm);
 248          // Get the users response.
 249          $answer = $DB->get_record('choice_answers', array('userid' => $user->id, 'choiceid' => $this->choice->id),
 250              '*', $strictness = IGNORE_MULTIPLE);
 251  
 252          // Redirect event.
 253          $sink = $this->redirectEvents();
 254          // Now delete the answer.
 255          choice_delete_responses(array($answer->id), $this->choice, $this->cm, $this->course);
 256  
 257          // Get our event event.
 258          $events = $sink->get_events();
 259          $event = reset($events);
 260  
 261          // Data checking.
 262          $this->assertInstanceOf('\mod_choice\event\answer_deleted', $event);
 263          $this->assertEquals($USER->id, $event->userid);
 264          $this->assertEquals($user->id, $event->relateduserid);
 265          $this->assertEquals(\context_module::instance($this->choice->cmid), $event->get_context());
 266          $this->assertEquals($this->choice->id, $event->other['choiceid']);
 267          $this->assertEquals($answer->optionid, $event->other['optionid']);
 268          $this->assertEventContextNotUsed($event);
 269          $sink->close();
 270      }
 271  
 272      /**
 273       * Test to ensure that event data is being stored correctly.
 274       */
 275      public function test_report_viewed() {
 276          global $USER;
 277  
 278          $this->resetAfterTest();
 279  
 280          // Generate user data.
 281          $this->setAdminUser();
 282  
 283          $eventdata = array();
 284          $eventdata['objectid'] = $this->choice->id;
 285          $eventdata['context'] = $this->context;
 286          $eventdata['courseid'] = $this->course->id;
 287          $eventdata['other']['content'] = 'choicereportcontentviewed';
 288  
 289          // This is fired in a page view so we can't run this through a function.
 290          $event = \mod_choice\event\report_viewed::create($eventdata);
 291  
 292          // Redirect event.
 293          $sink = $this->redirectEvents();
 294          $event->trigger();
 295          $event = $sink->get_events();
 296  
 297          // Data checking.
 298          $this->assertCount(1, $event);
 299          $this->assertInstanceOf('\mod_choice\event\report_viewed', $event[0]);
 300          $this->assertEquals($USER->id, $event[0]->userid);
 301          $this->assertEquals(\context_module::instance($this->choice->cmid), $event[0]->get_context());
 302          $sink->close();
 303      }
 304  
 305      /**
 306       * Test to ensure that event data is being stored correctly.
 307       */
 308      public function test_report_downloaded() {
 309          global $USER;
 310  
 311          $this->resetAfterTest();
 312  
 313          // Generate user data.
 314          $this->setAdminUser();
 315  
 316          $eventdata = array();
 317          $eventdata['context'] = $this->context;
 318          $eventdata['courseid'] = $this->course->id;
 319          $eventdata['other']['content'] = 'choicereportcontentviewed';
 320          $eventdata['other']['format'] = 'csv';
 321          $eventdata['other']['choiceid'] = $this->choice->id;
 322  
 323          // This is fired in a page view so we can't run this through a function.
 324          $event = \mod_choice\event\report_downloaded::create($eventdata);
 325  
 326          // Redirect event.
 327          $sink = $this->redirectEvents();
 328          $event->trigger();
 329          $event = $sink->get_events();
 330  
 331          // Data checking.
 332          $this->assertCount(1, $event);
 333          $this->assertInstanceOf('\mod_choice\event\report_downloaded', $event[0]);
 334          $this->assertEquals($USER->id, $event[0]->userid);
 335          $this->assertEquals(\context_module::instance($this->choice->cmid), $event[0]->get_context());
 336          $this->assertEquals('csv', $event[0]->other['format']);
 337          $this->assertEquals($this->choice->id, $event[0]->other['choiceid']);
 338          $this->assertEventContextNotUsed($event[0]);
 339          $sink->close();
 340      }
 341  
 342      /**
 343       * Test to ensure that event data is being stored correctly.
 344       */
 345      public function test_course_module_viewed() {
 346          global $USER;
 347  
 348          // Generate user data.
 349          $this->setAdminUser();
 350  
 351          $eventdata = array();
 352          $eventdata['objectid'] = $this->choice->id;
 353          $eventdata['context'] = $this->context;
 354          $eventdata['courseid'] = $this->course->id;
 355          $eventdata['other']['content'] = 'pageresourceview';
 356  
 357          // This is fired in a page view so we can't run this through a function.
 358          $event = \mod_choice\event\course_module_viewed::create($eventdata);
 359  
 360          // Redirect event.
 361          $sink = $this->redirectEvents();
 362          $event->trigger();
 363          $event = $sink->get_events();
 364  
 365          // Data checking.
 366          $this->assertCount(1, $event);
 367          $this->assertInstanceOf('\mod_choice\event\course_module_viewed', $event[0]);
 368          $this->assertEquals($USER->id, $event[0]->userid);
 369          $this->assertEquals(\context_module::instance($this->choice->cmid), $event[0]->get_context());
 370          $sink->close();
 371      }
 372  
 373      /**
 374       * Test to ensure that event data is being stored correctly.
 375       */
 376      public function test_course_module_instance_list_viewed_viewed() {
 377          global $USER;
 378  
 379          // Not much can be tested here as the event is only triggered on a page load,
 380          // let's just check that the event contains the expected basic information.
 381          $this->setAdminUser();
 382  
 383          $params = array('context' => \context_course::instance($this->course->id));
 384          $event = \mod_choice\event\course_module_instance_list_viewed::create($params);
 385          $sink = $this->redirectEvents();
 386          $event->trigger();
 387          $events = $sink->get_events();
 388          $event = reset($events);
 389          $this->assertInstanceOf('\mod_choice\event\course_module_instance_list_viewed', $event);
 390          $this->assertEquals($USER->id, $event->userid);
 391          $this->assertEquals(\context_course::instance($this->course->id), $event->get_context());
 392      }
 393  }