5d1402861c1e4c45b40b39d79565fd0e2ef09ab7
[moodle.git] / mod / assign / tests / events_test.php
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/>.
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  */
25 defined('MOODLE_INTERNAL') || die();
27 global $CFG;
28 require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
29 require_once($CFG->dirroot . '/mod/assign/tests/fixtures/event_mod_assign_fixtures.php');
30 require_once($CFG->dirroot . '/mod/assign/locallib.php');
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 mod_assign_base_testcase {
41     /**
42      * Basic tests for the submission_created() abstract class.
43      */
44     public function test_base_event() {
45         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
46         $instance = $generator->create_instance(array('course' => $this->course->id));
47         $modcontext = context_module::instance($instance->cmid);
49         $data = array(
50             'context' => $modcontext,
51         );
52         /** @var \mod_assign_unittests\event\nothing_happened $event */
53         $event = \mod_assign_unittests\event\nothing_happened::create($data);
54         $assign = $event->get_assign();
55         $this->assertDebuggingCalled();
56         $this->assertInstanceOf('assign', $assign);
58         $event = \mod_assign_unittests\event\nothing_happened::create($data);
59         $event->set_assign($assign);
60         $assign2 = $event->get_assign();
61         $this->assertDebuggingNotCalled();
62         $this->assertSame($assign, $assign2);
63     }
65     /**
66      * Basic tests for the submission_created() abstract class.
67      */
68     public function test_submission_created() {
69         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
70         $instance = $generator->create_instance(array('course' => $this->course->id));
71         $modcontext = context_module::instance($instance->cmid);
73         // Standard Event parameters.
74         $params = array(
75             'context' => $modcontext,
76             'courseid' => $this->course->id
77         );
79         $eventinfo = $params;
80         $eventinfo['other'] = array(
81             'submissionid' => '17',
82             'submissionattempt' => 0,
83             'submissionstatus' => 'submitted'
84         );
86         $sink = $this->redirectEvents();
87         $event = \mod_assign_unittests\event\submission_created::create($eventinfo);
88         $event->trigger();
89         $result = $sink->get_events();
90         $event = reset($result);
91         $sink->close();
93         $this->assertEquals($modcontext->id, $event->contextid);
94         $this->assertEquals($this->course->id, $event->courseid);
96         // Check that an error occurs when teamsubmission is not set.
97         try {
98             \mod_assign_unittests\event\submission_created::create($params);
99             $this->fail('Other must contain the key submissionid.');
100         } catch (Exception $e) {
101             $this->assertInstanceOf('coding_exception', $e);
102         }
103         // Check that the submission status debugging is fired.
104         $subinfo = $params;
105         $subinfo['other'] = array('submissionid' => '23');
106         try {
107             \mod_assign_unittests\event\submission_created::create($subinfo);
108             $this->fail('Other must contain the key submissionattempt.');
109         } catch (Exception $e) {
110             $this->assertInstanceOf('coding_exception', $e);
111         }
113         $subinfo['other'] = array('submissionattempt' => '0');
114         try {
115             \mod_assign_unittests\event\submission_created::create($subinfo);
116             $this->fail('Other must contain the key submissionstatus.');
117         } catch (Exception $e) {
118             $this->assertInstanceOf('coding_exception', $e);
119         }
120     }
122     /**
123      * Basic tests for the submission_updated() abstract class.
124      */
125     public function test_submission_updated() {
126         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
127         $instance = $generator->create_instance(array('course' => $this->course->id));
128         $modcontext = context_module::instance($instance->cmid);
130         // Standard Event parameters.
131         $params = array(
132             'context' => $modcontext,
133             'courseid' => $this->course->id
134         );
136         $eventinfo = $params;
137         $eventinfo['other'] = array(
138             'submissionid' => '17',
139             'submissionattempt' => 0,
140             'submissionstatus' => 'submitted'
141         );
143         $sink = $this->redirectEvents();
144         $event = \mod_assign_unittests\event\submission_updated::create($eventinfo);
145         $event->trigger();
146         $result = $sink->get_events();
147         $event = reset($result);
148         $sink->close();
150         $this->assertEquals($modcontext->id, $event->contextid);
151         $this->assertEquals($this->course->id, $event->courseid);
153         // Check that an error occurs when teamsubmission is not set.
154         try {
155             \mod_assign_unittests\event\submission_created::create($params);
156             $this->fail('Other must contain the key submissionid.');
157         } catch (Exception $e) {
158             $this->assertInstanceOf('coding_exception', $e);
159         }
160         // Check that the submission status debugging is fired.
161         $subinfo = $params;
162         $subinfo['other'] = array('submissionid' => '23');
163         try {
164             \mod_assign_unittests\event\submission_created::create($subinfo);
165             $this->fail('Other must contain the key submissionattempt.');
166         } catch (Exception $e) {
167             $this->assertInstanceOf('coding_exception', $e);
168         }
170         $subinfo['other'] = array('submissionattempt' => '0');
171         try {
172             \mod_assign_unittests\event\submission_created::create($subinfo);
173             $this->fail('Other must contain the key submissionstatus.');
174         } catch (Exception $e) {
175             $this->assertInstanceOf('coding_exception', $e);
176         }
177     }
179     public function test_extension_granted() {
180         $this->setUser($this->editingteachers[0]);
182         $tomorrow = time() + 24*60*60;
183         $yesterday = time() - 24*60*60;
185         $assign = $this->create_instance(array('duedate' => $yesterday, 'cutoffdate' => $yesterday));
186         $sink = $this->redirectEvents();
188         $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
190         $events = $sink->get_events();
191         $this->assertCount(1, $events);
192         $event = reset($events);
193         $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
194         $this->assertEquals($assign->get_context(), $event->get_context());
195         $this->assertEquals($assign->get_instance()->id, $event->objectid);
196         $this->assertEquals($this->students[0]->id, $event->relateduserid);
197         $expected = array(
198             $assign->get_course()->id,
199             'assign',
200             'grant extension',
201             'view.php?id=' . $assign->get_course_module()->id,
202             $this->students[0]->id,
203             $assign->get_course_module()->id
204         );
205         $this->assertEventLegacyLogData($expected, $event);
206         $sink->close();
207     }
209     public function test_submission_locked() {
210         $this->editingteachers[0]->ignoresesskey = true;
211         $this->setUser($this->editingteachers[0]);
213         $assign = $this->create_instance();
214         $sink = $this->redirectEvents();
216         $assign->lock_submission($this->students[0]->id);
218         $events = $sink->get_events();
219         $this->assertCount(1, $events);
220         $event = reset($events);
221         $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
222         $this->assertEquals($assign->get_context(), $event->get_context());
223         $this->assertEquals($assign->get_instance()->id, $event->objectid);
224         $this->assertEquals($this->students[0]->id, $event->relateduserid);
225         $expected = array(
226             $assign->get_course()->id,
227             'assign',
228             'lock submission',
229             'view.php?id=' . $assign->get_course_module()->id,
230             get_string('locksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
231                 'fullname' => fullname($this->students[0]))),
232             $assign->get_course_module()->id
233         );
234         $this->assertEventLegacyLogData($expected, $event);
235         $sink->close();
237         // Revert to defaults.
238         $this->editingteachers[0]->ignoresesskey = false;
239     }
241     public function test_identities_revealed() {
242         $this->editingteachers[0]->ignoresesskey = true;
243         $this->setUser($this->editingteachers[0]);
245         $assign = $this->create_instance(array('blindmarking'=>1));
246         $sink = $this->redirectEvents();
248         $assign->reveal_identities();
250         $events = $sink->get_events();
251         $this->assertCount(1, $events);
252         $event = reset($events);
253         $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
254         $this->assertEquals($assign->get_context(), $event->get_context());
255         $this->assertEquals($assign->get_instance()->id, $event->objectid);
256         $expected = array(
257             $assign->get_course()->id,
258             'assign',
259             'reveal identities',
260             'view.php?id=' . $assign->get_course_module()->id,
261             get_string('revealidentities', 'assign'),
262             $assign->get_course_module()->id
263         );
264         $this->assertEventLegacyLogData($expected, $event);
265         $sink->close();
267         // Revert to defaults.
268         $this->editingteachers[0]->ignoresesskey = false;
269     }
271     /**
272      * Test the submission_status_viewed event.
273      */
274     public function test_submission_status_viewed() {
275         global $PAGE;
277         $this->setUser($this->editingteachers[0]);
279         $assign = $this->create_instance();
281         // We need to set the URL in order to view the feedback.
282         $PAGE->set_url('/a_url');
284         // Trigger and capture the event.
285         $sink = $this->redirectEvents();
286         $assign->view();
287         $events = $sink->get_events();
288         $this->assertCount(1, $events);
289         $event = reset($events);
291         // Check that the event contains the expected values.
292         $this->assertInstanceOf('\mod_assign\event\submission_status_viewed', $event);
293         $this->assertEquals($assign->get_context(), $event->get_context());
294         $expected = array(
295             $assign->get_course()->id,
296             'assign',
297             'view',
298             'view.php?id=' . $assign->get_course_module()->id,
299             get_string('viewownsubmissionstatus', 'assign'),
300             $assign->get_course_module()->id
301         );
302         $this->assertEventLegacyLogData($expected, $event);
303         $this->assertEventContextNotUsed($event);
304     }
306     public function test_submission_status_updated() {
307         $this->editingteachers[0]->ignoresesskey = true;
308         $this->setUser($this->editingteachers[0]);
310         $assign = $this->create_instance();
311         $submission = $assign->get_user_submission($this->students[0]->id, true);
312         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
313         $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
315         $sink = $this->redirectEvents();
316         $assign->revert_to_draft($this->students[0]->id);
318         $events = $sink->get_events();
319         $this->assertCount(2, $events);
320         $event = $events[1];
321         $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
322         $this->assertEquals($assign->get_context(), $event->get_context());
323         $this->assertEquals($submission->id, $event->objectid);
324         $this->assertEquals($this->students[0]->id, $event->relateduserid);
325         $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
326         $expected = array(
327             $assign->get_course()->id,
328             'assign',
329             'revert submission to draft',
330             'view.php?id=' . $assign->get_course_module()->id,
331             get_string('reverttodraftforstudent', 'assign', array('id' => $this->students[0]->id,
332                 'fullname' => fullname($this->students[0]))),
333             $assign->get_course_module()->id
334         );
335         $this->assertEventLegacyLogData($expected, $event);
336         $sink->close();
338         // Revert to defaults.
339         $this->editingteachers[0]->ignoresesskey = false;
340     }
342     public function test_marker_updated() {
343         $this->editingteachers[0]->ignoresesskey = true;
344         $this->setUser($this->editingteachers[0]);
346         $assign = $this->create_instance();
348         $sink = $this->redirectEvents();
349         $assign->testable_process_set_batch_marking_allocation($this->students[0]->id, $this->teachers[0]->id);
351         $events = $sink->get_events();
352         $this->assertCount(1, $events);
353         $event = reset($events);
354         $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
355         $this->assertEquals($assign->get_context(), $event->get_context());
356         $this->assertEquals($assign->get_instance()->id, $event->objectid);
357         $this->assertEquals($this->students[0]->id, $event->relateduserid);
358         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
359         $this->assertEquals($this->teachers[0]->id, $event->other['markerid']);
360         $expected = array(
361             $assign->get_course()->id,
362             'assign',
363             'set marking allocation',
364             'view.php?id=' . $assign->get_course_module()->id,
365             get_string('setmarkerallocationforlog', 'assign', array('id' => $this->students[0]->id,
366                 'fullname' => fullname($this->students[0]), 'marker' => fullname($this->teachers[0]))),
367             $assign->get_course_module()->id
368         );
369         $this->assertEventLegacyLogData($expected, $event);
370         $sink->close();
372         // Revert to defaults.
373         $this->editingteachers[0]->ignoresesskey = false;
374     }
376     public function test_workflow_state_updated() {
377         $this->editingteachers[0]->ignoresesskey = true;
378         $this->setUser($this->editingteachers[0]);
380         $assign = $this->create_instance();
382         // Test process_set_batch_marking_workflow_state.
383         $sink = $this->redirectEvents();
384         $assign->testable_process_set_batch_marking_workflow_state($this->students[0]->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
386         $events = $sink->get_events();
387         $this->assertCount(1, $events);
388         $event = reset($events);
389         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
390         $this->assertEquals($assign->get_context(), $event->get_context());
391         $this->assertEquals($assign->get_instance()->id, $event->objectid);
392         $this->assertEquals($this->students[0]->id, $event->relateduserid);
393         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
394         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
395         $expected = array(
396             $assign->get_course()->id,
397             'assign',
398             'set marking workflow state',
399             'view.php?id=' . $assign->get_course_module()->id,
400             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
401                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW)),
402             $assign->get_course_module()->id
403         );
404         $this->assertEventLegacyLogData($expected, $event);
405         $sink->close();
407         // Test setting workflow state in apply_grade_to_user.
408         $sink = $this->redirectEvents();
409         $data = new stdClass();
410         $data->grade = '50.0';
411         $data->workflowstate = 'readyforrelease';
412         $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
414         $events = $sink->get_events();
415         $this->assertCount(4, $events);
416         $event = reset($events);
417         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
418         $this->assertEquals($assign->get_context(), $event->get_context());
419         $this->assertEquals($assign->get_instance()->id, $event->objectid);
420         $this->assertEquals($this->students[0]->id, $event->relateduserid);
421         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
422         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE, $event->other['newstate']);
423         $expected = array(
424             $assign->get_course()->id,
425             'assign',
426             'set marking workflow state',
427             'view.php?id=' . $assign->get_course_module()->id,
428             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
429                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE)),
430             $assign->get_course_module()->id
431         );
432         $this->assertEventLegacyLogData($expected, $event);
433         $sink->close();
435         // Test setting workflow state in process_save_quick_grades.
436         $sink = $this->redirectEvents();
438         $data = array(
439             'grademodified_' . $this->students[0]->id => time(),
440             'gradeattempt_' . $this->students[0]->id => '',
441             'quickgrade_' . $this->students[0]->id => '60.0',
442             'quickgrade_' . $this->students[0]->id . '_workflowstate' => 'inmarking'
443         );
444         $assign->testable_process_save_quick_grades($data);
446         $events = $sink->get_events();
447         $this->assertCount(4, $events);
448         $event = reset($events);
449         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
450         $this->assertEquals($assign->get_context(), $event->get_context());
451         $this->assertEquals($assign->get_instance()->id, $event->objectid);
452         $this->assertEquals($this->students[0]->id, $event->relateduserid);
453         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
454         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INMARKING, $event->other['newstate']);
455         $expected = array(
456             $assign->get_course()->id,
457             'assign',
458             'set marking workflow state',
459             'view.php?id=' . $assign->get_course_module()->id,
460             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
461                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INMARKING)),
462             $assign->get_course_module()->id
463         );
464         $this->assertEventLegacyLogData($expected, $event);
465         $sink->close();
467         // Revert to defaults.
468         $this->editingteachers[0]->ignoresesskey = false;
469     }
471     public function test_submission_duplicated() {
472         $this->setUser($this->students[0]);
474         $assign = $this->create_instance();
475         $submission1 = $assign->get_user_submission($this->students[0]->id, true, 0);
476         $submission2 = $assign->get_user_submission($this->students[0]->id, true, 1);
477         $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
478         $assign->testable_update_submission($submission2, $this->students[0]->id, time(), $assign->get_instance()->teamsubmission);
480         $sink = $this->redirectEvents();
481         $notices = null;
482         $assign->copy_previous_attempt($notices);
484         $events = $sink->get_events();
485         $this->assertCount(1, $events);
486         $event = reset($events);
487         $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
488         $this->assertEquals($assign->get_context(), $event->get_context());
489         $this->assertEquals($submission2->id, $event->objectid);
490         $this->assertEquals($this->students[0]->id, $event->userid);
491         $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
492         $expected = array(
493             $assign->get_course()->id,
494             'assign',
495             'submissioncopied',
496             'view.php?id=' . $assign->get_course_module()->id,
497             $assign->testable_format_submission_for_log($submission2),
498             $assign->get_course_module()->id
499         );
500         $this->assertEventLegacyLogData($expected, $event);
501         $sink->close();
502     }
504     public function test_submission_unlocked() {
505         $this->editingteachers[0]->ignoresesskey = true;
506         $this->setUser($this->editingteachers[0]);
508         $assign = $this->create_instance();
509         $sink = $this->redirectEvents();
511         $assign->unlock_submission($this->students[0]->id);
513         $events = $sink->get_events();
514         $this->assertCount(1, $events);
515         $event = reset($events);
516         $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
517         $this->assertEquals($assign->get_context(), $event->get_context());
518         $this->assertEquals($assign->get_instance()->id, $event->objectid);
519         $this->assertEquals($this->students[0]->id, $event->relateduserid);
520         $expected = array(
521             $assign->get_course()->id,
522             'assign',
523             'unlock submission',
524             'view.php?id=' . $assign->get_course_module()->id,
525             get_string('unlocksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
526                 'fullname' => fullname($this->students[0]))),
527             $assign->get_course_module()->id
528         );
529         $this->assertEventLegacyLogData($expected, $event);
530         $sink->close();
532         // Revert to defaults.
533         $this->editingteachers[0]->ignoresesskey = false;
534     }
536     public function test_submission_graded() {
537         $this->editingteachers[0]->ignoresesskey = true;
538         $this->setUser($this->editingteachers[0]);
539         $assign = $this->create_instance();
541         // Test apply_grade_to_user.
542         $sink = $this->redirectEvents();
544         $data = new stdClass();
545         $data->grade = '50.0';
546         $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
547         $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
549         $events = $sink->get_events();
550         $this->assertCount(3, $events);
551         $event = $events[2];
552         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
553         $this->assertEquals($assign->get_context(), $event->get_context());
554         $this->assertEquals($grade->id, $event->objectid);
555         $this->assertEquals($this->students[0]->id, $event->relateduserid);
556         $expected = array(
557             $assign->get_course()->id,
558             'assign',
559             'grade submission',
560             'view.php?id=' . $assign->get_course_module()->id,
561             $assign->format_grade_for_log($grade),
562             $assign->get_course_module()->id
563         );
564         $this->assertEventLegacyLogData($expected, $event);
565         $sink->close();
567         // Test process_save_quick_grades.
568         $sink = $this->redirectEvents();
570         $grade = $assign->get_user_grade($this->students[0]->id, false);
571         $data = array(
572             'grademodified_' . $this->students[0]->id => time(),
573             'gradeattempt_' . $this->students[0]->id => $grade->attemptnumber,
574             'quickgrade_' . $this->students[0]->id => '60.0'
575         );
576         $assign->testable_process_save_quick_grades($data);
577         $grade = $assign->get_user_grade($this->students[0]->id, false);
578         $this->assertEquals('60.0', $grade->grade);
580         $events = $sink->get_events();
581         $this->assertCount(3, $events);
582         $event = $events[2];
583         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
584         $this->assertEquals($assign->get_context(), $event->get_context());
585         $this->assertEquals($grade->id, $event->objectid);
586         $this->assertEquals($this->students[0]->id, $event->relateduserid);
587         $expected = array(
588             $assign->get_course()->id,
589             'assign',
590             'grade submission',
591             'view.php?id=' . $assign->get_course_module()->id,
592             $assign->format_grade_for_log($grade),
593             $assign->get_course_module()->id
594         );
595         $this->assertEventLegacyLogData($expected, $event);
596         $sink->close();
598         // Test update_grade.
599         $sink = $this->redirectEvents();
600         $data = clone($grade);
601         $data->grade = '50.0';
602         $assign->update_grade($data);
603         $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
604         $this->assertEquals('50.0', $grade->grade);
605         $events = $sink->get_events();
607         $this->assertCount(3, $events);
608         $event = $events[2];
609         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
610         $this->assertEquals($assign->get_context(), $event->get_context());
611         $this->assertEquals($grade->id, $event->objectid);
612         $this->assertEquals($this->students[0]->id, $event->relateduserid);
613         $expected = array(
614             $assign->get_course()->id,
615             'assign',
616             'grade submission',
617             'view.php?id=' . $assign->get_course_module()->id,
618             $assign->format_grade_for_log($grade),
619             $assign->get_course_module()->id
620         );
621         $this->assertEventLegacyLogData($expected, $event);
622         $sink->close();
623         // Revert to defaults.
624         $this->editingteachers[0]->ignoresesskey = false;
625     }
627     /**
628      * Test the submission_viewed event.
629      */
630     public function test_submission_viewed() {
631         global $PAGE;
633         $this->setUser($this->editingteachers[0]);
635         $assign = $this->create_instance();
636         $submission = $assign->get_user_submission($this->students[0]->id, true);
638         // We need to set the URL in order to view the submission.
639         $PAGE->set_url('/a_url');
640         // A hack - these variables are used by the view_plugin_content function to
641         // determine what we actually want to view - would usually be set in URL.
642         global $_POST;
643         $_POST['plugin'] = 'comments';
644         $_POST['sid'] = $submission->id;
646         // Trigger and capture the event.
647         $sink = $this->redirectEvents();
648         $assign->view('viewpluginassignsubmission');
649         $events = $sink->get_events();
650         $this->assertCount(1, $events);
651         $event = reset($events);
653         // Check that the event contains the expected values.
654         $this->assertInstanceOf('\mod_assign\event\submission_viewed', $event);
655         $this->assertEquals($assign->get_context(), $event->get_context());
656         $this->assertEquals($submission->id, $event->objectid);
657         $expected = array(
658             $assign->get_course()->id,
659             'assign',
660             'view submission',
661             'view.php?id=' . $assign->get_course_module()->id,
662             get_string('viewsubmissionforuser', 'assign', $this->students[0]->id),
663             $assign->get_course_module()->id
664         );
665         $this->assertEventLegacyLogData($expected, $event);
666         $this->assertEventContextNotUsed($event);
667     }
669     /**
670      * Test the feedback_viewed event.
671      */
672     public function test_feedback_viewed() {
673         global $DB, $PAGE;
675         $this->setUser($this->editingteachers[0]);
677         $assign = $this->create_instance();
678         $submission = $assign->get_user_submission($this->students[0]->id, true);
680         // Insert a grade for this submission.
681         $grade = new stdClass();
682         $grade->assignment = $assign->get_instance()->id;
683         $grade->userid = $this->students[0]->id;
684         $gradeid = $DB->insert_record('assign_grades', $grade);
686         // We need to set the URL in order to view the feedback.
687         $PAGE->set_url('/a_url');
688         // A hack - these variables are used by the view_plugin_content function to
689         // determine what we actually want to view - would usually be set in URL.
690         global $_POST;
691         $_POST['plugin'] = 'comments';
692         $_POST['gid'] = $gradeid;
693         $_POST['sid'] = $submission->id;
695         // Trigger and capture the event.
696         $sink = $this->redirectEvents();
697         $assign->view('viewpluginassignfeedback');
698         $events = $sink->get_events();
699         $this->assertCount(1, $events);
700         $event = reset($events);
702         // Check that the event contains the expected values.
703         $this->assertInstanceOf('\mod_assign\event\feedback_viewed', $event);
704         $this->assertEquals($assign->get_context(), $event->get_context());
705         $this->assertEquals($gradeid, $event->objectid);
706         $expected = array(
707             $assign->get_course()->id,
708             'assign',
709             'view feedback',
710             'view.php?id=' . $assign->get_course_module()->id,
711             get_string('viewfeedbackforuser', 'assign', $this->students[0]->id),
712             $assign->get_course_module()->id
713         );
714         $this->assertEventLegacyLogData($expected, $event);
715         $this->assertEventContextNotUsed($event);
716     }
718     /**
719      * Test the grading_form_viewed event.
720      */
721     public function test_grading_form_viewed() {
722         global $PAGE;
724         $this->setUser($this->editingteachers[0]);
726         $assign = $this->create_instance();
728         // We need to set the URL in order to view the feedback.
729         $PAGE->set_url('/a_url');
730         // A hack - this variable is used by the view_single_grade_page function.
731         global $_POST;
732         $_POST['rownum'] = 1;
733         $_POST['userid'] = $this->students[0]->id;
735         // Trigger and capture the event.
736         $sink = $this->redirectEvents();
737         $assign->view('grade');
738         $events = $sink->get_events();
739         $this->assertCount(1, $events);
740         $event = reset($events);
742         // Check that the event contains the expected values.
743         $this->assertInstanceOf('\mod_assign\event\grading_form_viewed', $event);
744         $this->assertEquals($assign->get_context(), $event->get_context());
745         $expected = array(
746             $assign->get_course()->id,
747             'assign',
748             'view grading form',
749             'view.php?id=' . $assign->get_course_module()->id,
750             get_string('viewgradingformforstudent', 'assign', array('id' => $this->students[0]->id,
751                 'fullname' => fullname($this->students[0]))),
752             $assign->get_course_module()->id
753         );
754         $this->assertEventLegacyLogData($expected, $event);
755         $this->assertEventContextNotUsed($event);
756     }
758     /**
759      * Test the grading_table_viewed event.
760      */
761     public function test_grading_table_viewed() {
762         global $PAGE;
764         $this->setUser($this->editingteachers[0]);
766         $assign = $this->create_instance();
768         // We need to set the URL in order to view the feedback.
769         $PAGE->set_url('/a_url');
770         // A hack - this variable is used by the view_single_grade_page function.
771         global $_POST;
772         $_POST['rownum'] = 1;
773         $_POST['userid'] = $this->students[0]->id;
775         // Trigger and capture the event.
776         $sink = $this->redirectEvents();
777         $assign->view('grading');
778         $events = $sink->get_events();
779         $this->assertCount(1, $events);
780         $event = reset($events);
782         // Check that the event contains the expected values.
783         $this->assertInstanceOf('\mod_assign\event\grading_table_viewed', $event);
784         $this->assertEquals($assign->get_context(), $event->get_context());
785         $expected = array(
786             $assign->get_course()->id,
787             'assign',
788             'view submission grading table',
789             'view.php?id=' . $assign->get_course_module()->id,
790             get_string('viewsubmissiongradingtable', 'assign'),
791             $assign->get_course_module()->id
792         );
793         $this->assertEventLegacyLogData($expected, $event);
794         $this->assertEventContextNotUsed($event);
795     }
797     /**
798      * Test the submission_form_viewed event.
799      */
800     public function test_submission_form_viewed() {
801         global $PAGE;
803         $this->setUser($this->students[0]);
805         $assign = $this->create_instance();
807         // We need to set the URL in order to view the submission form.
808         $PAGE->set_url('/a_url');
810         // Trigger and capture the event.
811         $sink = $this->redirectEvents();
812         $assign->view('editsubmission');
813         $events = $sink->get_events();
814         $this->assertCount(1, $events);
815         $event = reset($events);
817         // Check that the event contains the expected values.
818         $this->assertInstanceOf('\mod_assign\event\submission_form_viewed', $event);
819         $this->assertEquals($assign->get_context(), $event->get_context());
820         $expected = array(
821             $assign->get_course()->id,
822             'assign',
823             'view submit assignment form',
824             'view.php?id=' . $assign->get_course_module()->id,
825             get_string('editsubmission', 'assign'),
826             $assign->get_course_module()->id
827         );
828         $this->assertEventLegacyLogData($expected, $event);
829         $this->assertEventContextNotUsed($event);
830     }
832     /**
833      * Test the submission_form_viewed event.
834      */
835     public function test_submission_confirmation_form_viewed() {
836         global $PAGE;
838         $this->setUser($this->students[0]);
840         $assign = $this->create_instance();
842         // We need to set the URL in order to view the submission form.
843         $PAGE->set_url('/a_url');
845         // Trigger and capture the event.
846         $sink = $this->redirectEvents();
847         $assign->view('submit');
848         $events = $sink->get_events();
849         $this->assertCount(1, $events);
850         $event = reset($events);
852         // Check that the event contains the expected values.
853         $this->assertInstanceOf('\mod_assign\event\submission_confirmation_form_viewed', $event);
854         $this->assertEquals($assign->get_context(), $event->get_context());
855         $expected = array(
856             $assign->get_course()->id,
857             'assign',
858             'view confirm submit assignment form',
859             'view.php?id=' . $assign->get_course_module()->id,
860             get_string('viewownsubmissionform', 'assign'),
861             $assign->get_course_module()->id
862         );
863         $this->assertEventLegacyLogData($expected, $event);
864         $this->assertEventContextNotUsed($event);
865     }
867     /**
868      * Test the reveal_identities_confirmation_page_viewed event.
869      */
870     public function test_reveal_identities_confirmation_page_viewed() {
871         global $PAGE;
873         // Set to the admin user so we have the permission to reveal identities.
874         $this->setAdminUser();
876         $assign = $this->create_instance();
878         // We need to set the URL in order to view the submission form.
879         $PAGE->set_url('/a_url');
881         // Trigger and capture the event.
882         $sink = $this->redirectEvents();
883         $assign->view('revealidentities');
884         $events = $sink->get_events();
885         $this->assertCount(1, $events);
886         $event = reset($events);
888         // Check that the event contains the expected values.
889         $this->assertInstanceOf('\mod_assign\event\reveal_identities_confirmation_page_viewed', $event);
890         $this->assertEquals($assign->get_context(), $event->get_context());
891         $expected = array(
892             $assign->get_course()->id,
893             'assign',
894             'view',
895             'view.php?id=' . $assign->get_course_module()->id,
896             get_string('viewrevealidentitiesconfirm', 'assign'),
897             $assign->get_course_module()->id
898         );
899         $this->assertEventLegacyLogData($expected, $event);
900         $this->assertEventContextNotUsed($event);
901     }
903     /**
904      * Test the statement_accepted event.
905      */
906     public function test_statement_accepted() {
907         // We want to be a student so we can submit assignments.
908         $this->setUser($this->students[0]);
910         // We do not want to send any messages to the student during the PHPUNIT test.
911         set_config('submissionreceipts', false, 'assign');
913         $assign = $this->create_instance();
915         // Create the data we want to pass to the submit_for_grading function.
916         $data = new stdClass();
917         $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
918             to these terms?';
920         // Trigger and capture the event.
921         $sink = $this->redirectEvents();
922         $assign->submit_for_grading($data, array());
923         $events = $sink->get_events();
924         $event = reset($events);
926         // Check that the event contains the expected values.
927         $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
928         $this->assertEquals($assign->get_context(), $event->get_context());
929         $expected = array(
930             $assign->get_course()->id,
931             'assign',
932             'submission statement accepted',
933             'view.php?id=' . $assign->get_course_module()->id,
934             get_string('submissionstatementacceptedlog',
935                 'mod_assign',
936                 fullname($this->students[0])),
937             $assign->get_course_module()->id
938         );
939         $this->assertEventLegacyLogData($expected, $event);
940         $this->assertEventContextNotUsed($event);
942         // Enable the online text submission plugin.
943         $submissionplugins = $assign->get_submission_plugins();
944         foreach ($submissionplugins as $plugin) {
945             if ($plugin->get_type() === 'onlinetext') {
946                 $plugin->enable();
947                 break;
948             }
949         }
951         // Create the data we want to pass to the save_submission function.
952         $data = new stdClass();
953         $data->onlinetext_editor = array(
954             'text' => 'Online text',
955             'format' => FORMAT_HTML,
956             'itemid' => file_get_unused_draft_itemid()
957         );
958         $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
959             to these terms?';
961         // Trigger and capture the event.
962         $sink = $this->redirectEvents();
963         $assign->save_submission($data, $notices);
964         $events = $sink->get_events();
965         $event = $events[2];
967         // Check that the event contains the expected values.
968         $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
969         $this->assertEquals($assign->get_context(), $event->get_context());
970         $this->assertEventLegacyLogData($expected, $event);
971         $this->assertEventContextNotUsed($event);
972     }
974     /**
975      * Test the batch_set_workflow_state_viewed event.
976      */
977     public function test_batch_set_workflow_state_viewed() {
978         $assign = $this->create_instance();
980         // Trigger and capture the event.
981         $sink = $this->redirectEvents();
982         $assign->testable_view_batch_set_workflow_state($this->students[0]->id);
983         $events = $sink->get_events();
984         $event = reset($events);
986         // Check that the event contains the expected values.
987         $this->assertInstanceOf('\mod_assign\event\batch_set_workflow_state_viewed', $event);
988         $this->assertEquals($assign->get_context(), $event->get_context());
989         $expected = array(
990             $assign->get_course()->id,
991             'assign',
992             'view batch set marking workflow state',
993             'view.php?id=' . $assign->get_course_module()->id,
994             get_string('viewbatchsetmarkingworkflowstate', 'assign'),
995             $assign->get_course_module()->id
996         );
997         $this->assertEventLegacyLogData($expected, $event);
998         $this->assertEventContextNotUsed($event);
999     }
1001     /**
1002      * Test the batch_set_marker_allocation_viewed event.
1003      */
1004     public function test_batch_set_marker_allocation_viewed() {
1005         $assign = $this->create_instance();
1007         // Trigger and capture the event.
1008         $sink = $this->redirectEvents();
1009         $assign->testable_view_batch_markingallocation($this->students[0]->id);
1010         $events = $sink->get_events();
1011         $event = reset($events);
1013         // Check that the event contains the expected values.
1014         $this->assertInstanceOf('\mod_assign\event\batch_set_marker_allocation_viewed', $event);
1015         $this->assertEquals($assign->get_context(), $event->get_context());
1016         $expected = array(
1017             $assign->get_course()->id,
1018             'assign',
1019             'view batch set marker allocation',
1020             'view.php?id=' . $assign->get_course_module()->id,
1021             get_string('viewbatchmarkingallocation', 'assign'),
1022             $assign->get_course_module()->id
1023         );
1024         $this->assertEventLegacyLogData($expected, $event);
1025         $this->assertEventContextNotUsed($event);
1026     }
1028     /**
1029      * Test the user override created event.
1030      *
1031      * There is no external API for creating a user override, so the unit test will simply
1032      * create and trigger the event and ensure the event data is returned as expected.
1033      */
1034     public function test_user_override_created() {
1036         $course = $this->getDataGenerator()->create_course();
1037         $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1039         $params = array(
1040             'objectid' => 1,
1041             'relateduserid' => 2,
1042             'context' => context_module::instance($assign->cmid),
1043             'other' => array(
1044                 'assignid' => $assign->id
1045             )
1046         );
1047         $event = \mod_assign\event\user_override_created::create($params);
1049         // Trigger and capture the event.
1050         $sink = $this->redirectEvents();
1051         $event->trigger();
1052         $events = $sink->get_events();
1053         $event = reset($events);
1055         // Check that the event data is valid.
1056         $this->assertInstanceOf('\mod_assign\event\user_override_created', $event);
1057         $this->assertEquals(context_module::instance($assign->cmid), $event->get_context());
1058         $this->assertEventContextNotUsed($event);
1059     }
1061     /**
1062      * Test the group override created event.
1063      *
1064      * There is no external API for creating a group override, so the unit test will simply
1065      * create and trigger the event and ensure the event data is returned as expected.
1066      */
1067     public function test_group_override_created() {
1069         $course = $this->getDataGenerator()->create_course();
1070         $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1072         $params = array(
1073             'objectid' => 1,
1074             'context' => context_module::instance($assign->cmid),
1075             'other' => array(
1076                 'assignid' => $assign->id,
1077                 'groupid' => 2
1078             )
1079         );
1080         $event = \mod_assign\event\group_override_created::create($params);
1082         // Trigger and capture the event.
1083         $sink = $this->redirectEvents();
1084         $event->trigger();
1085         $events = $sink->get_events();
1086         $event = reset($events);
1088         // Check that the event data is valid.
1089         $this->assertInstanceOf('\mod_assign\event\group_override_created', $event);
1090         $this->assertEquals(context_module::instance($assign->cmid), $event->get_context());
1091         $this->assertEventContextNotUsed($event);
1092     }
1094     /**
1095      * Test the user override updated event.
1096      *
1097      * There is no external API for updating a user override, so the unit test will simply
1098      * create and trigger the event and ensure the event data is returned as expected.
1099      */
1100     public function test_user_override_updated() {
1102         $course = $this->getDataGenerator()->create_course();
1103         $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1105         $params = array(
1106             'objectid' => 1,
1107             'relateduserid' => 2,
1108             'context' => context_module::instance($assign->cmid),
1109             'other' => array(
1110                 'assignid' => $assign->id
1111             )
1112         );
1113         $event = \mod_assign\event\user_override_updated::create($params);
1115         // Trigger and capture the event.
1116         $sink = $this->redirectEvents();
1117         $event->trigger();
1118         $events = $sink->get_events();
1119         $event = reset($events);
1121         // Check that the event data is valid.
1122         $this->assertInstanceOf('\mod_assign\event\user_override_updated', $event);
1123         $this->assertEquals(context_module::instance($assign->cmid), $event->get_context());
1124         $this->assertEventContextNotUsed($event);
1125     }
1127     /**
1128      * Test the group override updated event.
1129      *
1130      * There is no external API for updating a group override, so the unit test will simply
1131      * create and trigger the event and ensure the event data is returned as expected.
1132      */
1133     public function test_group_override_updated() {
1135         $course = $this->getDataGenerator()->create_course();
1136         $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1138         $params = array(
1139             'objectid' => 1,
1140             'context' => context_module::instance($assign->cmid),
1141             'other' => array(
1142                 'assignid' => $assign->id,
1143                 'groupid' => 2
1144             )
1145         );
1146         $event = \mod_assign\event\group_override_updated::create($params);
1148         // Trigger and capture the event.
1149         $sink = $this->redirectEvents();
1150         $event->trigger();
1151         $events = $sink->get_events();
1152         $event = reset($events);
1154         // Check that the event data is valid.
1155         $this->assertInstanceOf('\mod_assign\event\group_override_updated', $event);
1156         $this->assertEquals(context_module::instance($assign->cmid), $event->get_context());
1157         $this->assertEventContextNotUsed($event);
1158     }
1160     /**
1161      * Test the user override deleted event.
1162      */
1163     public function test_user_override_deleted() {
1164         global $DB;
1166         $course = $this->getDataGenerator()->create_course();
1167         $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1168         $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1169         $context = context_module::instance($cm->id);
1170         $assign = new assign($context, $cm, $course);
1172         // Create an override.
1173         $override = new stdClass();
1174         $override->assign = $assigninstance->id;
1175         $override->userid = 2;
1176         $override->id = $DB->insert_record('assign_overrides', $override);
1178         // Trigger and capture the event.
1179         $sink = $this->redirectEvents();
1180         $assign->delete_override($override->id);
1181         $events = $sink->get_events();
1182         $event = reset($events);
1184         // Check that the event data is valid.
1185         $this->assertInstanceOf('\mod_assign\event\user_override_deleted', $event);
1186         $this->assertEquals(context_module::instance($cm->id), $event->get_context());
1187         $this->assertEventContextNotUsed($event);
1188     }
1190     /**
1191      * Test the group override deleted event.
1192      */
1193     public function test_group_override_deleted() {
1194         global $DB;
1196         $course = $this->getDataGenerator()->create_course();
1197         $assigninstance = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
1198         $cm = get_coursemodule_from_instance('assign', $assigninstance->id, $course->id);
1199         $context = context_module::instance($cm->id);
1200         $assign = new assign($context, $cm, $course);
1202         // Create an override.
1203         $override = new stdClass();
1204         $override->assign = $assigninstance->id;
1205         $override->groupid = 2;
1206         $override->id = $DB->insert_record('assign_overrides', $override);
1208         // Trigger and capture the event.
1209         $sink = $this->redirectEvents();
1210         $assign->delete_override($override->id);
1211         $events = $sink->get_events();
1212         $event = reset($events);
1214         // Check that the event data is valid.
1215         $this->assertInstanceOf('\mod_assign\event\group_override_deleted', $event);
1216         $this->assertEquals(context_module::instance($cm->id), $event->get_context());
1217         $this->assertEventContextNotUsed($event);
1218     }