Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 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   * Contains the event tests for the module assign.
  19   *
  20   * @package   mod_assign
  21   * @copyright 2014 Adrian Greeve <adrian@moodle.com>
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_assign\event;
  26  
  27  use mod_assign_test_generator;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  global $CFG;
  32  require_once($CFG->dirroot . '/mod/assign/tests/generator.php');
  33  require_once($CFG->dirroot . '/mod/assign/tests/fixtures/event_mod_assign_fixtures.php');
  34  require_once($CFG->dirroot . '/mod/assign/locallib.php');
  35  
  36  /**
  37   * Contains the event tests for the module assign.
  38   *
  39   * @package   mod_assign
  40   * @copyright 2014 Adrian Greeve <adrian@moodle.com>
  41   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   */
  43  class events_test extends \advanced_testcase {
  44      // Use the generator helper.
  45      use mod_assign_test_generator;
  46  
  47      /**
  48       * Basic tests for the submission_created() abstract class.
  49       */
  50      public function test_base_event() {
  51          $this->resetAfterTest();
  52  
  53          $course = $this->getDataGenerator()->create_course();
  54          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
  55          $instance = $generator->create_instance(array('course' => $course->id));
  56          $modcontext = \context_module::instance($instance->cmid);
  57  
  58          $data = array(
  59              'context' => $modcontext,
  60          );
  61  
  62          $event = \mod_assign_unittests\event\nothing_happened::create($data);
  63          $assign = $event->get_assign();
  64          $this->assertDebuggingCalled();
  65          $this->assertInstanceOf('assign', $assign);
  66  
  67          $event = \mod_assign_unittests\event\nothing_happened::create($data);
  68          $event->set_assign($assign);
  69          $assign2 = $event->get_assign();
  70          $this->assertDebuggingNotCalled();
  71          $this->assertSame($assign, $assign2);
  72      }
  73  
  74      /**
  75       * Basic tests for the submission_created() abstract class.
  76       */
  77      public function test_submission_created() {
  78          $this->resetAfterTest();
  79  
  80          $course = $this->getDataGenerator()->create_course();
  81          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
  82          $instance = $generator->create_instance(array('course' => $course->id));
  83          $modcontext = \context_module::instance($instance->cmid);
  84  
  85          // Standard Event parameters.
  86          $params = array(
  87              'context' => $modcontext,
  88              'courseid' => $course->id
  89          );
  90  
  91          $eventinfo = $params;
  92          $eventinfo['other'] = array(
  93              'submissionid' => '17',
  94              'submissionattempt' => 0,
  95              'submissionstatus' => 'submitted'
  96          );
  97  
  98          $sink = $this->redirectEvents();
  99          $event = \mod_assign_unittests\event\submission_created::create($eventinfo);
 100          $event->trigger();
 101          $result = $sink->get_events();
 102          $event = reset($result);
 103          $sink->close();
 104  
 105          $this->assertEquals($modcontext->id, $event->contextid);
 106          $this->assertEquals($course->id, $event->courseid);
 107  
 108          // Check that an error occurs when teamsubmission is not set.
 109          try {
 110              \mod_assign_unittests\event\submission_created::create($params);
 111              $this->fail('Other must contain the key submissionid.');
 112          } catch (\Exception $e) {
 113              $this->assertInstanceOf('coding_exception', $e);
 114          }
 115          // Check that the submission status debugging is fired.
 116          $subinfo = $params;
 117          $subinfo['other'] = array('submissionid' => '23');
 118          try {
 119              \mod_assign_unittests\event\submission_created::create($subinfo);
 120              $this->fail('Other must contain the key submissionattempt.');
 121          } catch (\Exception $e) {
 122              $this->assertInstanceOf('coding_exception', $e);
 123          }
 124  
 125          $subinfo['other'] = array('submissionattempt' => '0');
 126          try {
 127              \mod_assign_unittests\event\submission_created::create($subinfo);
 128              $this->fail('Other must contain the key submissionstatus.');
 129          } catch (\Exception $e) {
 130              $this->assertInstanceOf('coding_exception', $e);
 131          }
 132      }
 133  
 134      /**
 135       * Basic tests for the submission_updated() abstract class.
 136       */
 137      public function test_submission_updated() {
 138          $this->resetAfterTest();
 139  
 140          $course = $this->getDataGenerator()->create_course();
 141          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
 142          $instance = $generator->create_instance(array('course' => $course->id));
 143          $modcontext = \context_module::instance($instance->cmid);
 144  
 145          // Standard Event parameters.
 146          $params = array(
 147              'context' => $modcontext,
 148              'courseid' => $course->id
 149          );
 150  
 151          $eventinfo = $params;
 152          $eventinfo['other'] = array(
 153              'submissionid' => '17',
 154              'submissionattempt' => 0,
 155              'submissionstatus' => 'submitted'
 156          );
 157  
 158          $sink = $this->redirectEvents();
 159          $event = \mod_assign_unittests\event\submission_updated::create($eventinfo);
 160          $event->trigger();
 161          $result = $sink->get_events();
 162          $event = reset($result);
 163          $sink->close();
 164  
 165          $this->assertEquals($modcontext->id, $event->contextid);
 166          $this->assertEquals($course->id, $event->courseid);
 167  
 168          // Check that an error occurs when teamsubmission is not set.
 169          try {
 170              \mod_assign_unittests\event\submission_created::create($params);
 171              $this->fail('Other must contain the key submissionid.');
 172          } catch (\Exception $e) {
 173              $this->assertInstanceOf('coding_exception', $e);
 174          }
 175          // Check that the submission status debugging is fired.
 176          $subinfo = $params;
 177          $subinfo['other'] = array('submissionid' => '23');
 178          try {
 179              \mod_assign_unittests\event\submission_created::create($subinfo);
 180              $this->fail('Other must contain the key submissionattempt.');
 181          } catch (\Exception $e) {
 182              $this->assertInstanceOf('coding_exception', $e);
 183          }
 184  
 185          $subinfo['other'] = array('submissionattempt' => '0');
 186          try {
 187              \mod_assign_unittests\event\submission_created::create($subinfo);
 188              $this->fail('Other must contain the key submissionstatus.');
 189          } catch (\Exception $e) {
 190              $this->assertInstanceOf('coding_exception', $e);
 191          }
 192      }
 193  
 194      public function test_extension_granted() {
 195          $this->resetAfterTest();
 196  
 197          $course = $this->getDataGenerator()->create_course();
 198          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 199          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 200  
 201          $this->setUser($teacher);
 202  
 203          $now = time();
 204          $tomorrow = $now + DAYSECS;
 205          $yesterday = $now - DAYSECS;
 206  
 207          $assign = $this->create_instance($course, [
 208              'duedate' => $yesterday,
 209              'cutoffdate' => $yesterday,
 210          ]);
 211          $sink = $this->redirectEvents();
 212  
 213          $assign->testable_save_user_extension($student->id, $tomorrow);
 214  
 215          $events = $sink->get_events();
 216          $this->assertCount(1, $events);
 217          $event = reset($events);
 218          $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
 219          $this->assertEquals($assign->get_context(), $event->get_context());
 220          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 221          $this->assertEquals($student->id, $event->relateduserid);
 222  
 223          $expected = array(
 224              $assign->get_course()->id,
 225              'assign',
 226              'grant extension',
 227              'view.php?id=' . $assign->get_course_module()->id,
 228              $student->id,
 229              $assign->get_course_module()->id
 230          );
 231          $this->assertEventLegacyLogData($expected, $event);
 232          $sink->close();
 233      }
 234  
 235      public function test_submission_locked() {
 236          $this->resetAfterTest();
 237  
 238          $course = $this->getDataGenerator()->create_course();
 239          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 240          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 241  
 242          $teacher->ignoresesskey = true;
 243          $this->setUser($teacher);
 244  
 245          $assign = $this->create_instance($course);
 246          $sink = $this->redirectEvents();
 247  
 248          $assign->lock_submission($student->id);
 249  
 250          $events = $sink->get_events();
 251          $this->assertCount(1, $events);
 252          $event = reset($events);
 253          $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
 254          $this->assertEquals($assign->get_context(), $event->get_context());
 255          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 256          $this->assertEquals($student->id, $event->relateduserid);
 257          $expected = array(
 258              $assign->get_course()->id,
 259              'assign',
 260              'lock submission',
 261              'view.php?id=' . $assign->get_course_module()->id,
 262              get_string('locksubmissionforstudent', 'assign', array('id' => $student->id,
 263                  'fullname' => fullname($student))),
 264              $assign->get_course_module()->id
 265          );
 266          $this->assertEventLegacyLogData($expected, $event);
 267          $sink->close();
 268      }
 269  
 270      public function test_identities_revealed() {
 271          $this->resetAfterTest();
 272  
 273          $course = $this->getDataGenerator()->create_course();
 274          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 275  
 276          $teacher->ignoresesskey = true;
 277          $this->setUser($teacher);
 278  
 279          $assign = $this->create_instance($course, ['blindmarking' => 1]);
 280          $sink = $this->redirectEvents();
 281  
 282          $assign->reveal_identities();
 283  
 284          $events = $sink->get_events();
 285          $eventscount = 0;
 286  
 287          foreach ($events as $event) {
 288              if ($event instanceof \mod_assign\event\identities_revealed) {
 289                  $eventscount++;
 290                  $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
 291                  $this->assertEquals($assign->get_context(), $event->get_context());
 292                  $this->assertEquals($assign->get_instance()->id, $event->objectid);
 293                  $expected = array(
 294                      $assign->get_course()->id,
 295                      'assign',
 296                      'reveal identities',
 297                      'view.php?id=' . $assign->get_course_module()->id,
 298                      get_string('revealidentities', 'assign'),
 299                      $assign->get_course_module()->id
 300                  );
 301                  $this->assertEventLegacyLogData($expected, $event);
 302              }
 303          }
 304  
 305          $this->assertEquals(1, $eventscount);
 306          $sink->close();
 307      }
 308  
 309      /**
 310       * Test the submission_status_viewed event.
 311       */
 312      public function test_submission_status_viewed() {
 313          global $PAGE;
 314          $this->resetAfterTest();
 315  
 316          $course = $this->getDataGenerator()->create_course();
 317          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 318  
 319          $this->setUser($teacher);
 320  
 321          $assign = $this->create_instance($course);
 322  
 323          // We need to set the URL in order to view the feedback.
 324          $PAGE->set_url('/a_url');
 325  
 326          // Trigger and capture the event.
 327          $sink = $this->redirectEvents();
 328          $assign->view();
 329          $events = $sink->get_events();
 330          $this->assertCount(1, $events);
 331          $event = reset($events);
 332  
 333          // Check that the event contains the expected values.
 334          $this->assertInstanceOf('\mod_assign\event\submission_status_viewed', $event);
 335          $this->assertEquals($assign->get_context(), $event->get_context());
 336          $expected = array(
 337              $assign->get_course()->id,
 338              'assign',
 339              'view',
 340              'view.php?id=' . $assign->get_course_module()->id,
 341              get_string('viewownsubmissionstatus', 'assign'),
 342              $assign->get_course_module()->id
 343          );
 344          $this->assertEventLegacyLogData($expected, $event);
 345          $this->assertEventContextNotUsed($event);
 346      }
 347  
 348      public function test_submission_status_updated() {
 349          $this->resetAfterTest();
 350  
 351          $course = $this->getDataGenerator()->create_course();
 352          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 353          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 354  
 355          $this->setUser($teacher);
 356  
 357          $assign = $this->create_instance($course);
 358          $submission = $assign->get_user_submission($student->id, true);
 359          $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
 360          $assign->testable_update_submission($submission, $student->id, true, false);
 361  
 362          $sink = $this->redirectEvents();
 363          $assign->revert_to_draft($student->id);
 364  
 365          $events = $sink->get_events();
 366          $this->assertCount(2, $events);
 367          $event = $events[1];
 368          $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
 369          $this->assertEquals($assign->get_context(), $event->get_context());
 370          $this->assertEquals($submission->id, $event->objectid);
 371          $this->assertEquals($student->id, $event->relateduserid);
 372          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
 373          $expected = array(
 374              $assign->get_course()->id,
 375              'assign',
 376              'revert submission to draft',
 377              'view.php?id=' . $assign->get_course_module()->id,
 378              get_string('reverttodraftforstudent', 'assign', array('id' => $student->id,
 379                  'fullname' => fullname($student))),
 380              $assign->get_course_module()->id
 381          );
 382          $this->assertEventLegacyLogData($expected, $event);
 383          $sink->close();
 384      }
 385  
 386      public function test_marker_updated() {
 387          $this->resetAfterTest();
 388  
 389          $course = $this->getDataGenerator()->create_course();
 390          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 391          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 392  
 393          $teacher->ignoresesskey = true;
 394          $this->setUser($teacher);
 395  
 396          $assign = $this->create_instance($course);
 397  
 398          $sink = $this->redirectEvents();
 399          $assign->testable_process_set_batch_marking_allocation($student->id, $teacher->id);
 400  
 401          $events = $sink->get_events();
 402          $this->assertCount(1, $events);
 403          $event = reset($events);
 404          $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
 405          $this->assertEquals($assign->get_context(), $event->get_context());
 406          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 407          $this->assertEquals($student->id, $event->relateduserid);
 408          $this->assertEquals($teacher->id, $event->userid);
 409          $this->assertEquals($teacher->id, $event->other['markerid']);
 410          $expected = array(
 411              $assign->get_course()->id,
 412              'assign',
 413              'set marking allocation',
 414              'view.php?id=' . $assign->get_course_module()->id,
 415              get_string('setmarkerallocationforlog', 'assign', array('id' => $student->id,
 416                  'fullname' => fullname($student), 'marker' => fullname($teacher))),
 417              $assign->get_course_module()->id
 418          );
 419          $this->assertEventLegacyLogData($expected, $event);
 420          $sink->close();
 421      }
 422  
 423      public function test_workflow_state_updated() {
 424          $this->resetAfterTest();
 425  
 426          $course = $this->getDataGenerator()->create_course();
 427          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 428          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 429  
 430          $teacher->ignoresesskey = true;
 431          $this->setUser($teacher);
 432  
 433          $assign = $this->create_instance($course);
 434  
 435          // Test process_set_batch_marking_workflow_state.
 436          $sink = $this->redirectEvents();
 437          $assign->testable_process_set_batch_marking_workflow_state($student->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
 438  
 439          $events = $sink->get_events();
 440          $eventcount = 0;
 441          foreach ($events as $event) {
 442              if ($event instanceof \mod_assign\event\submission_graded) {
 443                  $eventcount++;
 444                  $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 445                  $this->assertEquals($assign->get_context(), $event->get_context());
 446              }
 447              if ($event instanceof \mod_assign\event\workflow_state_updated) {
 448                  $eventcount++;
 449                  $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 450                  $this->assertEquals($assign->get_context(), $event->get_context());
 451                  $this->assertEquals($assign->get_instance()->id, $event->objectid);
 452                  $this->assertEquals($student->id, $event->relateduserid);
 453                  $this->assertEquals($teacher->id, $event->userid);
 454                  $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
 455                  $expected = array(
 456                      $assign->get_course()->id,
 457                      'assign',
 458                      'set marking workflow state',
 459                      'view.php?id=' . $assign->get_course_module()->id,
 460                      get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $student->id,
 461                          'fullname' => fullname($student), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW)),
 462                      $assign->get_course_module()->id
 463                  );
 464                  $this->assertEventLegacyLogData($expected, $event);
 465              }
 466          }
 467          $this->assertEquals(2, $eventcount);
 468          $sink->close();
 469  
 470          // Test setting workflow state in apply_grade_to_user.
 471          $sink = $this->redirectEvents();
 472          $data = new \stdClass();
 473          $data->grade = '50.0';
 474          $data->workflowstate = 'readyforrelease';
 475          $assign->testable_apply_grade_to_user($data, $student->id, 0);
 476  
 477          $events = $sink->get_events();
 478          $this->assertCount(4, $events);
 479          $event = reset($events);
 480          $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 481          $this->assertEquals($assign->get_context(), $event->get_context());
 482          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 483          $this->assertEquals($student->id, $event->relateduserid);
 484          $this->assertEquals($teacher->id, $event->userid);
 485          $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE, $event->other['newstate']);
 486          $expected = array(
 487              $assign->get_course()->id,
 488              'assign',
 489              'set marking workflow state',
 490              'view.php?id=' . $assign->get_course_module()->id,
 491              get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $student->id,
 492                  'fullname' => fullname($student), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE)),
 493              $assign->get_course_module()->id
 494          );
 495          $this->assertEventLegacyLogData($expected, $event);
 496          $sink->close();
 497  
 498          // Test setting workflow state in process_save_quick_grades.
 499          $sink = $this->redirectEvents();
 500  
 501          $data = array(
 502              'grademodified_' . $student->id => time(),
 503              'gradeattempt_' . $student->id => '',
 504              'quickgrade_' . $student->id => '60.0',
 505              'quickgrade_' . $student->id . '_workflowstate' => 'inmarking'
 506          );
 507          $assign->testable_process_save_quick_grades($data);
 508  
 509          $events = $sink->get_events();
 510          $this->assertCount(4, $events);
 511          $event = reset($events);
 512          $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 513          $this->assertEquals($assign->get_context(), $event->get_context());
 514          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 515          $this->assertEquals($student->id, $event->relateduserid);
 516          $this->assertEquals($teacher->id, $event->userid);
 517          $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INMARKING, $event->other['newstate']);
 518          $expected = array(
 519              $assign->get_course()->id,
 520              'assign',
 521              'set marking workflow state',
 522              'view.php?id=' . $assign->get_course_module()->id,
 523              get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $student->id,
 524                  'fullname' => fullname($student), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INMARKING)),
 525              $assign->get_course_module()->id
 526          );
 527          $this->assertEventLegacyLogData($expected, $event);
 528          $sink->close();
 529      }
 530  
 531      public function test_submission_duplicated() {
 532          $this->resetAfterTest();
 533  
 534          $course = $this->getDataGenerator()->create_course();
 535          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 536  
 537          $this->setUser($student);
 538  
 539          $assign = $this->create_instance($course);
 540          $submission1 = $assign->get_user_submission($student->id, true, 0);
 541          $submission2 = $assign->get_user_submission($student->id, true, 1);
 542          $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
 543          $assign->testable_update_submission($submission2, $student->id, time(), $assign->get_instance()->teamsubmission);
 544  
 545          $sink = $this->redirectEvents();
 546          $notices = null;
 547          $assign->copy_previous_attempt($notices);
 548  
 549          $events = $sink->get_events();
 550          $this->assertCount(1, $events);
 551          $event = reset($events);
 552          $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
 553          $this->assertEquals($assign->get_context(), $event->get_context());
 554          $this->assertEquals($submission2->id, $event->objectid);
 555          $this->assertEquals($student->id, $event->userid);
 556          $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
 557          $expected = array(
 558              $assign->get_course()->id,
 559              'assign',
 560              'submissioncopied',
 561              'view.php?id=' . $assign->get_course_module()->id,
 562              $assign->testable_format_submission_for_log($submission2),
 563              $assign->get_course_module()->id
 564          );
 565          $this->assertEventLegacyLogData($expected, $event);
 566          $sink->close();
 567      }
 568  
 569      public function test_submission_unlocked() {
 570          $this->resetAfterTest();
 571  
 572          $course = $this->getDataGenerator()->create_course();
 573          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 574          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 575  
 576          $teacher->ignoresesskey = true;
 577          $this->setUser($teacher);
 578  
 579          $assign = $this->create_instance($course);
 580          $sink = $this->redirectEvents();
 581  
 582          $assign->unlock_submission($student->id);
 583  
 584          $events = $sink->get_events();
 585          $this->assertCount(1, $events);
 586          $event = reset($events);
 587          $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
 588          $this->assertEquals($assign->get_context(), $event->get_context());
 589          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 590          $this->assertEquals($student->id, $event->relateduserid);
 591          $expected = array(
 592              $assign->get_course()->id,
 593              'assign',
 594              'unlock submission',
 595              'view.php?id=' . $assign->get_course_module()->id,
 596              get_string('unlocksubmissionforstudent', 'assign', array('id' => $student->id,
 597                  'fullname' => fullname($student))),
 598              $assign->get_course_module()->id
 599          );
 600          $this->assertEventLegacyLogData($expected, $event);
 601          $sink->close();
 602      }
 603  
 604      public function test_submission_graded() {
 605          $this->resetAfterTest();
 606  
 607          $course = $this->getDataGenerator()->create_course();
 608          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 609          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 610  
 611          $teacher->ignoresesskey = true;
 612          $this->setUser($teacher);
 613  
 614          $assign = $this->create_instance($course);
 615  
 616          // Test apply_grade_to_user.
 617          $sink = $this->redirectEvents();
 618  
 619          $data = new \stdClass();
 620          $data->grade = '50.0';
 621          $assign->testable_apply_grade_to_user($data, $student->id, 0);
 622          $grade = $assign->get_user_grade($student->id, false, 0);
 623  
 624          $events = $sink->get_events();
 625          $this->assertCount(3, $events);
 626          $event = $events[2];
 627          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 628          $this->assertEquals($assign->get_context(), $event->get_context());
 629          $this->assertEquals($grade->id, $event->objectid);
 630          $this->assertEquals($student->id, $event->relateduserid);
 631          $expected = array(
 632              $assign->get_course()->id,
 633              'assign',
 634              'grade submission',
 635              'view.php?id=' . $assign->get_course_module()->id,
 636              $assign->format_grade_for_log($grade),
 637              $assign->get_course_module()->id
 638          );
 639          $this->assertEventLegacyLogData($expected, $event);
 640          $sink->close();
 641  
 642          // Test process_save_quick_grades.
 643          $sink = $this->redirectEvents();
 644  
 645          $grade = $assign->get_user_grade($student->id, false);
 646          $data = array(
 647              'grademodified_' . $student->id => time(),
 648              'gradeattempt_' . $student->id => $grade->attemptnumber,
 649              'quickgrade_' . $student->id => '60.0'
 650          );
 651          $assign->testable_process_save_quick_grades($data);
 652          $grade = $assign->get_user_grade($student->id, false);
 653          $this->assertEquals(60.0, $grade->grade);
 654  
 655          $events = $sink->get_events();
 656          $this->assertCount(3, $events);
 657          $event = $events[2];
 658          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 659          $this->assertEquals($assign->get_context(), $event->get_context());
 660          $this->assertEquals($grade->id, $event->objectid);
 661          $this->assertEquals($student->id, $event->relateduserid);
 662          $expected = array(
 663              $assign->get_course()->id,
 664              'assign',
 665              'grade submission',
 666              'view.php?id=' . $assign->get_course_module()->id,
 667              $assign->format_grade_for_log($grade),
 668              $assign->get_course_module()->id
 669          );
 670          $this->assertEventLegacyLogData($expected, $event);
 671          $sink->close();
 672  
 673          // Test update_grade.
 674          $sink = $this->redirectEvents();
 675          $data = clone($grade);
 676          $data->grade = '50.0';
 677          $assign->update_grade($data);
 678          $grade = $assign->get_user_grade($student->id, false, 0);
 679          $this->assertEquals(50.0, $grade->grade);
 680          $events = $sink->get_events();
 681  
 682          $this->assertCount(3, $events);
 683          $event = $events[2];
 684          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 685          $this->assertEquals($assign->get_context(), $event->get_context());
 686          $this->assertEquals($grade->id, $event->objectid);
 687          $this->assertEquals($student->id, $event->relateduserid);
 688          $expected = array(
 689              $assign->get_course()->id,
 690              'assign',
 691              'grade submission',
 692              'view.php?id=' . $assign->get_course_module()->id,
 693              $assign->format_grade_for_log($grade),
 694              $assign->get_course_module()->id
 695          );
 696          $this->assertEventLegacyLogData($expected, $event);
 697          $sink->close();
 698      }
 699  
 700      /**
 701       * Test the submission_viewed event.
 702       */
 703      public function test_submission_viewed() {
 704          global $PAGE;
 705  
 706          $this->resetAfterTest();
 707  
 708          $course = $this->getDataGenerator()->create_course();
 709          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 710          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 711  
 712          $this->setUser($teacher);
 713  
 714          $assign = $this->create_instance($course);
 715          $submission = $assign->get_user_submission($student->id, true);
 716  
 717          // We need to set the URL in order to view the submission.
 718          $PAGE->set_url('/a_url');
 719          // A hack - these variables are used by the view_plugin_content function to
 720          // determine what we actually want to view - would usually be set in URL.
 721          global $_POST;
 722          $_POST['plugin'] = 'comments';
 723          $_POST['sid'] = $submission->id;
 724  
 725          // Trigger and capture the event.
 726          $sink = $this->redirectEvents();
 727          $assign->view('viewpluginassignsubmission');
 728          $events = $sink->get_events();
 729          $this->assertCount(1, $events);
 730          $event = reset($events);
 731  
 732          // Check that the event contains the expected values.
 733          $this->assertInstanceOf('\mod_assign\event\submission_viewed', $event);
 734          $this->assertEquals($assign->get_context(), $event->get_context());
 735          $this->assertEquals($submission->id, $event->objectid);
 736          $expected = array(
 737              $assign->get_course()->id,
 738              'assign',
 739              'view submission',
 740              'view.php?id=' . $assign->get_course_module()->id,
 741              get_string('viewsubmissionforuser', 'assign', $student->id),
 742              $assign->get_course_module()->id
 743          );
 744          $this->assertEventLegacyLogData($expected, $event);
 745          $this->assertEventContextNotUsed($event);
 746      }
 747  
 748      /**
 749       * Test the feedback_viewed event.
 750       */
 751      public function test_feedback_viewed() {
 752          global $DB, $PAGE;
 753  
 754          $this->resetAfterTest();
 755  
 756          $course = $this->getDataGenerator()->create_course();
 757          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 758          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 759  
 760          $this->setUser($teacher);
 761  
 762          $assign = $this->create_instance($course);
 763          $submission = $assign->get_user_submission($student->id, true);
 764  
 765          // Insert a grade for this submission.
 766          $grade = new \stdClass();
 767          $grade->assignment = $assign->get_instance()->id;
 768          $grade->userid = $student->id;
 769          $gradeid = $DB->insert_record('assign_grades', $grade);
 770  
 771          // We need to set the URL in order to view the feedback.
 772          $PAGE->set_url('/a_url');
 773          // A hack - these variables are used by the view_plugin_content function to
 774          // determine what we actually want to view - would usually be set in URL.
 775          global $_POST;
 776          $_POST['plugin'] = 'comments';
 777          $_POST['gid'] = $gradeid;
 778          $_POST['sid'] = $submission->id;
 779  
 780          // Trigger and capture the event.
 781          $sink = $this->redirectEvents();
 782          $assign->view('viewpluginassignfeedback');
 783          $events = $sink->get_events();
 784          $this->assertCount(1, $events);
 785          $event = reset($events);
 786  
 787          // Check that the event contains the expected values.
 788          $this->assertInstanceOf('\mod_assign\event\feedback_viewed', $event);
 789          $this->assertEquals($assign->get_context(), $event->get_context());
 790          $this->assertEquals($gradeid, $event->objectid);
 791          $expected = array(
 792              $assign->get_course()->id,
 793              'assign',
 794              'view feedback',
 795              'view.php?id=' . $assign->get_course_module()->id,
 796              get_string('viewfeedbackforuser', 'assign', $student->id),
 797              $assign->get_course_module()->id
 798          );
 799          $this->assertEventLegacyLogData($expected, $event);
 800          $this->assertEventContextNotUsed($event);
 801      }
 802  
 803      /**
 804       * Test the grading_form_viewed event.
 805       */
 806      public function test_grading_form_viewed() {
 807          global $PAGE;
 808  
 809          $this->resetAfterTest();
 810  
 811          $course = $this->getDataGenerator()->create_course();
 812          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 813          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 814  
 815          $this->setUser($teacher);
 816  
 817          $assign = $this->create_instance($course);
 818  
 819          // We need to set the URL in order to view the feedback.
 820          $PAGE->set_url('/a_url');
 821          // A hack - this variable is used by the view_single_grade_page function.
 822          global $_POST;
 823          $_POST['rownum'] = 1;
 824          $_POST['userid'] = $student->id;
 825  
 826          // Trigger and capture the event.
 827          $sink = $this->redirectEvents();
 828          $assign->view('grade');
 829          $events = $sink->get_events();
 830          $this->assertCount(1, $events);
 831          $event = reset($events);
 832  
 833          // Check that the event contains the expected values.
 834          $this->assertInstanceOf('\mod_assign\event\grading_form_viewed', $event);
 835          $this->assertEquals($assign->get_context(), $event->get_context());
 836          $expected = array(
 837              $assign->get_course()->id,
 838              'assign',
 839              'view grading form',
 840              'view.php?id=' . $assign->get_course_module()->id,
 841              get_string('viewgradingformforstudent', 'assign', array('id' => $student->id,
 842                  'fullname' => fullname($student))),
 843              $assign->get_course_module()->id
 844          );
 845          $this->assertEventLegacyLogData($expected, $event);
 846          $this->assertEventContextNotUsed($event);
 847      }
 848  
 849      /**
 850       * Test the grading_table_viewed event.
 851       */
 852      public function test_grading_table_viewed() {
 853          global $PAGE;
 854  
 855          $this->resetAfterTest();
 856  
 857          $course = $this->getDataGenerator()->create_course();
 858          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 859          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 860  
 861          $this->setUser($teacher);
 862  
 863          $assign = $this->create_instance($course);
 864  
 865          // We need to set the URL in order to view the feedback.
 866          $PAGE->set_url('/a_url');
 867          // A hack - this variable is used by the view_single_grade_page function.
 868          global $_POST;
 869          $_POST['rownum'] = 1;
 870          $_POST['userid'] = $student->id;
 871  
 872          // Trigger and capture the event.
 873          $sink = $this->redirectEvents();
 874          $assign->view('grading');
 875          $events = $sink->get_events();
 876          $this->assertCount(1, $events);
 877          $event = reset($events);
 878  
 879          // Check that the event contains the expected values.
 880          $this->assertInstanceOf('\mod_assign\event\grading_table_viewed', $event);
 881          $this->assertEquals($assign->get_context(), $event->get_context());
 882          $expected = array(
 883              $assign->get_course()->id,
 884              'assign',
 885              'view submission grading table',
 886              'view.php?id=' . $assign->get_course_module()->id,
 887              get_string('viewsubmissiongradingtable', 'assign'),
 888              $assign->get_course_module()->id
 889          );
 890          $this->assertEventLegacyLogData($expected, $event);
 891          $this->assertEventContextNotUsed($event);
 892      }
 893  
 894      /**
 895       * Test the submission_form_viewed event.
 896       */
 897      public function test_submission_form_viewed() {
 898          global $PAGE;
 899  
 900          $this->resetAfterTest();
 901  
 902          $course = $this->getDataGenerator()->create_course();
 903          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 904  
 905          $this->setUser($student);
 906  
 907          $assign = $this->create_instance($course);
 908  
 909          // We need to set the URL in order to view the submission form.
 910          $PAGE->set_url('/a_url');
 911  
 912          // Trigger and capture the event.
 913          $sink = $this->redirectEvents();
 914          $assign->view('editsubmission');
 915          $events = $sink->get_events();
 916          $this->assertCount(1, $events);
 917          $event = reset($events);
 918  
 919          // Check that the event contains the expected values.
 920          $this->assertInstanceOf('\mod_assign\event\submission_form_viewed', $event);
 921          $this->assertEquals($assign->get_context(), $event->get_context());
 922          $expected = array(
 923              $assign->get_course()->id,
 924              'assign',
 925              'view submit assignment form',
 926              'view.php?id=' . $assign->get_course_module()->id,
 927              get_string('editsubmission', 'assign'),
 928              $assign->get_course_module()->id
 929          );
 930          $this->assertEventLegacyLogData($expected, $event);
 931          $this->assertEventContextNotUsed($event);
 932      }
 933  
 934      /**
 935       * Test the submission_form_viewed event.
 936       */
 937      public function test_submission_confirmation_form_viewed() {
 938          global $PAGE;
 939  
 940          $this->resetAfterTest();
 941  
 942          $course = $this->getDataGenerator()->create_course();
 943          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 944  
 945          $this->setUser($student);
 946  
 947          $assign = $this->create_instance($course);
 948  
 949          // We need to set the URL in order to view the submission form.
 950          $PAGE->set_url('/a_url');
 951  
 952          // Trigger and capture the event.
 953          $sink = $this->redirectEvents();
 954          $assign->view('submit');
 955          $events = $sink->get_events();
 956          $this->assertCount(1, $events);
 957          $event = reset($events);
 958  
 959          // Check that the event contains the expected values.
 960          $this->assertInstanceOf('\mod_assign\event\submission_confirmation_form_viewed', $event);
 961          $this->assertEquals($assign->get_context(), $event->get_context());
 962          $expected = array(
 963              $assign->get_course()->id,
 964              'assign',
 965              'view confirm submit assignment form',
 966              'view.php?id=' . $assign->get_course_module()->id,
 967              get_string('viewownsubmissionform', 'assign'),
 968              $assign->get_course_module()->id
 969          );
 970          $this->assertEventLegacyLogData($expected, $event);
 971          $this->assertEventContextNotUsed($event);
 972      }
 973  
 974      /**
 975       * Test the reveal_identities_confirmation_page_viewed event.
 976       */
 977      public function test_reveal_identities_confirmation_page_viewed() {
 978          global $PAGE;
 979          $this->resetAfterTest();
 980  
 981          // Set to the admin user so we have the permission to reveal identities.
 982          $this->setAdminUser();
 983  
 984          $course = $this->getDataGenerator()->create_course();
 985          $assign = $this->create_instance($course);
 986  
 987          // We need to set the URL in order to view the submission form.
 988          $PAGE->set_url('/a_url');
 989  
 990          // Trigger and capture the event.
 991          $sink = $this->redirectEvents();
 992          $assign->view('revealidentities');
 993          $events = $sink->get_events();
 994          $this->assertCount(1, $events);
 995          $event = reset($events);
 996  
 997          // Check that the event contains the expected values.
 998          $this->assertInstanceOf('\mod_assign\event\reveal_identities_confirmation_page_viewed', $event);
 999          $this->assertEquals($assign->get_context(), $event->get_context());
1000          $expected = array(
1001              $assign->get_course()->id,
1002              'assign',
1003              'view',
1004              'view.php?id=' . $assign->get_course_module()->id,
1005              get_string('viewrevealidentitiesconfirm', 'assign'),
1006              $assign->get_course_module()->id
1007          );
1008          $this->assertEventLegacyLogData($expected, $event);
1009          $this->assertEventContextNotUsed($event);
1010      }
1011  
1012      /**
1013       * Test the statement_accepted event.
1014       */
1015      public function test_statement_accepted() {
1016          // We want to be a student so we can submit assignments.
1017          $this->resetAfterTest();
1018  
1019          $course = $this->getDataGenerator()->create_course();
1020          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
1021  
1022          $this->setUser($student);
1023  
1024          // We do not want to send any messages to the student during the PHPUNIT test.
1025          set_config('submissionreceipts', false, 'assign');
1026  
1027          $assign = $this->create_instance($course);
1028  
1029          // Create the data we want to pass to the submit_for_grading function.
1030          $data = new \stdClass();
1031          $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
1032              to these terms?';
1033  
1034          // Trigger and capture the event.
1035          $sink = $this->redirectEvents();
1036          $assign->submit_for_grading($data, array());
1037          $events = $sink->get_events();
1038          $event = reset($events);
1039  
1040          // Check that the event contains the expected values.
1041          $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
1042          $this->assertEquals($assign->get_context(), $event->get_context());
1043          $expected = array(
1044              $assign->get_course()->id,
1045              'assign',
1046              'submission statement accepted',
1047              'view.php?id=' . $assign->get_course_module()->id,
1048              get_string('submissionstatementacceptedlog',
1049                  'mod_assign',
1050                  fullname($student)),
1051              $assign->get_course_module()->id
1052          );
1053          $this->assertEventLegacyLogData($expected, $event);
1054          $this->assertEventContextNotUsed($event);
1055  
1056          // Enable the online text submission plugin.
1057          $submissionplugins = $assign->get_submission_plugins();
1058          foreach ($submissionplugins as $plugin) {
1059              if ($plugin->get_type() === 'onlinetext') {
1060                  $plugin->enable();
1061                  break;
1062              }
1063          }
1064  
1065          // Create the data we want to pass to the save_submission function.
1066          $data = new \stdClass();
1067          $data->onlinetext_editor = array(
1068              'text' => 'Online text',
1069              'format' => FORMAT_HTML,
1070              'itemid' => file_get_unused_draft_itemid()
1071          );
1072          $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
1073              to these terms?';
1074  
1075          // Trigger and capture the event.
1076          $sink = $this->redirectEvents();
1077          $assign->save_submission($data, $notices);
1078          $events = $sink->get_events();
1079          $event = $events[2];
1080  
1081          // Check that the event contains the expected values.
1082          $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
1083          $this->assertEquals($assign->get_context(), $event->get_context());
1084          $this->assertEventLegacyLogData($expected, $event);
1085          $this->assertEventContextNotUsed($event);
1086      }
1087  
1088      /**
1089       * Test the batch_set_workflow_state_viewed event.
1090       */
1091      public function test_batch_set_workflow_state_viewed() {
1092          $this->resetAfterTest();
1093  
1094          $course = $this->getDataGenerator()->create_course();
1095          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
1096          $assign = $this->create_instance($course);
1097  
1098          // Trigger and capture the event.
1099          $sink = $this->redirectEvents();
1100          $assign->testable_view_batch_set_workflow_state($student->id);
1101          $events = $sink->get_events();
1102          $event = reset($events);
1103  
1104          // Check that the event contains the expected values.
1105          $this->assertInstanceOf('\mod_assign\event\batch_set_workflow_state_viewed', $event);
1106          $this->assertEquals($assign->get_context(), $event->get_context());
1107          $expected = array(
1108              $assign->get_course()->id,
1109              'assign',
1110              'view batch set marking workflow state',
1111              'view.php?id=' . $assign->get_course_module()->id,
1112              get_string('viewbatchsetmarkingworkflowstate', 'assign'),
1113              $assign->get_course_module()->id
1114          );
1115          $this->assertEventLegacyLogData($expected, $event);
1116          $this->assertEventContextNotUsed($event);
1117      }
1118  
1119      /**
1120       * Test the batch_set_marker_allocation_viewed event.
1121       */
1122      public function test_batch_set_marker_allocation_viewed() {
1123          $this->resetAfterTest();
1124  
1125          $course = $this->getDataGenerator()->create_course();
1126          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
1127          $assign = $this->create_instance($course);
1128  
1129          // Trigger and capture the event.
1130          $sink = $this->redirectEvents();
1131          $assign->testable_view_batch_markingallocation($student->id);
1132          $events = $sink->get_events();
1133          $event = reset($events);
1134  
1135          // Check that the event contains the expected values.
1136          $this->assertInstanceOf('\mod_assign\event\batch_set_marker_allocation_viewed', $event);
1137          $this->assertEquals($assign->get_context(), $event->get_context());
1138          $expected = array(
1139              $assign->get_course()->id,
1140              'assign',
1141              'view batch set marker allocation',
1142              'view.php?id=' . $assign->get_course_module()->id,
1143              get_string('viewbatchmarkingallocation', 'assign'),
1144              $assign->get_course_module()->id
1145          );
1146          $this->assertEventLegacyLogData($expected, $event);
1147          $this->assertEventContextNotUsed($event);
1148      }
1149  
1150      /**
1151       * Test the user override created event.
1152       *
1153       * There is no external API for creating a user override, so the unit test will simply
1154       * create and trigger the event and ensure the event data is returned as expected.
1155       */
1156      public function test_user_override_created() {
1157          $this->resetAfterTest();
1158  
1159          $course = $this->getDataGenerator()->create_course();
1160          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1161  
1162          $params = array(
1163              'objectid' => 1,
1164              'relateduserid' => 2,
1165              'context' => \context_module::instance($assign->cmid),
1166              'other' => array(
1167                  'assignid' => $assign->id
1168              )
1169          );
1170          $event = \mod_assign\event\user_override_created::create($params);
1171  
1172          // Trigger and capture the event.
1173          $sink = $this->redirectEvents();
1174          $event->trigger();
1175          $events = $sink->get_events();
1176          $event = reset($events);
1177  
1178          // Check that the event data is valid.
1179          $this->assertInstanceOf('\mod_assign\event\user_override_created', $event);
1180          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1181          $this->assertEventContextNotUsed($event);
1182      }
1183  
1184      /**
1185       * Test the group override created event.
1186       *
1187       * There is no external API for creating a group override, so the unit test will simply
1188       * create and trigger the event and ensure the event data is returned as expected.
1189       */
1190      public function test_group_override_created() {
1191          $this->resetAfterTest();
1192  
1193          $course = $this->getDataGenerator()->create_course();
1194          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1195  
1196          $params = array(
1197              'objectid' => 1,
1198              'context' => \context_module::instance($assign->cmid),
1199              'other' => array(
1200                  'assignid' => $assign->id,
1201                  'groupid' => 2
1202              )
1203          );
1204          $event = \mod_assign\event\group_override_created::create($params);
1205  
1206          // Trigger and capture the event.
1207          $sink = $this->redirectEvents();
1208          $event->trigger();
1209          $events = $sink->get_events();
1210          $event = reset($events);
1211  
1212          // Check that the event data is valid.
1213          $this->assertInstanceOf('\mod_assign\event\group_override_created', $event);
1214          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1215          $this->assertEventContextNotUsed($event);
1216      }
1217  
1218      /**
1219       * Test the user override updated event.
1220       *
1221       * There is no external API for updating a user override, so the unit test will simply
1222       * create and trigger the event and ensure the event data is returned as expected.
1223       */
1224      public function test_user_override_updated() {
1225          $this->resetAfterTest();
1226  
1227          $course = $this->getDataGenerator()->create_course();
1228          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1229  
1230          $params = array(
1231              'objectid' => 1,
1232              'relateduserid' => 2,
1233              'context' => \context_module::instance($assign->cmid),
1234              'other' => array(
1235                  'assignid' => $assign->id
1236              )
1237          );
1238          $event = \mod_assign\event\user_override_updated::create($params);
1239  
1240          // Trigger and capture the event.
1241          $sink = $this->redirectEvents();
1242          $event->trigger();
1243          $events = $sink->get_events();
1244          $event = reset($events);
1245  
1246          // Check that the event data is valid.
1247          $this->assertInstanceOf('\mod_assign\event\user_override_updated', $event);
1248          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1249          $this->assertEventContextNotUsed($event);
1250      }
1251  
1252      /**
1253       * Test the group override updated event.
1254       *
1255       * There is no external API for updating a group override, so the unit test will simply
1256       * create and trigger the event and ensure the event data is returned as expected.
1257       */
1258      public function test_group_override_updated() {
1259          $this->resetAfterTest();
1260  
1261          $course = $this->getDataGenerator()->create_course();
1262          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1263  
1264          $params = array(
1265              'objectid' => 1,
1266              'context' => \context_module::instance($assign->cmid),
1267              'other' => array(
1268                  'assignid' => $assign->id,
1269                  'groupid' => 2
1270              )
1271          );
1272          $event = \mod_assign\event\group_override_updated::create($params);
1273  
1274          // Trigger and capture the event.
1275          $sink = $this->redirectEvents();
1276          $event->trigger();
1277          $events = $sink->get_events();
1278          $event = reset($events);
1279  
1280          // Check that the event data is valid.
1281          $this->assertInstanceOf('\mod_assign\event\group_override_updated', $event);
1282          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1283          $this->assertEventContextNotUsed($event);
1284      }
1285  
1286      /**
1287       * Test the user override deleted event.
1288       */
1289      public function test_user_override_deleted() {
1290          global $DB;
1291          $this->resetAfterTest();
1292  
1293          $course = $this->getDataGenerator()->create_course();
1294          $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1295          $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1296          $context = \context_module::instance($cm->id);
1297          $assign = new \assign($context, $cm, $course);
1298  
1299          // Create an override.
1300          $override = new \stdClass();
1301          $override->assign = $assigninstance->id;
1302          $override->userid = 2;
1303          $override->id = $DB->insert_record('assign_overrides', $override);
1304  
1305          // Trigger and capture the event.
1306          $sink = $this->redirectEvents();
1307          $assign->delete_override($override->id);
1308          $events = $sink->get_events();
1309          $event = reset($events);
1310  
1311          // Check that the event data is valid.
1312          $this->assertInstanceOf('\mod_assign\event\user_override_deleted', $event);
1313          $this->assertEquals(\context_module::instance($cm->id), $event->get_context());
1314          $this->assertEventContextNotUsed($event);
1315      }
1316  
1317      /**
1318       * Test the group override deleted event.
1319       */
1320      public function test_group_override_deleted() {
1321          global $DB;
1322          $this->resetAfterTest();
1323  
1324          $course = $this->getDataGenerator()->create_course();
1325          $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1326          $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1327          $context = \context_module::instance($cm->id);
1328          $assign = new \assign($context, $cm, $course);
1329  
1330          // Create an override.
1331          $override = new \stdClass();
1332          $override->assign = $assigninstance->id;
1333          $override->groupid = 2;
1334          $override->id = $DB->insert_record('assign_overrides', $override);
1335  
1336          // Trigger and capture the event.
1337          $sink = $this->redirectEvents();
1338          $assign->delete_override($override->id);
1339          $events = $sink->get_events();
1340          $event = reset($events);
1341  
1342          // Check that the event data is valid.
1343          $this->assertInstanceOf('\mod_assign\event\group_override_deleted', $event);
1344          $this->assertEquals(\context_module::instance($cm->id), $event->get_context());
1345          $this->assertEventContextNotUsed($event);
1346      }
1347  
1348      /**
1349       * Test the course module viewed event.
1350       */
1351      public function test_course_module_viewed() {
1352          $this->resetAfterTest();
1353  
1354          $course = $this->getDataGenerator()->create_course();
1355          $assign = $this->create_instance($course);
1356  
1357          $context = $assign->get_context();
1358  
1359          $params = array(
1360              'context' => $context,
1361              'objectid' => $assign->get_instance()->id
1362          );
1363  
1364          $event = \mod_assign\event\course_module_viewed::create($params);
1365  
1366          // Trigger and capture the event.
1367          $sink = $this->redirectEvents();
1368          $event->trigger();
1369          $events = $sink->get_events();
1370          $this->assertCount(1, $events);
1371          $event = reset($events);
1372  
1373          // Check that the event contains the expected values.
1374          $this->assertInstanceOf('\mod_assign\event\course_module_viewed', $event);
1375          $this->assertEquals($context, $event->get_context());
1376      }
1377  
1378      /**
1379       * Test that all events generated with blindmarking enabled are anonymous
1380       */
1381      public function test_anonymous_events() {
1382          $this->resetAfterTest();
1383  
1384          $course = $this->getDataGenerator()->create_course();
1385          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
1386          $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
1387          $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
1388  
1389          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1390          $instance = $generator->create_instance(array('course' => $course->id, 'blindmarking' => 1));
1391  
1392          $cm = get_coursemodule_from_instance('assign', $instance->id, $course->id);
1393          $context = \context_module::instance($cm->id);
1394          $assign = new \assign($context, $cm, $course);
1395  
1396          $this->setUser($teacher);
1397          $sink = $this->redirectEvents();
1398  
1399          $assign->lock_submission($student1->id);
1400  
1401          $events = $sink->get_events();
1402          $event = reset($events);
1403  
1404          $this->assertTrue((bool)$event->anonymous);
1405  
1406          $assign->reveal_identities();
1407          $sink = $this->redirectEvents();
1408          $assign->lock_submission($student2->id);
1409  
1410          $events = $sink->get_events();
1411          $event = reset($events);
1412  
1413          $this->assertFalse((bool)$event->anonymous);
1414      }
1415  
1416  }