MDL-48778 assign: Use proper latest attempt for quickgrading prechecks
[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');
31 /**
32  * Contains the event tests for the module assign.
33  *
34  * @package   mod_assign
35  * @copyright 2014 Adrian Greeve <adrian@moodle.com>
36  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class assign_events_testcase extends mod_assign_base_testcase {
40     /**
41      * Basic tests for the submission_created() abstract class.
42      */
43     public function test_base_event() {
44         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
45         $instance = $generator->create_instance(array('course' => $this->course->id));
46         $modcontext = context_module::instance($instance->cmid);
48         $data = array(
49             'context' => $modcontext,
50         );
51         /** @var \mod_assign_unittests\event\nothing_happened $event */
52         $event = \mod_assign_unittests\event\nothing_happened::create($data);
53         $assign = $event->get_assign();
54         $this->assertDebuggingCalled();
55         $this->assertInstanceOf('assign', $assign);
57         $event = \mod_assign_unittests\event\nothing_happened::create($data);
58         $event->set_assign($assign);
59         $assign2 = $event->get_assign();
60         $this->assertDebuggingNotCalled();
61         $this->assertSame($assign, $assign2);
62     }
64     /**
65      * Basic tests for the submission_created() abstract class.
66      */
67     public function test_submission_created() {
68         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
69         $instance = $generator->create_instance(array('course' => $this->course->id));
70         $modcontext = context_module::instance($instance->cmid);
72         // Standard Event parameters.
73         $params = array(
74             'context' => $modcontext,
75             'courseid' => $this->course->id
76         );
78         $eventinfo = $params;
79         $eventinfo['other'] = array(
80             'submissionid' => '17',
81             'submissionattempt' => 0,
82             'submissionstatus' => 'submitted'
83         );
85         $sink = $this->redirectEvents();
86         $event = \mod_assign_unittests\event\submission_created::create($eventinfo);
87         $event->trigger();
88         $result = $sink->get_events();
89         $event = reset($result);
90         $sink->close();
92         $this->assertEquals($modcontext->id, $event->contextid);
93         $this->assertEquals($this->course->id, $event->courseid);
95         // Check that an error occurs when teamsubmission is not set.
96         try {
97             \mod_assign_unittests\event\submission_created::create($params);
98             $this->fail('Other must contain the key submissionid.');
99         } catch (Exception $e) {
100             $this->assertInstanceOf('coding_exception', $e);
101         }
102         // Check that the submission status debugging is fired.
103         $subinfo = $params;
104         $subinfo['other'] = array('submissionid' => '23');
105         try {
106             \mod_assign_unittests\event\submission_created::create($subinfo);
107             $this->fail('Other must contain the key submissionattempt.');
108         } catch (Exception $e) {
109             $this->assertInstanceOf('coding_exception', $e);
110         }
112         $subinfo['other'] = array('submissionattempt' => '0');
113         try {
114             \mod_assign_unittests\event\submission_created::create($subinfo);
115             $this->fail('Other must contain the key submissionstatus.');
116         } catch (Exception $e) {
117             $this->assertInstanceOf('coding_exception', $e);
118         }
119     }
121     /**
122      * Basic tests for the submission_updated() abstract class.
123      */
124     public function test_submission_updated() {
125         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
126         $instance = $generator->create_instance(array('course' => $this->course->id));
127         $modcontext = context_module::instance($instance->cmid);
129         // Standard Event parameters.
130         $params = array(
131             'context' => $modcontext,
132             'courseid' => $this->course->id
133         );
135         $eventinfo = $params;
136         $eventinfo['other'] = array(
137             'submissionid' => '17',
138             'submissionattempt' => 0,
139             'submissionstatus' => 'submitted'
140         );
142         $sink = $this->redirectEvents();
143         $event = \mod_assign_unittests\event\submission_updated::create($eventinfo);
144         $event->trigger();
145         $result = $sink->get_events();
146         $event = reset($result);
147         $sink->close();
149         $this->assertEquals($modcontext->id, $event->contextid);
150         $this->assertEquals($this->course->id, $event->courseid);
152         // Check that an error occurs when teamsubmission is not set.
153         try {
154             \mod_assign_unittests\event\submission_created::create($params);
155             $this->fail('Other must contain the key submissionid.');
156         } catch (Exception $e) {
157             $this->assertInstanceOf('coding_exception', $e);
158         }
159         // Check that the submission status debugging is fired.
160         $subinfo = $params;
161         $subinfo['other'] = array('submissionid' => '23');
162         try {
163             \mod_assign_unittests\event\submission_created::create($subinfo);
164             $this->fail('Other must contain the key submissionattempt.');
165         } catch (Exception $e) {
166             $this->assertInstanceOf('coding_exception', $e);
167         }
169         $subinfo['other'] = array('submissionattempt' => '0');
170         try {
171             \mod_assign_unittests\event\submission_created::create($subinfo);
172             $this->fail('Other must contain the key submissionstatus.');
173         } catch (Exception $e) {
174             $this->assertInstanceOf('coding_exception', $e);
175         }
176     }
178     public function test_extension_granted() {
179         $this->setUser($this->editingteachers[0]);
181         $tomorrow = time() + 24*60*60;
182         $yesterday = time() - 24*60*60;
184         $assign = $this->create_instance(array('duedate' => $yesterday, 'cutoffdate' => $yesterday));
185         $sink = $this->redirectEvents();
187         $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
189         $events = $sink->get_events();
190         $this->assertCount(1, $events);
191         $event = reset($events);
192         $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
193         $this->assertEquals($assign->get_context(), $event->get_context());
194         $this->assertEquals($assign->get_instance()->id, $event->objectid);
195         $this->assertEquals($this->students[0]->id, $event->relateduserid);
196         $expected = array(
197             $assign->get_course()->id,
198             'assign',
199             'grant extension',
200             'view.php?id=' . $assign->get_course_module()->id,
201             $this->students[0]->id,
202             $assign->get_course_module()->id
203         );
204         $this->assertEventLegacyLogData($expected, $event);
205         $sink->close();
206     }
208     public function test_submission_locked() {
209         $this->editingteachers[0]->ignoresesskey = true;
210         $this->setUser($this->editingteachers[0]);
212         $assign = $this->create_instance();
213         $sink = $this->redirectEvents();
215         $assign->lock_submission($this->students[0]->id);
217         $events = $sink->get_events();
218         $this->assertCount(1, $events);
219         $event = reset($events);
220         $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
221         $this->assertEquals($assign->get_context(), $event->get_context());
222         $this->assertEquals($assign->get_instance()->id, $event->objectid);
223         $this->assertEquals($this->students[0]->id, $event->relateduserid);
224         $expected = array(
225             $assign->get_course()->id,
226             'assign',
227             'lock submission',
228             'view.php?id=' . $assign->get_course_module()->id,
229             get_string('locksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
230                 'fullname' => fullname($this->students[0]))),
231             $assign->get_course_module()->id
232         );
233         $this->assertEventLegacyLogData($expected, $event);
234         $sink->close();
236         // Revert to defaults.
237         $this->editingteachers[0]->ignoresesskey = false;
238     }
240     public function test_identities_revealed() {
241         $this->editingteachers[0]->ignoresesskey = true;
242         $this->setUser($this->editingteachers[0]);
244         $assign = $this->create_instance(array('blindmarking'=>1));
245         $sink = $this->redirectEvents();
247         $assign->reveal_identities();
249         $events = $sink->get_events();
250         $this->assertCount(1, $events);
251         $event = reset($events);
252         $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
253         $this->assertEquals($assign->get_context(), $event->get_context());
254         $this->assertEquals($assign->get_instance()->id, $event->objectid);
255         $expected = array(
256             $assign->get_course()->id,
257             'assign',
258             'reveal identities',
259             'view.php?id=' . $assign->get_course_module()->id,
260             get_string('revealidentities', 'assign'),
261             $assign->get_course_module()->id
262         );
263         $this->assertEventLegacyLogData($expected, $event);
264         $sink->close();
266         // Revert to defaults.
267         $this->editingteachers[0]->ignoresesskey = false;
268     }
270     /**
271      * Test the submission_status_viewed event.
272      */
273     public function test_submission_status_viewed() {
274         global $PAGE;
276         $this->setUser($this->editingteachers[0]);
278         $assign = $this->create_instance();
280         // We need to set the URL in order to view the feedback.
281         $PAGE->set_url('/a_url');
283         // Trigger and capture the event.
284         $sink = $this->redirectEvents();
285         $assign->view();
286         $events = $sink->get_events();
287         $this->assertCount(1, $events);
288         $event = reset($events);
290         // Check that the event contains the expected values.
291         $this->assertInstanceOf('\mod_assign\event\submission_status_viewed', $event);
292         $this->assertEquals($assign->get_context(), $event->get_context());
293         $expected = array(
294             $assign->get_course()->id,
295             'assign',
296             'view',
297             'view.php?id=' . $assign->get_course_module()->id,
298             get_string('viewownsubmissionstatus', 'assign'),
299             $assign->get_course_module()->id
300         );
301         $this->assertEventLegacyLogData($expected, $event);
302         $this->assertEventContextNotUsed($event);
303     }
305     public function test_submission_status_updated() {
306         $this->editingteachers[0]->ignoresesskey = true;
307         $this->setUser($this->editingteachers[0]);
309         $assign = $this->create_instance();
310         $submission = $assign->get_user_submission($this->students[0]->id, true);
311         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
312         $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
314         $sink = $this->redirectEvents();
315         $assign->revert_to_draft($this->students[0]->id);
317         $events = $sink->get_events();
318         $this->assertCount(2, $events);
319         $event = $events[1];
320         $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
321         $this->assertEquals($assign->get_context(), $event->get_context());
322         $this->assertEquals($submission->id, $event->objectid);
323         $this->assertEquals($this->students[0]->id, $event->relateduserid);
324         $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
325         $expected = array(
326             $assign->get_course()->id,
327             'assign',
328             'revert submission to draft',
329             'view.php?id=' . $assign->get_course_module()->id,
330             get_string('reverttodraftforstudent', 'assign', array('id' => $this->students[0]->id,
331                 'fullname' => fullname($this->students[0]))),
332             $assign->get_course_module()->id
333         );
334         $this->assertEventLegacyLogData($expected, $event);
335         $sink->close();
337         // Revert to defaults.
338         $this->editingteachers[0]->ignoresesskey = false;
339     }
341     public function test_marker_updated() {
342         $this->editingteachers[0]->ignoresesskey = true;
343         $this->setUser($this->editingteachers[0]);
345         $assign = $this->create_instance();
347         $sink = $this->redirectEvents();
348         $assign->testable_process_set_batch_marking_allocation($this->students[0]->id, $this->teachers[0]->id);
350         $events = $sink->get_events();
351         $this->assertCount(1, $events);
352         $event = reset($events);
353         $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
354         $this->assertEquals($assign->get_context(), $event->get_context());
355         $this->assertEquals($assign->get_instance()->id, $event->objectid);
356         $this->assertEquals($this->students[0]->id, $event->relateduserid);
357         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
358         $this->assertEquals($this->teachers[0]->id, $event->other['markerid']);
359         $expected = array(
360             $assign->get_course()->id,
361             'assign',
362             'set marking allocation',
363             'view.php?id=' . $assign->get_course_module()->id,
364             get_string('setmarkerallocationforlog', 'assign', array('id' => $this->students[0]->id,
365                 'fullname' => fullname($this->students[0]), 'marker' => fullname($this->teachers[0]))),
366             $assign->get_course_module()->id
367         );
368         $this->assertEventLegacyLogData($expected, $event);
369         $sink->close();
371         // Revert to defaults.
372         $this->editingteachers[0]->ignoresesskey = false;
373     }
375     public function test_workflow_state_updated() {
376         $this->editingteachers[0]->ignoresesskey = true;
377         $this->setUser($this->editingteachers[0]);
379         $assign = $this->create_instance();
381         // Test process_set_batch_marking_workflow_state.
382         $sink = $this->redirectEvents();
383         $assign->testable_process_set_batch_marking_workflow_state($this->students[0]->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
385         $events = $sink->get_events();
386         $this->assertCount(1, $events);
387         $event = reset($events);
388         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
389         $this->assertEquals($assign->get_context(), $event->get_context());
390         $this->assertEquals($assign->get_instance()->id, $event->objectid);
391         $this->assertEquals($this->students[0]->id, $event->relateduserid);
392         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
393         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
394         $expected = array(
395             $assign->get_course()->id,
396             'assign',
397             'set marking workflow state',
398             'view.php?id=' . $assign->get_course_module()->id,
399             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
400                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW)),
401             $assign->get_course_module()->id
402         );
403         $this->assertEventLegacyLogData($expected, $event);
404         $sink->close();
406         // Test setting workflow state in apply_grade_to_user.
407         $sink = $this->redirectEvents();
408         $data = new stdClass();
409         $data->grade = '50.0';
410         $data->workflowstate = 'readyforrelease';
411         $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
413         $events = $sink->get_events();
414         $this->assertCount(4, $events);
415         $event = reset($events);
416         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
417         $this->assertEquals($assign->get_context(), $event->get_context());
418         $this->assertEquals($assign->get_instance()->id, $event->objectid);
419         $this->assertEquals($this->students[0]->id, $event->relateduserid);
420         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
421         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE, $event->other['newstate']);
422         $expected = array(
423             $assign->get_course()->id,
424             'assign',
425             'set marking workflow state',
426             'view.php?id=' . $assign->get_course_module()->id,
427             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
428                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE)),
429             $assign->get_course_module()->id
430         );
431         $this->assertEventLegacyLogData($expected, $event);
432         $sink->close();
434         // Test setting workflow state in process_save_quick_grades.
435         $sink = $this->redirectEvents();
437         $data = array(
438             'grademodified_' . $this->students[0]->id => time(),
439             'gradeattempt_' . $this->students[0]->id => '',
440             'quickgrade_' . $this->students[0]->id => '60.0',
441             'quickgrade_' . $this->students[0]->id . '_workflowstate' => 'inmarking'
442         );
443         $assign->testable_process_save_quick_grades($data);
445         $events = $sink->get_events();
446         $this->assertCount(4, $events);
447         $event = reset($events);
448         $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
449         $this->assertEquals($assign->get_context(), $event->get_context());
450         $this->assertEquals($assign->get_instance()->id, $event->objectid);
451         $this->assertEquals($this->students[0]->id, $event->relateduserid);
452         $this->assertEquals($this->editingteachers[0]->id, $event->userid);
453         $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INMARKING, $event->other['newstate']);
454         $expected = array(
455             $assign->get_course()->id,
456             'assign',
457             'set marking workflow state',
458             'view.php?id=' . $assign->get_course_module()->id,
459             get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
460                 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INMARKING)),
461             $assign->get_course_module()->id
462         );
463         $this->assertEventLegacyLogData($expected, $event);
464         $sink->close();
466         // Revert to defaults.
467         $this->editingteachers[0]->ignoresesskey = false;
468     }
470     public function test_submission_duplicated() {
471         $this->setUser($this->students[0]);
473         $assign = $this->create_instance();
474         $submission1 = $assign->get_user_submission($this->students[0]->id, true, 0);
475         $submission2 = $assign->get_user_submission($this->students[0]->id, true, 1);
476         $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
477         $assign->testable_update_submission($submission2, $this->students[0]->id, time(), $assign->get_instance()->teamsubmission);
479         $sink = $this->redirectEvents();
480         $notices = null;
481         $assign->copy_previous_attempt($notices);
483         $events = $sink->get_events();
484         $this->assertCount(1, $events);
485         $event = reset($events);
486         $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
487         $this->assertEquals($assign->get_context(), $event->get_context());
488         $this->assertEquals($submission2->id, $event->objectid);
489         $this->assertEquals($this->students[0]->id, $event->userid);
490         $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
491         $expected = array(
492             $assign->get_course()->id,
493             'assign',
494             'submissioncopied',
495             'view.php?id=' . $assign->get_course_module()->id,
496             $assign->testable_format_submission_for_log($submission2),
497             $assign->get_course_module()->id
498         );
499         $this->assertEventLegacyLogData($expected, $event);
500         $sink->close();
501     }
503     public function test_submission_unlocked() {
504         $this->editingteachers[0]->ignoresesskey = true;
505         $this->setUser($this->editingteachers[0]);
507         $assign = $this->create_instance();
508         $sink = $this->redirectEvents();
510         $assign->unlock_submission($this->students[0]->id);
512         $events = $sink->get_events();
513         $this->assertCount(1, $events);
514         $event = reset($events);
515         $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
516         $this->assertEquals($assign->get_context(), $event->get_context());
517         $this->assertEquals($assign->get_instance()->id, $event->objectid);
518         $this->assertEquals($this->students[0]->id, $event->relateduserid);
519         $expected = array(
520             $assign->get_course()->id,
521             'assign',
522             'unlock submission',
523             'view.php?id=' . $assign->get_course_module()->id,
524             get_string('unlocksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
525                 'fullname' => fullname($this->students[0]))),
526             $assign->get_course_module()->id
527         );
528         $this->assertEventLegacyLogData($expected, $event);
529         $sink->close();
531         // Revert to defaults.
532         $this->editingteachers[0]->ignoresesskey = false;
533     }
535     public function test_submission_graded() {
536         $this->editingteachers[0]->ignoresesskey = true;
537         $this->setUser($this->editingteachers[0]);
538         $assign = $this->create_instance();
540         // Test apply_grade_to_user.
541         $sink = $this->redirectEvents();
543         $data = new stdClass();
544         $data->grade = '50.0';
545         $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
546         $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
548         $events = $sink->get_events();
549         $this->assertCount(3, $events);
550         $event = $events[2];
551         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
552         $this->assertEquals($assign->get_context(), $event->get_context());
553         $this->assertEquals($grade->id, $event->objectid);
554         $this->assertEquals($this->students[0]->id, $event->relateduserid);
555         $expected = array(
556             $assign->get_course()->id,
557             'assign',
558             'grade submission',
559             'view.php?id=' . $assign->get_course_module()->id,
560             $assign->format_grade_for_log($grade),
561             $assign->get_course_module()->id
562         );
563         $this->assertEventLegacyLogData($expected, $event);
564         $sink->close();
566         // Test process_save_quick_grades.
567         $sink = $this->redirectEvents();
569         $grade = $assign->get_user_grade($this->students[0]->id, false);
570         $data = array(
571             'grademodified_' . $this->students[0]->id => time(),
572             'gradeattempt_' . $this->students[0]->id => $grade->attemptnumber,
573             'quickgrade_' . $this->students[0]->id => '60.0'
574         );
575         $assign->testable_process_save_quick_grades($data);
576         $grade = $assign->get_user_grade($this->students[0]->id, false);
577         $this->assertEquals('60.0', $grade->grade);
579         $events = $sink->get_events();
580         $this->assertCount(3, $events);
581         $event = $events[2];
582         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
583         $this->assertEquals($assign->get_context(), $event->get_context());
584         $this->assertEquals($grade->id, $event->objectid);
585         $this->assertEquals($this->students[0]->id, $event->relateduserid);
586         $expected = array(
587             $assign->get_course()->id,
588             'assign',
589             'grade submission',
590             'view.php?id=' . $assign->get_course_module()->id,
591             $assign->format_grade_for_log($grade),
592             $assign->get_course_module()->id
593         );
594         $this->assertEventLegacyLogData($expected, $event);
595         $sink->close();
597         // Test update_grade.
598         $sink = $this->redirectEvents();
599         $data = clone($grade);
600         $data->grade = '50.0';
601         $assign->update_grade($data);
602         $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
603         $this->assertEquals('50.0', $grade->grade);
604         $events = $sink->get_events();
606         $this->assertCount(3, $events);
607         $event = $events[2];
608         $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
609         $this->assertEquals($assign->get_context(), $event->get_context());
610         $this->assertEquals($grade->id, $event->objectid);
611         $this->assertEquals($this->students[0]->id, $event->relateduserid);
612         $expected = array(
613             $assign->get_course()->id,
614             'assign',
615             'grade submission',
616             'view.php?id=' . $assign->get_course_module()->id,
617             $assign->format_grade_for_log($grade),
618             $assign->get_course_module()->id
619         );
620         $this->assertEventLegacyLogData($expected, $event);
621         $sink->close();
622         // Revert to defaults.
623         $this->editingteachers[0]->ignoresesskey = false;
624     }
626     /**
627      * Test the submission_viewed event.
628      */
629     public function test_submission_viewed() {
630         global $PAGE;
632         $this->setUser($this->editingteachers[0]);
634         $assign = $this->create_instance();
635         $submission = $assign->get_user_submission($this->students[0]->id, true);
637         // We need to set the URL in order to view the submission.
638         $PAGE->set_url('/a_url');
639         // A hack - these variables are used by the view_plugin_content function to
640         // determine what we actually want to view - would usually be set in URL.
641         global $_POST;
642         $_POST['plugin'] = 'comments';
643         $_POST['sid'] = $submission->id;
645         // Trigger and capture the event.
646         $sink = $this->redirectEvents();
647         $assign->view('viewpluginassignsubmission');
648         $events = $sink->get_events();
649         $this->assertCount(1, $events);
650         $event = reset($events);
652         // Check that the event contains the expected values.
653         $this->assertInstanceOf('\mod_assign\event\submission_viewed', $event);
654         $this->assertEquals($assign->get_context(), $event->get_context());
655         $this->assertEquals($submission->id, $event->objectid);
656         $expected = array(
657             $assign->get_course()->id,
658             'assign',
659             'view submission',
660             'view.php?id=' . $assign->get_course_module()->id,
661             get_string('viewsubmissionforuser', 'assign', $this->students[0]->id),
662             $assign->get_course_module()->id
663         );
664         $this->assertEventLegacyLogData($expected, $event);
665         $this->assertEventContextNotUsed($event);
666     }
668     /**
669      * Test the feedback_viewed event.
670      */
671     public function test_feedback_viewed() {
672         global $DB, $PAGE;
674         $this->setUser($this->editingteachers[0]);
676         $assign = $this->create_instance();
677         $submission = $assign->get_user_submission($this->students[0]->id, true);
679         // Insert a grade for this submission.
680         $grade = new stdClass();
681         $grade->assignment = $assign->get_instance()->id;
682         $grade->userid = $this->students[0]->id;
683         $gradeid = $DB->insert_record('assign_grades', $grade);
685         // We need to set the URL in order to view the feedback.
686         $PAGE->set_url('/a_url');
687         // A hack - these variables are used by the view_plugin_content function to
688         // determine what we actually want to view - would usually be set in URL.
689         global $_POST;
690         $_POST['plugin'] = 'comments';
691         $_POST['gid'] = $gradeid;
692         $_POST['sid'] = $submission->id;
694         // Trigger and capture the event.
695         $sink = $this->redirectEvents();
696         $assign->view('viewpluginassignfeedback');
697         $events = $sink->get_events();
698         $this->assertCount(1, $events);
699         $event = reset($events);
701         // Check that the event contains the expected values.
702         $this->assertInstanceOf('\mod_assign\event\feedback_viewed', $event);
703         $this->assertEquals($assign->get_context(), $event->get_context());
704         $this->assertEquals($gradeid, $event->objectid);
705         $expected = array(
706             $assign->get_course()->id,
707             'assign',
708             'view feedback',
709             'view.php?id=' . $assign->get_course_module()->id,
710             get_string('viewfeedbackforuser', 'assign', $this->students[0]->id),
711             $assign->get_course_module()->id
712         );
713         $this->assertEventLegacyLogData($expected, $event);
714         $this->assertEventContextNotUsed($event);
715     }
717     /**
718      * Test the grading_form_viewed event.
719      */
720     public function test_grading_form_viewed() {
721         global $PAGE;
723         $this->setUser($this->editingteachers[0]);
725         $assign = $this->create_instance();
727         // We need to set the URL in order to view the feedback.
728         $PAGE->set_url('/a_url');
729         // A hack - this variable is used by the view_single_grade_page function.
730         global $_POST;
731         $_POST['rownum'] = 1;
732         $_POST['userid'] = $this->students[0]->id;
734         // Trigger and capture the event.
735         $sink = $this->redirectEvents();
736         $assign->view('grade');
737         $events = $sink->get_events();
738         $this->assertCount(1, $events);
739         $event = reset($events);
741         // Check that the event contains the expected values.
742         $this->assertInstanceOf('\mod_assign\event\grading_form_viewed', $event);
743         $this->assertEquals($assign->get_context(), $event->get_context());
744         $expected = array(
745             $assign->get_course()->id,
746             'assign',
747             'view grading form',
748             'view.php?id=' . $assign->get_course_module()->id,
749             get_string('viewgradingformforstudent', 'assign', array('id' => $this->students[0]->id,
750                 'fullname' => fullname($this->students[0]))),
751             $assign->get_course_module()->id
752         );
753         $this->assertEventLegacyLogData($expected, $event);
754         $this->assertEventContextNotUsed($event);
755     }
757     /**
758      * Test the grading_table_viewed event.
759      */
760     public function test_grading_table_viewed() {
761         global $PAGE;
763         $this->setUser($this->editingteachers[0]);
765         $assign = $this->create_instance();
767         // We need to set the URL in order to view the feedback.
768         $PAGE->set_url('/a_url');
769         // A hack - this variable is used by the view_single_grade_page function.
770         global $_POST;
771         $_POST['rownum'] = 1;
772         $_POST['userid'] = $this->students[0]->id;
774         // Trigger and capture the event.
775         $sink = $this->redirectEvents();
776         $assign->view('grading');
777         $events = $sink->get_events();
778         $this->assertCount(1, $events);
779         $event = reset($events);
781         // Check that the event contains the expected values.
782         $this->assertInstanceOf('\mod_assign\event\grading_table_viewed', $event);
783         $this->assertEquals($assign->get_context(), $event->get_context());
784         $expected = array(
785             $assign->get_course()->id,
786             'assign',
787             'view submission grading table',
788             'view.php?id=' . $assign->get_course_module()->id,
789             get_string('viewsubmissiongradingtable', 'assign'),
790             $assign->get_course_module()->id
791         );
792         $this->assertEventLegacyLogData($expected, $event);
793         $this->assertEventContextNotUsed($event);
794     }
796     /**
797      * Test the submission_form_viewed event.
798      */
799     public function test_submission_form_viewed() {
800         global $PAGE;
802         $this->setUser($this->students[0]);
804         $assign = $this->create_instance();
806         // We need to set the URL in order to view the submission form.
807         $PAGE->set_url('/a_url');
809         // Trigger and capture the event.
810         $sink = $this->redirectEvents();
811         $assign->view('editsubmission');
812         $events = $sink->get_events();
813         $this->assertCount(1, $events);
814         $event = reset($events);
816         // Check that the event contains the expected values.
817         $this->assertInstanceOf('\mod_assign\event\submission_form_viewed', $event);
818         $this->assertEquals($assign->get_context(), $event->get_context());
819         $expected = array(
820             $assign->get_course()->id,
821             'assign',
822             'view submit assignment form',
823             'view.php?id=' . $assign->get_course_module()->id,
824             get_string('editsubmission', 'assign'),
825             $assign->get_course_module()->id
826         );
827         $this->assertEventLegacyLogData($expected, $event);
828         $this->assertEventContextNotUsed($event);
829     }
831     /**
832      * Test the submission_form_viewed event.
833      */
834     public function test_submission_confirmation_form_viewed() {
835         global $PAGE;
837         $this->setUser($this->students[0]);
839         $assign = $this->create_instance();
841         // We need to set the URL in order to view the submission form.
842         $PAGE->set_url('/a_url');
844         // Trigger and capture the event.
845         $sink = $this->redirectEvents();
846         $assign->view('submit');
847         $events = $sink->get_events();
848         $this->assertCount(1, $events);
849         $event = reset($events);
851         // Check that the event contains the expected values.
852         $this->assertInstanceOf('\mod_assign\event\submission_confirmation_form_viewed', $event);
853         $this->assertEquals($assign->get_context(), $event->get_context());
854         $expected = array(
855             $assign->get_course()->id,
856             'assign',
857             'view confirm submit assignment form',
858             'view.php?id=' . $assign->get_course_module()->id,
859             get_string('viewownsubmissionform', 'assign'),
860             $assign->get_course_module()->id
861         );
862         $this->assertEventLegacyLogData($expected, $event);
863         $this->assertEventContextNotUsed($event);
864     }
866     /**
867      * Test the reveal_identities_confirmation_page_viewed event.
868      */
869     public function test_reveal_identities_confirmation_page_viewed() {
870         global $PAGE;
872         // Set to the admin user so we have the permission to reveal identities.
873         $this->setAdminUser();
875         $assign = $this->create_instance();
877         // We need to set the URL in order to view the submission form.
878         $PAGE->set_url('/a_url');
880         // Trigger and capture the event.
881         $sink = $this->redirectEvents();
882         $assign->view('revealidentities');
883         $events = $sink->get_events();
884         $this->assertCount(1, $events);
885         $event = reset($events);
887         // Check that the event contains the expected values.
888         $this->assertInstanceOf('\mod_assign\event\reveal_identities_confirmation_page_viewed', $event);
889         $this->assertEquals($assign->get_context(), $event->get_context());
890         $expected = array(
891             $assign->get_course()->id,
892             'assign',
893             'view',
894             'view.php?id=' . $assign->get_course_module()->id,
895             get_string('viewrevealidentitiesconfirm', 'assign'),
896             $assign->get_course_module()->id
897         );
898         $this->assertEventLegacyLogData($expected, $event);
899         $this->assertEventContextNotUsed($event);
900     }
902     /**
903      * Test the statement_accepted event.
904      */
905     public function test_statement_accepted() {
906         // We want to be a student so we can submit assignments.
907         $this->setUser($this->students[0]);
909         // We do not want to send any messages to the student during the PHPUNIT test.
910         set_config('submissionreceipts', false, 'assign');
912         $assign = $this->create_instance();
914         // Create the data we want to pass to the submit_for_grading function.
915         $data = new stdClass();
916         $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
917             to these terms?';
919         // Trigger and capture the event.
920         $sink = $this->redirectEvents();
921         $assign->submit_for_grading($data, array());
922         $events = $sink->get_events();
923         $event = reset($events);
925         // Check that the event contains the expected values.
926         $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
927         $this->assertEquals($assign->get_context(), $event->get_context());
928         $expected = array(
929             $assign->get_course()->id,
930             'assign',
931             'submission statement accepted',
932             'view.php?id=' . $assign->get_course_module()->id,
933             get_string('submissionstatementacceptedlog',
934                 'mod_assign',
935                 fullname($this->students[0])),
936             $assign->get_course_module()->id
937         );
938         $this->assertEventLegacyLogData($expected, $event);
939         $this->assertEventContextNotUsed($event);
941         // Enable the online text submission plugin.
942         $submissionplugins = $assign->get_submission_plugins();
943         foreach ($submissionplugins as $plugin) {
944             if ($plugin->get_type() === 'onlinetext') {
945                 $plugin->enable();
946                 break;
947             }
948         }
950         // Create the data we want to pass to the save_submission function.
951         $data = new stdClass();
952         $data->onlinetext_editor = array(
953             'text' => 'Online text',
954             'format' => FORMAT_HTML,
955             'itemid' => file_get_unused_draft_itemid()
956         );
957         $data->submissionstatement = 'We are the Borg. You will be assimilated. Resistance is futile. - do you agree
958             to these terms?';
960         // Trigger and capture the event.
961         $sink = $this->redirectEvents();
962         $assign->save_submission($data, $notices);
963         $events = $sink->get_events();
964         $event = $events[2];
966         // Check that the event contains the expected values.
967         $this->assertInstanceOf('\mod_assign\event\statement_accepted', $event);
968         $this->assertEquals($assign->get_context(), $event->get_context());
969         $this->assertEventLegacyLogData($expected, $event);
970         $this->assertEventContextNotUsed($event);
971     }
973     /**
974      * Test the batch_set_workflow_state_viewed event.
975      */
976     public function test_batch_set_workflow_state_viewed() {
977         $assign = $this->create_instance();
979         // Trigger and capture the event.
980         $sink = $this->redirectEvents();
981         $assign->testable_view_batch_set_workflow_state($this->students[0]->id);
982         $events = $sink->get_events();
983         $event = reset($events);
985         // Check that the event contains the expected values.
986         $this->assertInstanceOf('\mod_assign\event\batch_set_workflow_state_viewed', $event);
987         $this->assertEquals($assign->get_context(), $event->get_context());
988         $expected = array(
989             $assign->get_course()->id,
990             'assign',
991             'view batch set marking workflow state',
992             'view.php?id=' . $assign->get_course_module()->id,
993             get_string('viewbatchsetmarkingworkflowstate', 'assign'),
994             $assign->get_course_module()->id
995         );
996         $this->assertEventLegacyLogData($expected, $event);
997         $this->assertEventContextNotUsed($event);
998     }
1000     /**
1001      * Test the batch_set_marker_allocation_viewed event.
1002      */
1003     public function test_batch_set_marker_allocation_viewed() {
1004         $assign = $this->create_instance();
1006         // Trigger and capture the event.
1007         $sink = $this->redirectEvents();
1008         $assign->testable_view_batch_markingallocation($this->students[0]->id);
1009         $events = $sink->get_events();
1010         $event = reset($events);
1012         // Check that the event contains the expected values.
1013         $this->assertInstanceOf('\mod_assign\event\batch_set_marker_allocation_viewed', $event);
1014         $this->assertEquals($assign->get_context(), $event->get_context());
1015         $expected = array(
1016             $assign->get_course()->id,
1017             'assign',
1018             'view batch set marker allocation',
1019             'view.php?id=' . $assign->get_course_module()->id,
1020             get_string('viewbatchmarkingallocation', 'assign'),
1021             $assign->get_course_module()->id
1022         );
1023         $this->assertEventLegacyLogData($expected, $event);
1024         $this->assertEventContextNotUsed($event);
1025     }