Search moodle.org's
Developer Documentation

See Release Notes

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

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

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * 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      /**
 195       * Test submission_removed event.
 196       *
 197       * @covers \mod_assign\event\submission_removed
 198       */
 199      public function test_submission_removed() {
 200          $this->resetAfterTest();
 201  
 202          $course = $this->getDataGenerator()->create_course();
 203          $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 204          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 205  
 206          $assign = $this->create_instance($course);
 207          $this->add_submission($student, $assign);
 208          $submission = $assign->get_user_submission($student->id, 0);
 209  
 210          $sink = $this->redirectEvents();
 211          $assign->remove_submission($student->id);
 212          $events = $sink->get_events();
 213          $this->assertCount(2, $events);
 214          $event = $events[0];
 215          $this->assertInstanceOf('mod_assign\event\submission_removed', $event);
 216          $this->assertEquals($assign->get_context(), $event->get_context());
 217          $this->assertEquals($submission->id, $event->objectid);
 218          $this->assertEquals($student->id, $event->relateduserid);
 219          $this->assertEquals($submission->id, $event->other['submissionid']);
 220          $this->assertEquals(0, $event->other['submissionattempt']);
 221          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_NEW, $event->other['submissionstatus']);
 222          $this->assertEquals(0, $event->other['groupid']);
 223          $this->assertEquals(null, $event->other['groupname']);
 224          $sink->close();
 225      }
 226  
 227      /**
 228       * Test submission_removed event when a team submission is removed.
 229       *
 230       * @covers \mod_assign\event\submission_removed
 231       */
 232      public function test_team_submission_removed() {
 233          $this->resetAfterTest();
 234  
 235          $course = $this->getDataGenerator()->create_course();
 236          $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 237          $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
 238  
 239          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 240          groups_add_member($group, $student);
 241  
 242          $otherstudent = $this->getDataGenerator()->create_and_enrol($course, 'student');
 243          groups_add_member($group, $otherstudent);
 244  
 245          $assign = $this->create_instance($course, [
 246              'teamsubmission' => 1,
 247          ]);
 248          $this->add_submission($student, $assign);
 249          $submission = $assign->get_group_submission($student->id, 0, true);
 250  
 251          $sink = $this->redirectEvents();
 252          $assign->remove_submission($student->id);
 253          $events = $sink->get_events();
 254          $this->assertCount(2, $events);
 255          $event = $events[0];
 256          $this->assertInstanceOf('mod_assign\event\submission_removed', $event);
 257          $this->assertEquals($assign->get_context(), $event->get_context());
 258          $this->assertEquals($submission->id, $event->objectid);
 259          $this->assertEquals(null, $event->relateduserid);
 260          $this->assertEquals($submission->id, $event->other['submissionid']);
 261          $this->assertEquals(0, $event->other['submissionattempt']);
 262          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_NEW, $event->other['submissionstatus']);
 263          $this->assertEquals($group->id, $event->other['groupid']);
 264          $this->assertEquals($group->name, $event->other['groupname']);
 265          $sink->close();
 266      }
 267  
 268      public function test_extension_granted() {
 269          $this->resetAfterTest();
 270  
 271          $course = $this->getDataGenerator()->create_course();
 272          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 273          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 274  
 275          $this->setUser($teacher);
 276  
 277          $now = time();
 278          $tomorrow = $now + DAYSECS;
 279          $yesterday = $now - DAYSECS;
 280  
 281          $assign = $this->create_instance($course, [
 282              'duedate' => $yesterday,
 283              'cutoffdate' => $yesterday,
 284          ]);
 285          $sink = $this->redirectEvents();
 286  
 287          $assign->testable_save_user_extension($student->id, $tomorrow);
 288  
 289          $events = $sink->get_events();
 290          $this->assertCount(1, $events);
 291          $event = reset($events);
 292          $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
 293          $this->assertEquals($assign->get_context(), $event->get_context());
 294          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 295          $this->assertEquals($student->id, $event->relateduserid);
 296          $sink->close();
 297      }
 298  
 299      public function test_submission_locked() {
 300          $this->resetAfterTest();
 301  
 302          $course = $this->getDataGenerator()->create_course();
 303          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 304          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 305  
 306          $teacher->ignoresesskey = true;
 307          $this->setUser($teacher);
 308  
 309          $assign = $this->create_instance($course);
 310          $sink = $this->redirectEvents();
 311  
 312          $assign->lock_submission($student->id);
 313  
 314          $events = $sink->get_events();
 315          $this->assertCount(1, $events);
 316          $event = reset($events);
 317          $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
 318          $this->assertEquals($assign->get_context(), $event->get_context());
 319          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 320          $this->assertEquals($student->id, $event->relateduserid);
 321          $sink->close();
 322      }
 323  
 324      public function test_identities_revealed() {
 325          $this->resetAfterTest();
 326  
 327          $course = $this->getDataGenerator()->create_course();
 328          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 329  
 330          $teacher->ignoresesskey = true;
 331          $this->setUser($teacher);
 332  
 333          $assign = $this->create_instance($course, ['blindmarking' => 1]);
 334          $sink = $this->redirectEvents();
 335  
 336          $assign->reveal_identities();
 337  
 338          $events = $sink->get_events();
 339          $eventscount = 0;
 340  
 341          foreach ($events as $event) {
 342              if ($event instanceof \mod_assign\event\identities_revealed) {
 343                  $eventscount++;
 344                  $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
 345                  $this->assertEquals($assign->get_context(), $event->get_context());
 346                  $this->assertEquals($assign->get_instance()->id, $event->objectid);
 347              }
 348          }
 349  
 350          $this->assertEquals(1, $eventscount);
 351          $sink->close();
 352      }
 353  
 354      /**
 355       * Test the submission_status_viewed event.
 356       */
 357      public function test_submission_status_viewed() {
 358          global $PAGE;
 359          $this->resetAfterTest();
 360  
 361          $course = $this->getDataGenerator()->create_course();
 362          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 363  
 364          $this->setUser($teacher);
 365  
 366          $assign = $this->create_instance($course);
 367  
 368          // We need to set the URL in order to view the feedback.
 369          $PAGE->set_url('/a_url');
 370  
 371          // Trigger and capture the event.
 372          $sink = $this->redirectEvents();
 373          $assign->view();
 374          $events = $sink->get_events();
 375          $this->assertCount(1, $events);
 376          $event = reset($events);
 377  
 378          // Check that the event contains the expected values.
 379          $this->assertInstanceOf('\mod_assign\event\submission_status_viewed', $event);
 380          $this->assertEquals($assign->get_context(), $event->get_context());
 381      }
 382  
 383      /**
 384       * Test submission_status_updated event when a submission is updated.
 385       *
 386       * @covers \mod_assign\event\submission_status_updated
 387       */
 388      public function test_submission_status_updated_on_update() {
 389          $this->resetAfterTest();
 390  
 391          $course = $this->getDataGenerator()->create_course();
 392          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 393          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 394  
 395          $this->setUser($teacher);
 396  
 397          $assign = $this->create_instance($course);
 398          $submission = $assign->get_user_submission($student->id, true);
 399          $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
 400          $assign->testable_update_submission($submission, $student->id, true, false);
 401  
 402          $sink = $this->redirectEvents();
 403          $assign->revert_to_draft($student->id);
 404  
 405          $events = $sink->get_events();
 406          $this->assertCount(2, $events);
 407          $event = $events[1];
 408          $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
 409          $this->assertEquals($assign->get_context(), $event->get_context());
 410          $this->assertEquals($submission->id, $event->objectid);
 411          $this->assertEquals($student->id, $event->relateduserid);
 412          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
 413          $sink->close();
 414      }
 415  
 416      /**
 417       * Test submission_status_updated event when a submission is removed.
 418       *
 419       * @covers \mod_assign\event\submission_status_updated
 420       */
 421      public function test_submission_status_updated_on_remove() {
 422          $this->resetAfterTest();
 423  
 424          $course = $this->getDataGenerator()->create_course();
 425          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 426          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 427  
 428          $assign = $this->create_instance($course);
 429          $this->add_submission($student, $assign);
 430          $submission = $assign->get_user_submission($student->id, false);
 431  
 432          $sink = $this->redirectEvents();
 433          $assign->remove_submission($student->id);
 434  
 435          $events = $sink->get_events();
 436          $this->assertCount(2, $events);
 437  
 438          $event = $events[1];
 439          $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
 440          $this->assertEquals($assign->get_context(), $event->get_context());
 441          $this->assertEquals($submission->id, $event->objectid);
 442          $this->assertEquals($student->id, $event->relateduserid);
 443          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_NEW, $event->other['newstatus']);
 444          $sink->close();
 445      }
 446  
 447      /**
 448       * Test submission_status_updated event when a team submission is removed.
 449       *
 450       * @covers \mod_assign\event\submission_status_updated
 451       */
 452      public function test_team_submission_status_updated_on_remove() {
 453          $this->resetAfterTest();
 454  
 455          $course = $this->getDataGenerator()->create_course();
 456          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
 457          $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
 458  
 459          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 460          groups_add_member($group, $student);
 461  
 462          $otherstudent = $this->getDataGenerator()->create_and_enrol($course, 'student');
 463          groups_add_member($group, $otherstudent);
 464  
 465          $assign = $this->create_instance($course, [
 466              'teamsubmission' => 1,
 467          ]);
 468          $this->add_submission($student, $assign);
 469          $submission = $assign->get_group_submission($student->id, 0, false);
 470  
 471          $sink = $this->redirectEvents();
 472          $assign->remove_submission($student->id);
 473  
 474          $events = $sink->get_events();
 475          $this->assertCount(2, $events);
 476  
 477          $event = $events[1];
 478          $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
 479          $this->assertEquals($assign->get_context(), $event->get_context());
 480          $this->assertEquals($submission->id, $event->objectid);
 481          $this->assertEquals(null, $event->relateduserid);
 482          $this->assertEquals(ASSIGN_SUBMISSION_STATUS_NEW, $event->other['newstatus']);
 483          $sink->close();
 484      }
 485  
 486      public function test_marker_updated() {
 487          $this->resetAfterTest();
 488  
 489          $course = $this->getDataGenerator()->create_course();
 490          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 491          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 492  
 493          $teacher->ignoresesskey = true;
 494          $this->setUser($teacher);
 495  
 496          $assign = $this->create_instance($course);
 497  
 498          $sink = $this->redirectEvents();
 499          $assign->testable_process_set_batch_marking_allocation($student->id, $teacher->id);
 500  
 501          $events = $sink->get_events();
 502          $this->assertCount(1, $events);
 503          $event = reset($events);
 504          $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
 505          $this->assertEquals($assign->get_context(), $event->get_context());
 506          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 507          $this->assertEquals($student->id, $event->relateduserid);
 508          $this->assertEquals($teacher->id, $event->userid);
 509          $this->assertEquals($teacher->id, $event->other['markerid']);
 510          $sink->close();
 511      }
 512  
 513      public function test_workflow_state_updated() {
 514          $this->resetAfterTest();
 515  
 516          $course = $this->getDataGenerator()->create_course();
 517          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 518          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 519  
 520          $teacher->ignoresesskey = true;
 521          $this->setUser($teacher);
 522  
 523          $assign = $this->create_instance($course);
 524  
 525          // Test process_set_batch_marking_workflow_state.
 526          $sink = $this->redirectEvents();
 527          $assign->testable_process_set_batch_marking_workflow_state($student->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
 528  
 529          $events = $sink->get_events();
 530          $eventcount = 0;
 531          foreach ($events as $event) {
 532              if ($event instanceof \mod_assign\event\submission_graded) {
 533                  $eventcount++;
 534                  $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 535                  $this->assertEquals($assign->get_context(), $event->get_context());
 536              }
 537              if ($event instanceof \mod_assign\event\workflow_state_updated) {
 538                  $eventcount++;
 539                  $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 540                  $this->assertEquals($assign->get_context(), $event->get_context());
 541                  $this->assertEquals($assign->get_instance()->id, $event->objectid);
 542                  $this->assertEquals($student->id, $event->relateduserid);
 543                  $this->assertEquals($teacher->id, $event->userid);
 544                  $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
 545              }
 546          }
 547          $this->assertEquals(2, $eventcount);
 548          $sink->close();
 549  
 550          // Test setting workflow state in apply_grade_to_user.
 551          $sink = $this->redirectEvents();
 552          $data = new \stdClass();
 553          $data->grade = '50.0';
 554          $data->workflowstate = 'readyforrelease';
 555          $assign->testable_apply_grade_to_user($data, $student->id, 0);
 556  
 557          $events = $sink->get_events();
 558          $this->assertCount(4, $events);
 559          $event = reset($events);
 560          $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 561          $this->assertEquals($assign->get_context(), $event->get_context());
 562          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 563          $this->assertEquals($student->id, $event->relateduserid);
 564          $this->assertEquals($teacher->id, $event->userid);
 565          $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE, $event->other['newstate']);
 566          $sink->close();
 567  
 568          // Test setting workflow state in process_save_quick_grades.
 569          $sink = $this->redirectEvents();
 570  
 571          $data = array(
 572              'grademodified_' . $student->id => time(),
 573              'gradeattempt_' . $student->id => '',
 574              'quickgrade_' . $student->id => '60.0',
 575              'quickgrade_' . $student->id . '_workflowstate' => 'inmarking'
 576          );
 577          $assign->testable_process_save_quick_grades($data);
 578  
 579          $events = $sink->get_events();
 580          $this->assertCount(4, $events);
 581          $event = reset($events);
 582          $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
 583          $this->assertEquals($assign->get_context(), $event->get_context());
 584          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 585          $this->assertEquals($student->id, $event->relateduserid);
 586          $this->assertEquals($teacher->id, $event->userid);
 587          $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INMARKING, $event->other['newstate']);
 588          $sink->close();
 589      }
 590  
 591      public function test_submission_duplicated() {
 592          $this->resetAfterTest();
 593  
 594          $course = $this->getDataGenerator()->create_course();
 595          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 596  
 597          $this->setUser($student);
 598  
 599          $assign = $this->create_instance($course);
 600          $submission1 = $assign->get_user_submission($student->id, true, 0);
 601          $submission2 = $assign->get_user_submission($student->id, true, 1);
 602          $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
 603          $assign->testable_update_submission($submission2, $student->id, time(), $assign->get_instance()->teamsubmission);
 604  
 605          $sink = $this->redirectEvents();
 606          $notices = null;
 607          $assign->copy_previous_attempt($notices);
 608  
 609          $events = $sink->get_events();
 610          $this->assertCount(1, $events);
 611          $event = reset($events);
 612          $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
 613          $this->assertEquals($assign->get_context(), $event->get_context());
 614          $this->assertEquals($submission2->id, $event->objectid);
 615          $this->assertEquals($student->id, $event->userid);
 616          $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
 617          $sink->close();
 618      }
 619  
 620      public function test_submission_unlocked() {
 621          $this->resetAfterTest();
 622  
 623          $course = $this->getDataGenerator()->create_course();
 624          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 625          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 626  
 627          $teacher->ignoresesskey = true;
 628          $this->setUser($teacher);
 629  
 630          $assign = $this->create_instance($course);
 631          $sink = $this->redirectEvents();
 632  
 633          $assign->unlock_submission($student->id);
 634  
 635          $events = $sink->get_events();
 636          $this->assertCount(1, $events);
 637          $event = reset($events);
 638          $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
 639          $this->assertEquals($assign->get_context(), $event->get_context());
 640          $this->assertEquals($assign->get_instance()->id, $event->objectid);
 641          $this->assertEquals($student->id, $event->relateduserid);
 642          $sink->close();
 643      }
 644  
 645      public function test_submission_graded() {
 646          $this->resetAfterTest();
 647  
 648          $course = $this->getDataGenerator()->create_course();
 649          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 650          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 651  
 652          $teacher->ignoresesskey = true;
 653          $this->setUser($teacher);
 654  
 655          $assign = $this->create_instance($course);
 656  
 657          // Test apply_grade_to_user.
 658          $sink = $this->redirectEvents();
 659  
 660          $data = new \stdClass();
 661          $data->grade = '50.0';
 662          $assign->testable_apply_grade_to_user($data, $student->id, 0);
 663          $grade = $assign->get_user_grade($student->id, false, 0);
 664  
 665          $events = $sink->get_events();
 666          $this->assertCount(3, $events);
 667          $event = $events[2];
 668          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 669          $this->assertEquals($assign->get_context(), $event->get_context());
 670          $this->assertEquals($grade->id, $event->objectid);
 671          $this->assertEquals($student->id, $event->relateduserid);
 672          $sink->close();
 673  
 674          // Test process_save_quick_grades.
 675          $sink = $this->redirectEvents();
 676  
 677          $grade = $assign->get_user_grade($student->id, false);
 678          $data = array(
 679              'grademodified_' . $student->id => time(),
 680              'gradeattempt_' . $student->id => $grade->attemptnumber,
 681              'quickgrade_' . $student->id => '60.0'
 682          );
 683          $assign->testable_process_save_quick_grades($data);
 684          $grade = $assign->get_user_grade($student->id, false);
 685          $this->assertEquals(60.0, $grade->grade);
 686  
 687          $events = $sink->get_events();
 688          $this->assertCount(3, $events);
 689          $event = $events[2];
 690          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 691          $this->assertEquals($assign->get_context(), $event->get_context());
 692          $this->assertEquals($grade->id, $event->objectid);
 693          $this->assertEquals($student->id, $event->relateduserid);
 694          $sink->close();
 695  
 696          // Test update_grade.
 697          $sink = $this->redirectEvents();
 698          $data = clone($grade);
 699          $data->grade = '50.0';
 700          $assign->update_grade($data);
 701          $grade = $assign->get_user_grade($student->id, false, 0);
 702          $this->assertEquals(50.0, $grade->grade);
 703          $events = $sink->get_events();
 704  
 705          $this->assertCount(3, $events);
 706          $event = $events[2];
 707          $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
 708          $this->assertEquals($assign->get_context(), $event->get_context());
 709          $this->assertEquals($grade->id, $event->objectid);
 710          $this->assertEquals($student->id, $event->relateduserid);
 711          $sink->close();
 712      }
 713  
 714      /**
 715       * Test the submission_viewed event.
 716       */
 717      public function test_submission_viewed() {
 718          global $PAGE;
 719  
 720          $this->resetAfterTest();
 721  
 722          $course = $this->getDataGenerator()->create_course();
 723          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 724          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 725  
 726          $this->setUser($teacher);
 727  
 728          $assign = $this->create_instance($course);
 729          $submission = $assign->get_user_submission($student->id, true);
 730  
 731          // We need to set the URL in order to view the submission.
 732          $PAGE->set_url('/a_url');
 733          // A hack - these variables are used by the view_plugin_content function to
 734          // determine what we actually want to view - would usually be set in URL.
 735          global $_POST;
 736          $_POST['plugin'] = 'comments';
 737          $_POST['sid'] = $submission->id;
 738  
 739          // Trigger and capture the event.
 740          $sink = $this->redirectEvents();
 741          $assign->view('viewpluginassignsubmission');
 742          $events = $sink->get_events();
 743          $this->assertCount(1, $events);
 744          $event = reset($events);
 745  
 746          // Check that the event contains the expected values.
 747          $this->assertInstanceOf('\mod_assign\event\submission_viewed', $event);
 748          $this->assertEquals($assign->get_context(), $event->get_context());
 749          $this->assertEquals($submission->id, $event->objectid);
 750      }
 751  
 752      /**
 753       * Test the feedback_viewed event.
 754       */
 755      public function test_feedback_viewed() {
 756          global $DB, $PAGE;
 757  
 758          $this->resetAfterTest();
 759  
 760          $course = $this->getDataGenerator()->create_course();
 761          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 762          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 763  
 764          $this->setUser($teacher);
 765  
 766          $assign = $this->create_instance($course);
 767          $submission = $assign->get_user_submission($student->id, true);
 768  
 769          // Insert a grade for this submission.
 770          $grade = new \stdClass();
 771          $grade->assignment = $assign->get_instance()->id;
 772          $grade->userid = $student->id;
 773          $gradeid = $DB->insert_record('assign_grades', $grade);
 774  
 775          // We need to set the URL in order to view the feedback.
 776          $PAGE->set_url('/a_url');
 777          // A hack - these variables are used by the view_plugin_content function to
 778          // determine what we actually want to view - would usually be set in URL.
 779          global $_POST;
 780          $_POST['plugin'] = 'comments';
 781          $_POST['gid'] = $gradeid;
 782          $_POST['sid'] = $submission->id;
 783  
 784          // Trigger and capture the event.
 785          $sink = $this->redirectEvents();
 786          $assign->view('viewpluginassignfeedback');
 787          $events = $sink->get_events();
 788          $this->assertCount(1, $events);
 789          $event = reset($events);
 790  
 791          // Check that the event contains the expected values.
 792          $this->assertInstanceOf('\mod_assign\event\feedback_viewed', $event);
 793          $this->assertEquals($assign->get_context(), $event->get_context());
 794          $this->assertEquals($gradeid, $event->objectid);
 795      }
 796  
 797      /**
 798       * Test the grading_form_viewed event.
 799       */
 800      public function test_grading_form_viewed() {
 801          global $PAGE;
 802  
 803          $this->resetAfterTest();
 804  
 805          $course = $this->getDataGenerator()->create_course();
 806          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 807          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 808  
 809          $this->setUser($teacher);
 810  
 811          $assign = $this->create_instance($course);
 812  
 813          // We need to set the URL in order to view the feedback.
 814          $PAGE->set_url('/a_url');
 815          // A hack - this variable is used by the view_single_grade_page function.
 816          global $_POST;
 817          $_POST['rownum'] = 1;
 818          $_POST['userid'] = $student->id;
 819  
 820          // Trigger and capture the event.
 821          $sink = $this->redirectEvents();
 822          $assign->view('grade');
 823          $events = $sink->get_events();
 824          $this->assertCount(1, $events);
 825          $event = reset($events);
 826  
 827          // Check that the event contains the expected values.
 828          $this->assertInstanceOf('\mod_assign\event\grading_form_viewed', $event);
 829          $this->assertEquals($assign->get_context(), $event->get_context());
 830      }
 831  
 832      /**
 833       * Test the grading_table_viewed event.
 834       */
 835      public function test_grading_table_viewed() {
 836          global $PAGE;
 837  
 838          $this->resetAfterTest();
 839  
 840          $course = $this->getDataGenerator()->create_course();
 841          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
 842          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 843  
 844          $this->setUser($teacher);
 845  
 846          $assign = $this->create_instance($course);
 847  
 848          // We need to set the URL in order to view the feedback.
 849          $PAGE->set_url('/a_url');
 850          // A hack - this variable is used by the view_single_grade_page function.
 851          global $_POST;
 852          $_POST['rownum'] = 1;
 853          $_POST['userid'] = $student->id;
 854  
 855          // Trigger and capture the event.
 856          $sink = $this->redirectEvents();
 857          $assign->view('grading');
 858          $events = $sink->get_events();
 859          $this->assertCount(1, $events);
 860          $event = reset($events);
 861  
 862          // Check that the event contains the expected values.
 863          $this->assertInstanceOf('\mod_assign\event\grading_table_viewed', $event);
 864          $this->assertEquals($assign->get_context(), $event->get_context());
 865          $this->assertEventContextNotUsed($event);
 866      }
 867  
 868      /**
 869       * Test the submission_form_viewed event.
 870       */
 871      public function test_submission_form_viewed() {
 872          global $PAGE;
 873  
 874          $this->resetAfterTest();
 875  
 876          $course = $this->getDataGenerator()->create_course();
 877          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 878  
 879          $this->setUser($student);
 880  
 881          $assign = $this->create_instance($course);
 882  
 883          // We need to set the URL in order to view the submission form.
 884          $PAGE->set_url('/a_url');
 885  
 886          // Trigger and capture the event.
 887          $sink = $this->redirectEvents();
 888          $assign->view('editsubmission');
 889          $events = $sink->get_events();
 890          $this->assertCount(1, $events);
 891          $event = reset($events);
 892  
 893          // Check that the event contains the expected values.
 894          $this->assertInstanceOf('\mod_assign\event\submission_form_viewed', $event);
 895          $this->assertEquals($assign->get_context(), $event->get_context());
 896          $this->assertEventContextNotUsed($event);
 897      }
 898  
 899      /**
 900       * Test the submission_form_viewed event.
 901       */
 902      public function test_submission_confirmation_form_viewed() {
 903          global $PAGE;
 904  
 905          $this->resetAfterTest();
 906  
 907          $course = $this->getDataGenerator()->create_course();
 908          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 909  
 910          $this->setUser($student);
 911  
 912          $assign = $this->create_instance($course);
 913  
 914          // We need to set the URL in order to view the submission form.
 915          $PAGE->set_url('/a_url');
 916  
 917          // Trigger and capture the event.
 918          $sink = $this->redirectEvents();
 919          $assign->view('submit');
 920          $events = $sink->get_events();
 921          $this->assertCount(1, $events);
 922          $event = reset($events);
 923  
 924          // Check that the event contains the expected values.
 925          $this->assertInstanceOf('\mod_assign\event\submission_confirmation_form_viewed', $event);
 926          $this->assertEquals($assign->get_context(), $event->get_context());
 927          $this->assertEventContextNotUsed($event);
 928      }
 929  
 930      /**
 931       * Test the reveal_identities_confirmation_page_viewed event.
 932       */
 933      public function test_reveal_identities_confirmation_page_viewed() {
 934          global $PAGE;
 935          $this->resetAfterTest();
 936  
 937          // Set to the admin user so we have the permission to reveal identities.
 938          $this->setAdminUser();
 939  
 940          $course = $this->getDataGenerator()->create_course();
 941          $assign = $this->create_instance($course);
 942  
 943          // We need to set the URL in order to view the submission form.
 944          $PAGE->set_url('/a_url');
 945  
 946          // Trigger and capture the event.
 947          $sink = $this->redirectEvents();
 948          $assign->view('revealidentities');
 949          $events = $sink->get_events();
 950          $this->assertCount(1, $events);
 951          $event = reset($events);
 952  
 953          // Check that the event contains the expected values.
 954          $this->assertInstanceOf('\mod_assign\event\reveal_identities_confirmation_page_viewed', $event);
 955          $this->assertEquals($assign->get_context(), $event->get_context());
 956          $this->assertEventContextNotUsed($event);
 957      }
 958  
 959      /**
 960       * Test the statement_accepted event.
 961       */
 962      public function test_statement_accepted() {
 963          // We want to be a student so we can submit assignments.
 964          $this->resetAfterTest();
 965  
 966          $course = $this->getDataGenerator()->create_course();
 967          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 968  
 969          $this->setUser($student);
 970  
 971          // We do not want to send any messages to the student during the PHPUNIT test.
 972          set_config('submissionreceipts', false, 'assign');
 973  
 974          $assign = $this->create_instance($course);
 975  
 976          // Create the data we want to pass to the submit_for_grading function.
 977          $data = new \stdClass();
 978          $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
 979              to these terms?';
 980  
 981          // Trigger and capture the event.
 982          $sink = $this->redirectEvents();
 983          $assign->submit_for_grading($data, array());
 984          $events = $sink->get_events();
 985          $event = reset($events);
 986  
 987          // Check that the event contains the expected values.
 988          $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
 989          $this->assertEquals($assign->get_context(), $event->get_context());
 990          $this->assertEventContextNotUsed($event);
 991  
 992          // Enable the online text submission plugin.
 993          $submissionplugins = $assign->get_submission_plugins();
 994          foreach ($submissionplugins as $plugin) {
 995              if ($plugin->get_type() === 'onlinetext') {
 996                  $plugin->enable();
 997                  break;
 998              }
 999          }
1000  
1001          // Create the data we want to pass to the save_submission function.
1002          $data = new \stdClass();
1003          $data->onlinetext_editor = array(
1004              'text' => 'Online text',
1005              'format' => FORMAT_HTML,
1006              'itemid' => file_get_unused_draft_itemid()
1007          );
1008          $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
1009              to these terms?';
1010  
1011          // Trigger and capture the event.
1012          $sink = $this->redirectEvents();
1013          $assign->save_submission($data, $notices);
1014          $events = $sink->get_events();
1015          $event = $events[2];
1016  
1017          // Check that the event contains the expected values.
1018          $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
1019          $this->assertEquals($assign->get_context(), $event->get_context());
1020          $this->assertEventContextNotUsed($event);
1021      }
1022  
1023      /**
1024       * Test the batch_set_workflow_state_viewed event.
1025       */
1026      public function test_batch_set_workflow_state_viewed() {
1027          $this->resetAfterTest();
1028  
1029          $course = $this->getDataGenerator()->create_course();
1030          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
1031          $assign = $this->create_instance($course);
1032  
1033          // Trigger and capture the event.
1034          $sink = $this->redirectEvents();
1035          $assign->testable_view_batch_set_workflow_state($student->id);
1036          $events = $sink->get_events();
1037          $event = reset($events);
1038  
1039          // Check that the event contains the expected values.
1040          $this->assertInstanceOf('\mod_assign\event\batch_set_workflow_state_viewed', $event);
1041          $this->assertEquals($assign->get_context(), $event->get_context());
1042          $this->assertEventContextNotUsed($event);
1043      }
1044  
1045      /**
1046       * Test the batch_set_marker_allocation_viewed event.
1047       */
1048      public function test_batch_set_marker_allocation_viewed() {
1049          $this->resetAfterTest();
1050  
1051          $course = $this->getDataGenerator()->create_course();
1052          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
1053          $assign = $this->create_instance($course);
1054  
1055          // Trigger and capture the event.
1056          $sink = $this->redirectEvents();
1057          $assign->testable_view_batch_markingallocation($student->id);
1058          $events = $sink->get_events();
1059          $event = reset($events);
1060  
1061          // Check that the event contains the expected values.
1062          $this->assertInstanceOf('\mod_assign\event\batch_set_marker_allocation_viewed', $event);
1063          $this->assertEquals($assign->get_context(), $event->get_context());
1064          $this->assertEventContextNotUsed($event);
1065      }
1066  
1067      /**
1068       * Test the user override created event.
1069       *
1070       * There is no external API for creating a user override, so the unit test will simply
1071       * create and trigger the event and ensure the event data is returned as expected.
1072       */
1073      public function test_user_override_created() {
1074          $this->resetAfterTest();
1075  
1076          $course = $this->getDataGenerator()->create_course();
1077          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1078  
1079          $params = array(
1080              'objectid' => 1,
1081              'relateduserid' => 2,
1082              'context' => \context_module::instance($assign->cmid),
1083              'other' => array(
1084                  'assignid' => $assign->id
1085              )
1086          );
1087          $event = \mod_assign\event\user_override_created::create($params);
1088  
1089          // Trigger and capture the event.
1090          $sink = $this->redirectEvents();
1091          $event->trigger();
1092          $events = $sink->get_events();
1093          $event = reset($events);
1094  
1095          // Check that the event data is valid.
1096          $this->assertInstanceOf('\mod_assign\event\user_override_created', $event);
1097          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1098          $this->assertEventContextNotUsed($event);
1099      }
1100  
1101      /**
1102       * Test the group override created event.
1103       *
1104       * There is no external API for creating a group override, so the unit test will simply
1105       * create and trigger the event and ensure the event data is returned as expected.
1106       */
1107      public function test_group_override_created() {
1108          $this->resetAfterTest();
1109  
1110          $course = $this->getDataGenerator()->create_course();
1111          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1112  
1113          $params = array(
1114              'objectid' => 1,
1115              'context' => \context_module::instance($assign->cmid),
1116              'other' => array(
1117                  'assignid' => $assign->id,
1118                  'groupid' => 2
1119              )
1120          );
1121          $event = \mod_assign\event\group_override_created::create($params);
1122  
1123          // Trigger and capture the event.
1124          $sink = $this->redirectEvents();
1125          $event->trigger();
1126          $events = $sink->get_events();
1127          $event = reset($events);
1128  
1129          // Check that the event data is valid.
1130          $this->assertInstanceOf('\mod_assign\event\group_override_created', $event);
1131          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1132          $this->assertEventContextNotUsed($event);
1133      }
1134  
1135      /**
1136       * Test the user override updated event.
1137       *
1138       * There is no external API for updating a user override, so the unit test will simply
1139       * create and trigger the event and ensure the event data is returned as expected.
1140       */
1141      public function test_user_override_updated() {
1142          $this->resetAfterTest();
1143  
1144          $course = $this->getDataGenerator()->create_course();
1145          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1146  
1147          $params = array(
1148              'objectid' => 1,
1149              'relateduserid' => 2,
1150              'context' => \context_module::instance($assign->cmid),
1151              'other' => array(
1152                  'assignid' => $assign->id
1153              )
1154          );
1155          $event = \mod_assign\event\user_override_updated::create($params);
1156  
1157          // Trigger and capture the event.
1158          $sink = $this->redirectEvents();
1159          $event->trigger();
1160          $events = $sink->get_events();
1161          $event = reset($events);
1162  
1163          // Check that the event data is valid.
1164          $this->assertInstanceOf('\mod_assign\event\user_override_updated', $event);
1165          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1166          $this->assertEventContextNotUsed($event);
1167      }
1168  
1169      /**
1170       * Test the group override updated event.
1171       *
1172       * There is no external API for updating a group override, so the unit test will simply
1173       * create and trigger the event and ensure the event data is returned as expected.
1174       */
1175      public function test_group_override_updated() {
1176          $this->resetAfterTest();
1177  
1178          $course = $this->getDataGenerator()->create_course();
1179          $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance(['course' => $course->id]);
1180  
1181          $params = array(
1182              'objectid' => 1,
1183              'context' => \context_module::instance($assign->cmid),
1184              'other' => array(
1185                  'assignid' => $assign->id,
1186                  'groupid' => 2
1187              )
1188          );
1189          $event = \mod_assign\event\group_override_updated::create($params);
1190  
1191          // Trigger and capture the event.
1192          $sink = $this->redirectEvents();
1193          $event->trigger();
1194          $events = $sink->get_events();
1195          $event = reset($events);
1196  
1197          // Check that the event data is valid.
1198          $this->assertInstanceOf('\mod_assign\event\group_override_updated', $event);
1199          $this->assertEquals(\context_module::instance($assign->cmid), $event->get_context());
1200          $this->assertEventContextNotUsed($event);
1201      }
1202  
1203      /**
1204       * Test the user override deleted event.
1205       */
1206      public function test_user_override_deleted() {
1207          global $DB;
1208          $this->resetAfterTest();
1209  
1210          $course = $this->getDataGenerator()->create_course();
1211          $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1212          $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1213          $context = \context_module::instance($cm->id);
1214          $assign = new \assign($context, $cm, $course);
1215  
1216          // Create an override.
1217          $override = new \stdClass();
1218          $override->assign = $assigninstance->id;
1219          $override->userid = 2;
1220          $override->id = $DB->insert_record('assign_overrides', $override);
1221  
1222          // Trigger and capture the event.
1223          $sink = $this->redirectEvents();
1224          $assign->delete_override($override->id);
1225          $events = $sink->get_events();
1226          $event = reset($events);
1227  
1228          // Check that the event data is valid.
1229          $this->assertInstanceOf('\mod_assign\event\user_override_deleted', $event);
1230          $this->assertEquals(\context_module::instance($cm->id), $event->get_context());
1231          $this->assertEventContextNotUsed($event);
1232      }
1233  
1234      /**
1235       * Test the group override deleted event.
1236       */
1237      public function test_group_override_deleted() {
1238          global $DB;
1239          $this->resetAfterTest();
1240  
1241          $course = $this->getDataGenerator()->create_course();
1242          $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1243          $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1244          $context = \context_module::instance($cm->id);
1245          $assign = new \assign($context, $cm, $course);
1246  
1247          // Create an override.
1248          $override = new \stdClass();
1249          $override->assign = $assigninstance->id;
1250          $override->groupid = 2;
1251          $override->id = $DB->insert_record('assign_overrides', $override);
1252  
1253          // Trigger and capture the event.
1254          $sink = $this->redirectEvents();
1255          $assign->delete_override($override->id);
1256          $events = $sink->get_events();
1257          $event = reset($events);
1258  
1259          // Check that the event data is valid.
1260          $this->assertInstanceOf('\mod_assign\event\group_override_deleted', $event);
1261          $this->assertEquals(\context_module::instance($cm->id), $event->get_context());
1262          $this->assertEventContextNotUsed($event);
1263      }
1264  
1265      /**
1266       * Test the course module viewed event.
1267       */
1268      public function test_course_module_viewed() {
1269          $this->resetAfterTest();
1270  
1271          $course = $this->getDataGenerator()->create_course();
1272          $assign = $this->create_instance($course);
1273  
1274          $context = $assign->get_context();
1275  
1276          $params = array(
1277              'context' => $context,
1278              'objectid' => $assign->get_instance()->id
1279          );
1280  
1281          $event = \mod_assign\event\course_module_viewed::create($params);
1282  
1283          // Trigger and capture the event.
1284          $sink = $this->redirectEvents();
1285          $event->trigger();
1286          $events = $sink->get_events();
1287          $this->assertCount(1, $events);
1288          $event = reset($events);
1289  
1290          // Check that the event contains the expected values.
1291          $this->assertInstanceOf('\mod_assign\event\course_module_viewed', $event);
1292          $this->assertEquals($context, $event->get_context());
1293      }
1294  
1295      /**
1296       * Test that all events generated with blindmarking enabled are anonymous
1297       */
1298      public function test_anonymous_events() {
1299          $this->resetAfterTest();
1300  
1301          $course = $this->getDataGenerator()->create_course();
1302          $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
1303          $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
1304          $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
1305  
1306          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1307          $instance = $generator->create_instance(array('course' => $course->id, 'blindmarking' => 1));
1308  
1309          $cm = get_coursemodule_from_instance('assign', $instance->id, $course->id);
1310          $context = \context_module::instance($cm->id);
1311          $assign = new \assign($context, $cm, $course);
1312  
1313          $this->setUser($teacher);
1314          $sink = $this->redirectEvents();
1315  
1316          $assign->lock_submission($student1->id);
1317  
1318          $events = $sink->get_events();
1319          $event = reset($events);
1320  
1321          $this->assertTrue((bool)$event->anonymous);
1322  
1323          $assign->reveal_identities();
1324          $sink = $this->redirectEvents();
1325          $assign->lock_submission($student2->id);
1326  
1327          $events = $sink->get_events();
1328          $event = reset($events);
1329  
1330          $this->assertFalse((bool)$event->anonymous);
1331      }
1332  
1333  }