Search moodle.org's
Developer Documentation

See Release Notes

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