Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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(): void {
  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      public function test_answer_created_other_exception() {
 173          // Generate user data.
 174          $user = $this->getDataGenerator()->create_user();
 175  
 176          $eventdata = array();
 177          $eventdata['context'] = $this->context;
 178          $eventdata['objectid'] = 2;
 179          $eventdata['userid'] = $user->id;
 180          $eventdata['courseid'] = $this->course->id;
 181          $eventdata['other'] = array();
 182  
 183          // Make sure content identifier is always set.
 184          $this->expectException(coding_exception::class);
 185          $event = \mod_choice\event\answer_created::create($eventdata);
 186          $event->trigger();
 187          $this->assertEventContextNotUsed($event);
 188      }
 189  
 190      /**
 191       * Test to ensure that event data is being stored correctly.
 192       */
 193      public function test_answer_updated() {
 194          global $DB;
 195          // Generate user data.
 196          $user = $this->getDataGenerator()->create_user();
 197          $this->setUser($user);
 198  
 199          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
 200  
 201          // Create the first answer.
 202          choice_user_submit_response($optionids[2], $this->choice, $user->id, $this->course, $this->cm);
 203          $oldanswer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
 204  
 205          // Redirect event.
 206          $sink = $this->redirectEvents();
 207          // Now choose a different answer.
 208          choice_user_submit_response($optionids[3], $this->choice, $user->id, $this->course, $this->cm);
 209          $newanswer = $DB->get_record('choice_answers', ['userid' => $user->id, 'choiceid' => $this->choice->id]);
 210  
 211          $events = $sink->get_events();
 212  
 213          // Data checking.
 214          $this->assertCount(2, $events);
 215          $this->assertInstanceOf('\mod_choice\event\answer_deleted', $events[0]);
 216          $this->assertEquals($user->id, $events[0]->userid);
 217          $this->assertEquals(context_module::instance($this->choice->cmid), $events[0]->get_context());
 218          $this->assertEquals($oldanswer->id, $events[0]->objectid);
 219          $this->assertEquals($this->choice->id, $events[0]->other['choiceid']);
 220          $this->assertEquals($optionids[2], $events[0]->other['optionid']);
 221          $this->assertEventContextNotUsed($events[0]);
 222  
 223          $this->assertInstanceOf('\mod_choice\event\answer_created', $events[1]);
 224          $this->assertEquals($user->id, $events[1]->userid);
 225          $this->assertEquals(context_module::instance($this->choice->cmid), $events[1]->get_context());
 226          $this->assertEquals($newanswer->id, $events[1]->objectid);
 227          $this->assertEquals($this->choice->id, $events[1]->other['choiceid']);
 228          $this->assertEquals($optionids[3], $events[1]->other['optionid']);
 229          $this->assertEventContextNotUsed($events[1]);
 230  
 231          $sink->close();
 232      }
 233  
 234      /**
 235       * Test to ensure that event data is being stored correctly.
 236       */
 237      public function test_answer_deleted() {
 238          global $DB, $USER;
 239          // Generate user data.
 240          $user = $this->getDataGenerator()->create_user();
 241  
 242          $optionids = array_keys($DB->get_records('choice_options', array('choiceid' => $this->choice->id)));
 243  
 244          // Create the first answer.
 245          choice_user_submit_response($optionids[2], $this->choice, $user->id, $this->course, $this->cm);
 246          // Get the users response.
 247          $answer = $DB->get_record('choice_answers', array('userid' => $user->id, 'choiceid' => $this->choice->id),
 248              '*', $strictness = IGNORE_MULTIPLE);
 249  
 250          // Redirect event.
 251          $sink = $this->redirectEvents();
 252          // Now delete the answer.
 253          choice_delete_responses(array($answer->id), $this->choice, $this->cm, $this->course);
 254  
 255          // Get our event event.
 256          $events = $sink->get_events();
 257          $event = reset($events);
 258  
 259          // Data checking.
 260          $this->assertInstanceOf('\mod_choice\event\answer_deleted', $event);
 261          $this->assertEquals($USER->id, $event->userid);
 262          $this->assertEquals($user->id, $event->relateduserid);
 263          $this->assertEquals(context_module::instance($this->choice->cmid), $event->get_context());
 264          $this->assertEquals($this->choice->id, $event->other['choiceid']);
 265          $this->assertEquals($answer->optionid, $event->other['optionid']);
 266          $this->assertEventContextNotUsed($event);
 267          $sink->close();
 268      }
 269  
 270      /**
 271       * Test to ensure that event data is being stored correctly.
 272       */
 273      public function test_report_viewed() {
 274          global $USER;
 275  
 276          $this->resetAfterTest();
 277  
 278          // Generate user data.
 279          $this->setAdminUser();
 280  
 281          $eventdata = array();
 282          $eventdata['objectid'] = $this->choice->id;
 283          $eventdata['context'] = $this->context;
 284          $eventdata['courseid'] = $this->course->id;
 285          $eventdata['other']['content'] = 'choicereportcontentviewed';
 286  
 287          // This is fired in a page view so we can't run this through a function.
 288          $event = \mod_choice\event\report_viewed::create($eventdata);
 289  
 290          // Redirect event.
 291          $sink = $this->redirectEvents();
 292          $event->trigger();
 293          $event = $sink->get_events();
 294  
 295          // Data checking.
 296          $this->assertCount(1, $event);
 297          $this->assertInstanceOf('\mod_choice\event\report_viewed', $event[0]);
 298          $this->assertEquals($USER->id, $event[0]->userid);
 299          $this->assertEquals(context_module::instance($this->choice->cmid), $event[0]->get_context());
 300          $expected = array($this->course->id, "choice", "report", 'report.php?id=' . $this->context->instanceid,
 301              $this->choice->id, $this->context->instanceid);
 302          $this->assertEventLegacyLogData($expected, $event[0]);
 303          $this->assertEventContextNotUsed($event[0]);
 304          $sink->close();
 305      }
 306  
 307      /**
 308       * Test to ensure that event data is being stored correctly.
 309       */
 310      public function test_report_downloaded() {
 311          global $USER;
 312  
 313          $this->resetAfterTest();
 314  
 315          // Generate user data.
 316          $this->setAdminUser();
 317  
 318          $eventdata = array();
 319          $eventdata['context'] = $this->context;
 320          $eventdata['courseid'] = $this->course->id;
 321          $eventdata['other']['content'] = 'choicereportcontentviewed';
 322          $eventdata['other']['format'] = 'csv';
 323          $eventdata['other']['choiceid'] = $this->choice->id;
 324  
 325          // This is fired in a page view so we can't run this through a function.
 326          $event = \mod_choice\event\report_downloaded::create($eventdata);
 327  
 328          // Redirect event.
 329          $sink = $this->redirectEvents();
 330          $event->trigger();
 331          $event = $sink->get_events();
 332  
 333          // Data checking.
 334          $this->assertCount(1, $event);
 335          $this->assertInstanceOf('\mod_choice\event\report_downloaded', $event[0]);
 336          $this->assertEquals($USER->id, $event[0]->userid);
 337          $this->assertEquals(context_module::instance($this->choice->cmid), $event[0]->get_context());
 338          $this->assertEquals('csv', $event[0]->other['format']);
 339          $this->assertEquals($this->choice->id, $event[0]->other['choiceid']);
 340          $this->assertEventContextNotUsed($event[0]);
 341          $sink->close();
 342      }
 343  
 344      /**
 345       * Test to ensure that event data is being stored correctly.
 346       */
 347      public function test_course_module_viewed() {
 348          global $USER;
 349  
 350          // Generate user data.
 351          $this->setAdminUser();
 352  
 353          $eventdata = array();
 354          $eventdata['objectid'] = $this->choice->id;
 355          $eventdata['context'] = $this->context;
 356          $eventdata['courseid'] = $this->course->id;
 357          $eventdata['other']['content'] = 'pageresourceview';
 358  
 359          // This is fired in a page view so we can't run this through a function.
 360          $event = \mod_choice\event\course_module_viewed::create($eventdata);
 361  
 362          // Redirect event.
 363          $sink = $this->redirectEvents();
 364          $event->trigger();
 365          $event = $sink->get_events();
 366  
 367          // Data checking.
 368          $this->assertCount(1, $event);
 369          $this->assertInstanceOf('\mod_choice\event\course_module_viewed', $event[0]);
 370          $this->assertEquals($USER->id, $event[0]->userid);
 371          $this->assertEquals(context_module::instance($this->choice->cmid), $event[0]->get_context());
 372          $expected = array($this->course->id, "choice", "view", 'view.php?id=' . $this->context->instanceid,
 373              $this->choice->id, $this->context->instanceid);
 374          $this->assertEventLegacyLogData($expected, $event[0]);
 375          $this->assertEventContextNotUsed($event[0]);
 376          $sink->close();
 377      }
 378  
 379      /**
 380       * Test to ensure that event data is being stored correctly.
 381       */
 382      public function test_course_module_instance_list_viewed_viewed() {
 383          global $USER;
 384  
 385          // Not much can be tested here as the event is only triggered on a page load,
 386          // let's just check that the event contains the expected basic information.
 387          $this->setAdminUser();
 388  
 389          $params = array('context' => context_course::instance($this->course->id));
 390          $event = \mod_choice\event\course_module_instance_list_viewed::create($params);
 391          $sink = $this->redirectEvents();
 392          $event->trigger();
 393          $events = $sink->get_events();
 394          $event = reset($events);
 395          $this->assertInstanceOf('\mod_choice\event\course_module_instance_list_viewed', $event);
 396          $this->assertEquals($USER->id, $event->userid);
 397          $this->assertEquals(context_course::instance($this->course->id), $event->get_context());
 398          $expected = array($this->course->id, 'choice', 'view all', 'index.php?id=' . $this->course->id, '');
 399          $this->assertEventLegacyLogData($expected, $event);
 400          $this->assertEventContextNotUsed($event);
 401      }
 402  }