Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310]

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