2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Unit tests for (some of) mod/assign/locallib.php.
22 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
30 require_once($CFG->dirroot . '/mod/assign/locallib.php');
31 require_once($CFG->dirroot . '/mod/assign/upgradelib.php');
32 require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
35 * Unit tests for (some of) mod/assign/locallib.php.
37 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 class mod_assign_locallib_testcase extends mod_assign_base_testcase {
42 public function test_return_links() {
44 $this->setUser($this->editingteachers[0]);
45 $returnaction = 'RETURNACTION';
46 $returnparams = array('param'=>'1');
47 $assign = $this->create_instance();
48 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
49 $assign->register_return_link($returnaction, $returnparams);
50 $this->assertEquals($returnaction, $assign->get_return_action());
51 $this->assertEquals($returnparams, $assign->get_return_params());
54 public function test_get_feedback_plugins() {
55 $this->setUser($this->editingteachers[0]);
56 $assign = $this->create_instance();
57 $installedplugins = array_keys(core_component::get_plugin_list('assignfeedback'));
59 foreach ($assign->get_feedback_plugins() as $plugin) {
60 $this->assertContains($plugin->get_type(), $installedplugins, 'Feedback plugin not in list of installed plugins');
64 public function test_get_submission_plugins() {
65 $this->setUser($this->editingteachers[0]);
66 $assign = $this->create_instance();
67 $installedplugins = array_keys(core_component::get_plugin_list('assignsubmission'));
69 foreach ($assign->get_submission_plugins() as $plugin) {
70 $this->assertContains($plugin->get_type(), $installedplugins, 'Submission plugin not in list of installed plugins');
74 public function test_is_blind_marking() {
75 $this->setUser($this->editingteachers[0]);
76 $assign = $this->create_instance(array('blindmarking'=>1));
77 $this->assertEquals(true, $assign->is_blind_marking());
79 // Test cannot see student names.
80 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
81 $output = $assign->get_renderer()->render($gradingtable);
82 $this->assertEquals(true, strpos($output, get_string('hiddenuser', 'assign')));
84 // Test students cannot reveal identities.
85 $nopermission = false;
86 $this->students[0]->ignoresesskey = true;
87 $this->setUser($this->students[0]);
88 $this->setExpectedException('required_capability_exception');
89 $assign->reveal_identities();
90 $this->students[0]->ignoresesskey = false;
92 // Test teachers cannot reveal identities.
93 $nopermission = false;
94 $this->teachers[0]->ignoresesskey = true;
95 $this->setUser($this->teachers[0]);
96 $this->setExpectedException('required_capability_exception');
97 $assign->reveal_identities();
98 $this->teachers[0]->ignoresesskey = false;
100 // Test sesskey is required.
101 $this->setUser($this->editingteachers[0]);
102 $this->setExpectedException('moodle_exception');
103 $assign->reveal_identities();
105 // Test editingteacher can reveal identities if sesskey is ignored.
106 $this->editingteachers[0]->ignoresesskey = true;
107 $this->setUser($this->editingteachers[0]);
108 $assign->reveal_identities();
109 $this->assertEquals(false, $assign->is_blind_marking());
110 $this->editingteachers[0]->ignoresesskey = false;
112 // Test student names are visible.
113 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
114 $output = $assign->get_renderer()->render($gradingtable);
115 $this->assertEquals(false, strpos($output, get_string('hiddenuser', 'assign')));
117 // Set this back to default.
118 $this->editingteachers[0]->ignoresesskey = false;
121 public function test_show_intro() {
122 // Test whether we are showing the intro at the correct times.
123 $this->setUser($this->editingteachers[0]);
124 $assign = $this->create_instance(array('alwaysshowdescription'=>1));
126 $this->assertEquals(true, $assign->testable_show_intro());
128 $tomorrow = time() + (24*60*60);
130 $assign = $this->create_instance(array('alwaysshowdescription'=>0,
131 'allowsubmissionsfromdate'=>$tomorrow));
132 $this->assertEquals(false, $assign->testable_show_intro());
133 $yesterday = time() - (24*60*60);
134 $assign = $this->create_instance(array('alwaysshowdescription'=>0,
135 'allowsubmissionsfromdate'=>$yesterday));
136 $this->assertEquals(true, $assign->testable_show_intro());
139 public function test_has_submissions_or_grades() {
140 $this->setUser($this->editingteachers[0]);
141 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
143 $instance = $assign->get_instance();
145 // Should start empty.
146 $this->assertEquals(false, $assign->has_submissions_or_grades());
148 // Simulate a submission.
149 $this->setUser($this->students[0]);
150 $submission = $assign->get_user_submission($this->students[0]->id, true);
151 $data = new stdClass();
152 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
153 'text'=>'Submission text',
154 'format'=>FORMAT_MOODLE);
155 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
156 $plugin->save($submission, $data);
159 $this->assertEquals(true, $assign->has_submissions_or_grades());
160 // Set this back to default.
161 $this->students[0]->ignoresesskey = false;
164 public function test_delete_grades() {
165 $this->setUser($this->editingteachers[0]);
166 $assign = $this->create_instance();
168 // Simulate adding a grade.
169 $this->setUser($this->teachers[0]);
170 $data = new stdClass();
171 $data->grade = '50.0';
172 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
174 // Now see if the data is in the gradebook.
175 $gradinginfo = grade_get_grades($this->course->id,
178 $assign->get_instance()->id);
180 $this->assertNotEquals(0, count($gradinginfo->items));
182 $assign->testable_delete_grades();
183 $gradinginfo = grade_get_grades($this->course->id,
186 $assign->get_instance()->id);
188 $this->assertEquals(0, count($gradinginfo->items));
191 public function test_delete_instance() {
192 $this->setUser($this->editingteachers[0]);
193 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
195 // Simulate adding a grade.
196 $this->setUser($this->teachers[0]);
197 $data = new stdClass();
198 $data->grade = '50.0';
199 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
201 // Simulate a submission.
202 $this->setUser($this->students[0]);
203 $submission = $assign->get_user_submission($this->students[0]->id, true);
204 $data = new stdClass();
205 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
206 'text'=>'Submission text',
207 'format'=>FORMAT_MOODLE);
208 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
209 $plugin->save($submission, $data);
211 // Now try and delete.
212 $this->assertEquals(true, $assign->delete_instance());
215 public function test_reset_userdata() {
219 $this->setUser($this->editingteachers[0]);
220 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1,
223 // Simulate adding a grade.
224 $this->setUser($this->teachers[0]);
225 $data = new stdClass();
226 $data->grade = '50.0';
227 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
229 // Simulate a submission.
230 $this->setUser($this->students[0]);
231 $submission = $assign->get_user_submission($this->students[0]->id, true);
232 $data = new stdClass();
233 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
234 'text'=>'Submission text',
235 'format'=>FORMAT_MOODLE);
236 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
237 $plugin->save($submission, $data);
239 $this->assertEquals(true, $assign->has_submissions_or_grades());
240 // Now try and reset.
241 $data = new stdClass();
242 $data->reset_assign_submissions = 1;
243 $data->reset_gradebook_grades = 1;
244 $data->courseid = $this->course->id;
245 $data->timeshift = 24*60*60;
246 $this->setUser($this->editingteachers[0]);
247 $assign->reset_userdata($data);
248 $this->assertEquals(false, $assign->has_submissions_or_grades());
250 // Reload the instance data.
251 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
252 $this->assertEquals($now + 24*60*60, $instance->duedate);
255 public function test_plugin_settings() {
259 $this->setUser($this->editingteachers[0]);
260 $assign = $this->create_instance(array('assignsubmission_file_enabled'=>1,
261 'assignsubmission_file_maxfiles'=>12,
262 'assignsubmission_file_maxsizebytes'=>10));
264 $plugin = $assign->get_submission_plugin_by_type('file');
265 $this->assertEquals('12', $plugin->get_config('maxfilesubmissions'));
268 public function test_update_calendar() {
272 $this->setUser($this->editingteachers[0]);
273 $assign = $this->create_instance(array('duedate'=>$now));
275 // See if there is an event in the calendar.
276 $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id);
277 $id = $DB->get_field('event', 'id', $params);
279 $this->assertEquals(false, empty($id));
282 public function test_update_instance() {
285 $this->setUser($this->editingteachers[0]);
286 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
289 $instance = $assign->get_instance();
290 $instance->duedate = $now;
291 $instance->instance = $instance->id;
292 $instance->assignsubmission_onlinetext_enabled = 1;
294 $assign->update_instance($instance);
296 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
297 $this->assertEquals($now, $instance->duedate);
300 public function test_cannot_submit_empty() {
303 $this->setUser($this->editingteachers[0]);
304 $assign = $this->create_instance(array('submissiondrafts'=>1));
306 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
308 // Test you cannot see the submit button for an offline assignment regardless.
309 $this->setUser($this->students[0]);
310 $output = $assign->view_student_summary($this->students[0], true);
311 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Can submit empty offline assignment');
313 // Test you cannot see the submit button for an online text assignment with no submission.
314 $this->setUser($this->editingteachers[0]);
315 $instance = $assign->get_instance();
316 $instance->instance = $instance->id;
317 $instance->assignsubmission_onlinetext_enabled = 1;
319 $assign->update_instance($instance);
320 $this->setUser($this->students[0]);
321 $output = $assign->view_student_summary($this->students[0], true);
322 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Cannot submit empty onlinetext assignment');
324 // Simulate a submission.
325 $submission = $assign->get_user_submission($this->students[0]->id, true);
326 $data = new stdClass();
327 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
328 'text'=>'Submission text',
329 'format'=>FORMAT_MOODLE);
330 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
331 $plugin->save($submission, $data);
332 // Test you can see the submit button for an online text assignment with a submission.
333 $output = $assign->view_student_summary($this->students[0], true);
334 $this->assertContains(get_string('submitassignment', 'assign'), $output, 'Can submit non empty onlinetext assignment');
337 public function test_list_participants() {
338 $this->create_extra_users();
339 $this->setUser($this->editingteachers[0]);
340 $assign = $this->create_instance(array('grade'=>100));
342 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true)));
344 // Teacher with user preference set should see suspended users as well.
345 set_user_preference('grade_report_showonlyactiveenrol', false);
346 $assign = $this->create_instance(array('grade'=>100));
347 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT,
348 count($assign->list_participants(null, true)));
350 // Non-editing teacher should not see suspended users, even if user preference is set.
351 $this->setUser($this->teachers[0]);
352 set_user_preference('grade_report_showonlyactiveenrol', false);
353 $assign = $this->create_instance(array('grade'=>100));
354 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true)));
357 public function test_count_teams() {
358 $this->create_extra_users();
359 $this->setUser($this->editingteachers[0]);
360 $assign = $this->create_instance(array('teamsubmission'=>1));
362 $this->assertEquals(self::GROUP_COUNT + 1, $assign->count_teams());
365 public function test_count_submissions() {
366 $this->create_extra_users();
367 $this->setUser($this->editingteachers[0]);
368 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
370 // Simulate a submission.
371 $this->setUser($this->extrastudents[0]);
372 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
373 // Leave this one as DRAFT.
374 $data = new stdClass();
375 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
376 'text'=>'Submission text',
377 'format'=>FORMAT_MOODLE);
378 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
379 $plugin->save($submission, $data);
381 // Simulate adding a grade.
382 $this->setUser($this->teachers[0]);
383 $data = new stdClass();
384 $data->grade = '50.0';
385 $assign->testable_apply_grade_to_user($data, $this->extrastudents[0]->id, 0);
387 // Simulate a submission.
388 $this->setUser($this->extrastudents[1]);
389 $submission = $assign->get_user_submission($this->extrastudents[1]->id, true);
390 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
391 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, false);
392 $data = new stdClass();
393 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
394 'text'=>'Submission text',
395 'format'=>FORMAT_MOODLE);
396 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
397 $plugin->save($submission, $data);
399 // Simulate a submission.
400 $this->setUser($this->extrastudents[2]);
401 $submission = $assign->get_user_submission($this->extrastudents[2]->id, true);
402 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
403 $assign->testable_update_submission($submission, $this->extrastudents[2]->id, true, false);
404 $data = new stdClass();
405 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
406 'text'=>'Submission text',
407 'format'=>FORMAT_MOODLE);
408 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
409 $plugin->save($submission, $data);
411 // Simulate a submission.
412 $this->setUser($this->extrastudents[3]);
413 $submission = $assign->get_user_submission($this->extrastudents[3]->id, true);
414 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
415 $assign->testable_update_submission($submission, $this->extrastudents[3]->id, true, false);
416 $data = new stdClass();
417 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
418 'text'=>'Submission text',
419 'format'=>FORMAT_MOODLE);
420 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
421 $plugin->save($submission, $data);
423 // Simulate a submission for suspended user, this will never be counted.
424 $this->setUser($this->extrastudents[3]);
425 $submission = $assign->get_user_submission($this->extrasuspendedstudents[0]->id, true);
426 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
427 $assign->testable_update_submission($submission, $this->extrasuspendedstudents[0]->id, true, false);
428 $data = new stdClass();
429 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
430 'text'=>'Submission text',
431 'format'=>FORMAT_MOODLE);
432 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
433 $plugin->save($submission, $data);
435 // Simulate adding a grade.
436 $this->setUser($this->teachers[0]);
437 $data = new stdClass();
438 $data->grade = '50.0';
439 $assign->testable_apply_grade_to_user($data, $this->extrastudents[3]->id, 0);
440 $assign->testable_apply_grade_to_user($data, $this->extrasuspendedstudents[0]->id, 0);
442 $this->assertEquals(2, $assign->count_grades());
443 $this->assertEquals(4, $assign->count_submissions());
444 $this->assertEquals(2, $assign->count_submissions_need_grading());
445 $this->assertEquals(3, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED));
446 $this->assertEquals(1, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT));
449 public function test_get_grading_userid_list() {
450 $this->create_extra_users();
451 $this->setUser($this->editingteachers[0]);
452 $assign = $this->create_instance();
454 $users = $assign->testable_get_grading_userid_list();
455 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($users));
457 $this->setUser($this->editingteachers[0]);
458 set_user_preference('grade_report_showonlyactiveenrol', false);
459 $assign = $this->create_instance();
461 $users = $assign->testable_get_grading_userid_list();
462 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT, count($users));
465 public function test_cron() {
466 // First run cron so there are no messages waiting to be sent (from other tests).
470 // Now create an assignment and add some feedback.
471 $this->setUser($this->editingteachers[0]);
472 $assign = $this->create_instance();
474 // Simulate adding a grade.
475 $this->setUser($this->teachers[0]);
476 $data = new stdClass();
477 $data->grade = '50.0';
478 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
480 // Now run cron and see that one message was sent.
481 $this->preventResetByRollback();
482 $sink = $this->redirectMessages();
484 $this->expectOutputRegex('/Done processing 1 assignment submissions/');
487 $messages = $sink->get_messages();
488 $this->assertEquals(1, count($messages));
489 $this->assertEquals(1, $messages[0]->notification);
490 $this->assertEquals($assign->get_instance()->name, $messages[0]->contexturlname);
493 public function test_is_graded() {
494 $this->setUser($this->editingteachers[0]);
495 $assign = $this->create_instance();
497 // Simulate adding a grade.
498 $this->setUser($this->teachers[0]);
499 $data = new stdClass();
500 $data->grade = '50.0';
501 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
503 $this->assertEquals(true, $assign->testable_is_graded($this->students[0]->id));
504 $this->assertEquals(false, $assign->testable_is_graded($this->students[1]->id));
507 public function test_can_view_submission() {
508 $this->create_extra_users();
509 $this->setUser($this->editingteachers[0]);
510 $assign = $this->create_instance();
512 $this->setUser($this->students[0]);
513 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
514 $this->assertEquals(false, $assign->can_view_submission($this->students[1]->id));
515 $this->assertEquals(false, $assign->can_view_submission($this->teachers[0]->id));
516 $this->setUser($this->teachers[0]);
517 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
518 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
519 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
520 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
521 $this->setUser($this->editingteachers[0]);
522 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
523 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
524 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
525 $this->assertEquals(true, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
529 public function test_update_submission() {
530 $this->create_extra_users();
531 $this->setUser($this->editingteachers[0]);
532 $assign = $this->create_instance();
534 $this->setUser($this->extrastudents[0]);
536 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
537 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
539 $this->setUser($this->teachers[0]);
540 // Verify the gradebook update.
541 $gradinginfo = grade_get_grades($this->course->id,
544 $assign->get_instance()->id,
545 $this->extrastudents[0]->id);
547 $this->assertEquals($this->extrastudents[0]->id,
548 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
550 // Now verify group assignments.
551 $this->setUser($this->editingteachers[0]);
552 $assign = $this->create_instance(array('teamsubmission'=>1));
554 $this->setUser($this->extrastudents[0]);
556 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
557 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
559 // Check that at least 2 active members and 1 suspended member of the submission group had their submission updated.
561 $this->setUser($this->editingteachers[0]);
562 $gradinginfo = grade_get_grades($this->course->id,
565 $assign->get_instance()->id,
566 $this->extrastudents[0]->id);
568 $this->assertEquals($this->extrastudents[0]->id,
569 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
571 $gradinginfo = grade_get_grades($this->course->id,
574 $assign->get_instance()->id,
575 $this->extrastudents[self::GROUP_COUNT]->id);
577 $this->assertEquals($this->extrastudents[self::GROUP_COUNT]->id,
578 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT]->id]->usermodified);
580 $gradinginfo = grade_get_grades($this->course->id,
583 $assign->get_instance()->id,
584 $this->extrasuspendedstudents[0]->id);
585 $this->assertEquals($this->extrasuspendedstudents[0]->id,
586 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[0]->id]->usermodified);
588 // Check the same with non-editing teacher and make sure submission is not updated for suspended user.
589 $this->setUser($this->editingteachers[0]);
590 $assign = $this->create_instance(array('teamsubmission'=>1));
592 $this->setUser($this->extrastudents[1]);
594 $submission = $assign->get_group_submission($this->extrastudents[1]->id, 0, true);
595 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, true);
597 $this->setUser($this->teachers[0]);
598 $gradinginfo = grade_get_grades($this->course->id,
601 $assign->get_instance()->id,
602 $this->extrastudents[1]->id);
604 $this->assertEquals($this->extrastudents[1]->id,
605 $gradinginfo->items[0]->grades[$this->extrastudents[1]->id]->usermodified);
607 $gradinginfo = grade_get_grades($this->course->id,
610 $assign->get_instance()->id,
611 $this->extrastudents[self::GROUP_COUNT+1]->id);
613 $this->assertEquals($this->extrastudents[self::GROUP_COUNT+1]->id,
614 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT+1]->id]->usermodified);
616 $gradinginfo = grade_get_grades($this->course->id,
619 $assign->get_instance()->id,
620 $this->extrasuspendedstudents[1]->id);
621 $this->assertEquals($this->extrasuspendedstudents[1]->id,
622 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[1]->id]->usermodified);
624 // Now verify blind marking.
625 $this->setUser($this->editingteachers[0]);
626 $assign = $this->create_instance(array('blindmarking'=>1));
628 $this->setUser($this->extrastudents[0]);
630 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
631 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
633 $this->setUser($this->editingteachers[0]);
634 $gradinginfo = grade_get_grades($this->course->id,
637 $assign->get_instance()->id,
638 $this->extrastudents[0]->id);
640 $this->assertEquals(null, $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->datesubmitted);
643 public function test_submissions_open() {
644 $this->setUser($this->editingteachers[0]);
647 $tomorrow = $now + 24*60*60;
648 $oneweek = $now + 7*24*60*60;
649 $yesterday = $now - 24*60*60;
651 $assign = $this->create_instance();
652 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
654 $assign = $this->create_instance(array('duedate'=>$tomorrow));
655 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
657 $assign = $this->create_instance(array('duedate'=>$yesterday));
658 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
660 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$tomorrow));
661 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
663 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$yesterday));
664 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
666 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
667 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
669 $assign = $this->create_instance(array('submissiondrafts'=>1));
670 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
672 $this->setUser($this->students[0]);
674 $submission = $assign->get_user_submission($this->students[0]->id, true);
675 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
676 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
677 $this->setUser($this->editingteachers[0]);
678 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
681 public function test_get_graders() {
682 $this->create_extra_users();
683 $this->setUser($this->editingteachers[0]);
684 $assign = $this->create_instance();
686 $this->assertCount(self::DEFAULT_TEACHER_COUNT +
687 self::DEFAULT_EDITING_TEACHER_COUNT +
688 self::EXTRA_TEACHER_COUNT +
689 self::EXTRA_EDITING_TEACHER_COUNT,
690 $assign->testable_get_graders($this->students[0]->id));
692 $assign = $this->create_instance();
693 // Force create an assignment with SEPARATEGROUPS.
694 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
695 $params = array('course'=>$this->course->id);
696 $instance = $generator->create_instance($params);
697 $cm = get_coursemodule_from_instance('assign', $instance->id);
698 set_coursemodule_groupmode($cm->id, SEPARATEGROUPS);
699 $cm->groupmode = SEPARATEGROUPS;
700 $context = context_module::instance($cm->id);
701 $assign = new testable_assign($context, $cm, $this->course);
703 $this->setUser($this->students[1]);
704 $this->assertCount(4, $assign->testable_get_graders($this->students[0]->id));
707 public function test_get_uniqueid_for_user() {
708 $this->setUser($this->editingteachers[0]);
709 $assign = $this->create_instance();
711 foreach ($this->students as $student) {
712 $uniqueid = $assign->get_uniqueid_for_user($student->id);
713 $this->assertEquals($student->id, $assign->get_user_id_for_uniqueid($uniqueid));
717 public function test_show_student_summary() {
720 $this->setUser($this->editingteachers[0]);
721 $assign = $this->create_instance();
722 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
724 // No feedback should be available because this student has not been graded.
725 $this->setUser($this->students[0]);
726 $output = $assign->view_student_summary($this->students[0], true);
727 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if there is no grade');
728 // Simulate adding a grade.
729 $this->setUser($this->teachers[0]);
730 $data = new stdClass();
731 $data->grade = '50.0';
732 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
734 // Now we should see the feedback.
735 $this->setUser($this->students[0]);
736 $output = $assign->view_student_summary($this->students[0], true);
737 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade');
739 // Now hide the grade in gradebook.
740 $this->setUser($this->teachers[0]);
741 require_once($CFG->libdir.'/gradelib.php');
742 $gradeitem = new grade_item(array(
744 'itemmodule' => 'assign',
745 'iteminstance' => $assign->get_instance()->id,
746 'courseid' => $this->course->id));
748 $gradeitem->set_hidden(1, false);
750 // No feedback should be available because the grade is hidden.
751 $this->setUser($this->students[0]);
752 $output = $assign->view_student_summary($this->students[0], true);
753 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
755 // Do the same but add feedback.
756 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
758 $this->setUser($this->teachers[0]);
759 $grade = $assign->get_user_grade($this->students[0]->id, true);
760 $data = new stdClass();
761 $data->assignfeedbackcomments_editor = array('text'=>'Tomato sauce',
762 'format'=>FORMAT_MOODLE);
763 $plugin = $assign->get_feedback_plugin_by_type('comments');
764 $plugin->save($grade, $data);
766 // Should have feedback but no grade.
767 $this->setUser($this->students[0]);
768 $output = $assign->view_student_summary($this->students[0], true);
769 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback even if there is no grade');
770 $this->assertEquals(false, strpos($output, 'Grade'), 'Do not show grade when there is no grade.');
771 $this->assertEquals(false, strpos($output, 'Graded on'), 'Do not show graded date when there is no grade.');
773 // Now hide the grade in gradebook.
774 $this->setUser($this->teachers[0]);
775 $gradeitem = new grade_item(array(
777 'itemmodule' => 'assign',
778 'iteminstance' => $assign->get_instance()->id,
779 'courseid' => $this->course->id));
781 $gradeitem->set_hidden(1, false);
783 // No feedback should be available because the grade is hidden.
784 $this->setUser($this->students[0]);
785 $output = $assign->view_student_summary($this->students[0], true);
786 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
789 public function test_attempt_reopen_method_manual() {
792 $this->setUser($this->editingteachers[0]);
793 $assign = $this->create_instance(array('attemptreopenmethod'=>ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
795 'submissiondrafts'=>1,
796 'assignsubmission_onlinetext_enabled'=>1));
797 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
799 // Student should be able to see an add submission button.
800 $this->setUser($this->students[0]);
801 $output = $assign->view_student_summary($this->students[0], true);
802 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
806 $submission = $assign->get_user_submission($this->students[0]->id, true);
807 $data = new stdClass();
808 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
809 'text'=>'Submission text',
810 'format'=>FORMAT_MOODLE);
811 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
812 $plugin->save($submission, $data);
814 // And now submit it for marking.
815 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
816 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
818 // Verify the student cannot make changes to the submission.
819 $output = $assign->view_student_summary($this->students[0], true);
820 $this->assertEquals(false, strpos($output, get_string('addsubmission', 'assign')));
822 // Mark the submission.
823 $this->setUser($this->teachers[0]);
824 $data = new stdClass();
825 $data->grade = '50.0';
826 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
828 // Check the student can see the grade.
829 $this->setUser($this->students[0]);
830 $output = $assign->view_student_summary($this->students[0], true);
831 $this->assertNotEquals(false, strpos($output, '50.0'));
833 // Allow the student another attempt.
834 $this->teachers[0]->ignoresesskey = true;
835 $this->setUser($this->teachers[0]);
836 $result = $assign->testable_process_add_attempt($this->students[0]->id);
837 $this->assertEquals(true, $result);
839 // Check that the previous attempt is now in the submission history table.
840 $this->setUser($this->students[0]);
841 $output = $assign->view_student_summary($this->students[0], true);
842 // Need a better check.
843 $this->assertNotEquals(false, strpos($output, 'Submission text'), 'Contains: Submission text');
845 // Check that the student now has a button for Add a new attempt".
846 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
847 // Check that the student now does not have a button for Submit.
848 $this->assertEquals(false, strpos($output, get_string('submitassignment', 'assign')));
850 // Check that the student now has a submission history.
851 $this->assertNotEquals(false, strpos($output, get_string('attempthistory', 'assign')));
853 $this->setUser($this->teachers[0]);
854 // Check that the grading table loads correctly and contains this user.
855 // This is also testing that we do not get duplicate rows in the grading table.
856 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
857 $output = $assign->get_renderer()->render($gradingtable);
858 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
860 // Should be 1 not 2.
861 $this->assertEquals(1, $assign->count_submissions());
862 $this->assertEquals(1, $assign->count_submissions_with_status('reopened'));
863 $this->assertEquals(0, $assign->count_submissions_need_grading());
864 $this->assertEquals(1, $assign->count_grades());
866 // Change max attempts to unlimited.
867 $formdata = clone($assign->get_instance());
868 $formdata->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS;
869 $formdata->instance = $formdata->id;
870 $assign->update_instance($formdata);
872 // Check we can repopen still.
873 $result = $assign->testable_process_add_attempt($this->students[0]->id);
874 $this->assertEquals(true, $result);
876 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id);
877 $this->assertEquals(50, (int)$grades[$this->students[0]->id]->rawgrade);
881 public function test_markingworkflow() {
884 $this->setUser($this->editingteachers[0]);
885 $assign = $this->create_instance(array('markingworkflow'=>1));
886 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
888 // Mark the submission and set to notmarked.
889 $this->setUser($this->teachers[0]);
890 $data = new stdClass();
891 $data->grade = '50.0';
892 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED;
893 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
895 // Check the student can't see the grade.
896 $this->setUser($this->students[0]);
897 $output = $assign->view_student_summary($this->students[0], true);
898 $this->assertEquals(false, strpos($output, '50.0'));
900 // Mark the submission and set to inmarking.
901 $this->setUser($this->teachers[0]);
902 $data = new stdClass();
903 $data->grade = '50.0';
904 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INMARKING;
905 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
907 // Check the student can't see the grade.
908 $this->setUser($this->students[0]);
909 $output = $assign->view_student_summary($this->students[0], true);
910 $this->assertEquals(false, strpos($output, '50.0'));
912 // Mark the submission and set to readyforreview.
913 $this->setUser($this->teachers[0]);
914 $data = new stdClass();
915 $data->grade = '50.0';
916 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW;
917 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
919 // Check the student can't see the grade.
920 $this->setUser($this->students[0]);
921 $output = $assign->view_student_summary($this->students[0], true);
922 $this->assertEquals(false, strpos($output, '50.0'));
924 // Mark the submission and set to inreview.
925 $this->setUser($this->teachers[0]);
926 $data = new stdClass();
927 $data->grade = '50.0';
928 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW;
929 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
931 // Check the student can't see the grade.
932 $this->setUser($this->students[0]);
933 $output = $assign->view_student_summary($this->students[0], true);
934 $this->assertEquals(false, strpos($output, '50.0'));
936 // Mark the submission and set to readyforrelease.
937 $this->setUser($this->teachers[0]);
938 $data = new stdClass();
939 $data->grade = '50.0';
940 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE;
941 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
943 // Check the student can't see the grade.
944 $this->setUser($this->students[0]);
945 $output = $assign->view_student_summary($this->students[0], true);
946 $this->assertEquals(false, strpos($output, '50.0'));
948 // Mark the submission and set to released.
949 $this->setUser($this->teachers[0]);
950 $data = new stdClass();
951 $data->grade = '50.0';
952 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_RELEASED;
953 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
955 // Check the student can see the grade.
956 $this->setUser($this->students[0]);
957 $output = $assign->view_student_summary($this->students[0], true);
958 $this->assertNotEquals(false, strpos($output, '50.0'));
961 public function test_markerallocation() {
964 $this->setUser($this->editingteachers[0]);
965 $assign = $this->create_instance(array('markingworkflow'=>1, 'markingallocation'=>1));
966 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
968 // Allocate marker to submission.
969 $data = new stdClass();
970 $data->allocatedmarker = $this->teachers[0]->id;
971 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
973 // Check the allocated marker can view the submission.
974 $this->setUser($this->teachers[0]);
975 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
976 $output = $assign->get_renderer()->render($gradingtable);
977 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
979 // Check that other teachers can't view this submission.
980 $this->setUser($this->teachers[1]);
981 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
982 $output = $assign->get_renderer()->render($gradingtable);
983 $this->assertNotEquals(true, strpos($output, $this->students[0]->lastname));
986 public function test_extension_granted_event() {
987 $this->setUser($this->editingteachers[0]);
989 $tomorrow = time() + 24*60*60;
990 $yesterday = time() - 24*60*60;
992 $assign = $this->create_instance(array('duedate' => $yesterday, 'cutoffdate' => $yesterday));
993 $sink = $this->redirectEvents();
995 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
997 $events = $sink->get_events();
998 $this->assertCount(1, $events);
999 $event = reset($events);
1000 $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
1001 $this->assertEquals($assign->get_context(), $event->get_context());
1002 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1003 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1005 $assign->get_course()->id,
1008 'view.php?id=' . $assign->get_course_module()->id,
1009 $this->students[0]->id,
1010 $assign->get_course_module()->id,
1011 $this->editingteachers[0]->id
1013 $this->assertEventLegacyLogData($expected, $event);
1017 public function test_submission_locked_event() {
1018 $this->editingteachers[0]->ignoresesskey = true;
1019 $this->setUser($this->editingteachers[0]);
1021 $assign = $this->create_instance();
1022 $sink = $this->redirectEvents();
1024 $assign->lock_submission($this->students[0]->id);
1026 $events = $sink->get_events();
1027 $this->assertCount(1, $events);
1028 $event = reset($events);
1029 $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
1030 $this->assertEquals($assign->get_context(), $event->get_context());
1031 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1032 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1034 $assign->get_course()->id,
1037 'view.php?id=' . $assign->get_course_module()->id,
1038 get_string('locksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
1039 'fullname' => fullname($this->students[0]))),
1040 $assign->get_course_module()->id,
1041 $this->editingteachers[0]->id
1043 $this->assertEventLegacyLogData($expected, $event);
1046 // Revert to defaults.
1047 $this->editingteachers[0]->ignoresesskey = false;
1050 public function test_identities_revealed_event() {
1051 $this->editingteachers[0]->ignoresesskey = true;
1052 $this->setUser($this->editingteachers[0]);
1054 $assign = $this->create_instance(array('blindmarking'=>1));
1055 $sink = $this->redirectEvents();
1057 $assign->reveal_identities();
1059 $events = $sink->get_events();
1060 $this->assertCount(1, $events);
1061 $event = reset($events);
1062 $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
1063 $this->assertEquals($assign->get_context(), $event->get_context());
1064 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1066 $assign->get_course()->id,
1068 'reveal identities',
1069 'view.php?id=' . $assign->get_course_module()->id,
1070 get_string('revealidentities', 'assign'),
1071 $assign->get_course_module()->id,
1072 $this->editingteachers[0]->id
1074 $this->assertEventLegacyLogData($expected, $event);
1077 // Revert to defaults.
1078 $this->editingteachers[0]->ignoresesskey = false;
1081 public function test_submission_status_updated_event() {
1082 $this->editingteachers[0]->ignoresesskey = true;
1083 $this->setUser($this->editingteachers[0]);
1085 $assign = $this->create_instance();
1086 $submission = $assign->get_user_submission($this->students[0]->id, true);
1087 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1088 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1090 $sink = $this->redirectEvents();
1091 $assign->revert_to_draft($this->students[0]->id);
1093 $events = $sink->get_events();
1094 $this->assertCount(1, $events);
1095 $event = reset($events);
1096 $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
1097 $this->assertEquals($assign->get_context(), $event->get_context());
1098 $this->assertEquals($submission->id, $event->objectid);
1099 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1100 $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
1102 $assign->get_course()->id,
1104 'revert submission to draft',
1105 'view.php?id=' . $assign->get_course_module()->id,
1106 get_string('reverttodraftforstudent', 'assign', array('id' => $this->students[0]->id,
1107 'fullname' => fullname($this->students[0]))),
1108 $assign->get_course_module()->id,
1109 $this->editingteachers[0]->id
1111 $this->assertEventLegacyLogData($expected, $event);
1114 // Revert to defaults.
1115 $this->editingteachers[0]->ignoresesskey = false;
1118 public function test_marker_updated_event() {
1119 $this->editingteachers[0]->ignoresesskey = true;
1120 $this->setUser($this->editingteachers[0]);
1122 $assign = $this->create_instance();
1124 $sink = $this->redirectEvents();
1125 $assign->testable_process_set_batch_marking_allocation($this->students[0]->id, $this->teachers[0]->id);
1127 $events = $sink->get_events();
1128 $this->assertCount(1, $events);
1129 $event = reset($events);
1130 $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
1131 $this->assertEquals($assign->get_context(), $event->get_context());
1132 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1133 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1134 $this->assertEquals($this->editingteachers[0]->id, $event->userid);
1135 $this->assertEquals($this->teachers[0]->id, $event->other['markerid']);
1137 $assign->get_course()->id,
1139 'set marking allocation',
1140 'view.php?id=' . $assign->get_course_module()->id,
1141 get_string('setmarkerallocationforlog', 'assign', array('id' => $this->students[0]->id,
1142 'fullname' => fullname($this->students[0]), 'marker' => fullname($this->teachers[0]))),
1143 $assign->get_course_module()->id,
1144 $this->editingteachers[0]->id
1146 $this->assertEventLegacyLogData($expected, $event);
1149 // Revert to defaults.
1150 $this->editingteachers[0]->ignoresesskey = false;
1153 public function test_workflow_state_updated_event() {
1154 $this->editingteachers[0]->ignoresesskey = true;
1155 $this->setUser($this->editingteachers[0]);
1157 $assign = $this->create_instance();
1159 $sink = $this->redirectEvents();
1160 $assign->testable_process_set_batch_marking_workflow_state($this->students[0]->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
1162 $events = $sink->get_events();
1163 $this->assertCount(1, $events);
1164 $event = reset($events);
1165 $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
1166 $this->assertEquals($assign->get_context(), $event->get_context());
1167 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1168 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1169 $this->assertEquals($this->editingteachers[0]->id, $event->userid);
1170 $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
1172 $assign->get_course()->id,
1174 'set marking workflow state',
1175 'view.php?id=' . $assign->get_course_module()->id,
1176 get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
1177 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW)),
1178 $assign->get_course_module()->id,
1179 $this->editingteachers[0]->id
1181 $this->assertEventLegacyLogData($expected, $event);
1184 // Revert to defaults.
1185 $this->editingteachers[0]->ignoresesskey = false;
1188 public function test_submission_duplicated_event() {
1189 $this->setUser($this->students[0]);
1191 $assign = $this->create_instance();
1192 $submission1 = $assign->get_user_submission($this->students[0]->id, true, 0);
1193 $submission2 = $assign->get_user_submission($this->students[0]->id, true, 1);
1194 $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
1195 $assign->testable_update_submission($submission2, $this->students[0]->id, time(), $assign->get_instance()->teamsubmission);
1197 $sink = $this->redirectEvents();
1199 $assign->copy_previous_attempt($notices);
1201 $events = $sink->get_events();
1202 $this->assertCount(1, $events);
1203 $event = reset($events);
1204 $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
1205 $this->assertEquals($assign->get_context(), $event->get_context());
1206 $this->assertEquals($submission2->id, $event->objectid);
1207 $this->assertEquals($this->students[0]->id, $event->userid);
1208 $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
1210 $assign->get_course()->id,
1213 'view.php?id=' . $assign->get_course_module()->id,
1214 $assign->testable_format_submission_for_log($submission2),
1215 $assign->get_course_module()->id,
1216 $this->students[0]->id
1218 $this->assertEventLegacyLogData($expected, $event);
1222 public function test_submission_unlocked_event() {
1223 $this->editingteachers[0]->ignoresesskey = true;
1224 $this->setUser($this->editingteachers[0]);
1226 $assign = $this->create_instance();
1227 $sink = $this->redirectEvents();
1229 $assign->unlock_submission($this->students[0]->id);
1231 $events = $sink->get_events();
1232 $this->assertCount(1, $events);
1233 $event = reset($events);
1234 $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
1235 $this->assertEquals($assign->get_context(), $event->get_context());
1236 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1237 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1239 $assign->get_course()->id,
1241 'unlock submission',
1242 'view.php?id=' . $assign->get_course_module()->id,
1243 get_string('unlocksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
1244 'fullname' => fullname($this->students[0]))),
1245 $assign->get_course_module()->id,
1246 $this->editingteachers[0]->id
1248 $this->assertEventLegacyLogData($expected, $event);
1251 // Revert to defaults.
1252 $this->editingteachers[0]->ignoresesskey = false;
1255 public function test_submission_graded_event() {
1256 $this->setUser($this->editingteachers[0]);
1257 $assign = $this->create_instance();
1259 // Test apply_grade_to_user.
1260 $sink = $this->redirectEvents();
1262 $data = new stdClass();
1263 $data->grade = '50.0';
1264 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1265 $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
1267 $events = $sink->get_events();
1268 $this->assertCount(1, $events);
1269 $event = reset($events);
1270 $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
1271 $this->assertEquals($assign->get_context(), $event->get_context());
1272 $this->assertEquals($grade->id, $event->objectid);
1273 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1275 $assign->get_course()->id,
1278 'view.php?id=' . $assign->get_course_module()->id,
1279 $assign->format_grade_for_log($grade),
1280 $assign->get_course_module()->id,
1281 $this->editingteachers[0]->id
1283 $this->assertEventLegacyLogData($expected, $event);
1286 // Test process_save_quick_grades.
1287 $sink = $this->redirectEvents();
1290 'grademodified_' . $this->students[0]->id => time(),
1291 'quickgrade_' . $this->students[0]->id => '60.0'
1293 $assign->testable_process_save_quick_grades($data);
1294 $grade = $assign->get_user_grade($this->students[0]->id, false);
1295 $this->assertEquals('60.0', $grade->grade);
1297 $events = $sink->get_events();
1298 $this->assertCount(1, $events);
1299 $event = reset($events);
1300 $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
1301 $this->assertEquals($assign->get_context(), $event->get_context());
1302 $this->assertEquals($grade->id, $event->objectid);
1303 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1305 $assign->get_course()->id,
1308 'view.php?id=' . $assign->get_course_module()->id,
1309 $assign->format_grade_for_log($grade),
1310 $assign->get_course_module()->id,
1311 $this->editingteachers[0]->id
1313 $this->assertEventLegacyLogData($expected, $event);
1317 public function test_disable_submit_after_cutoff_date() {
1320 $this->setUser($this->editingteachers[0]);
1322 $tomorrow = $now + 24*60*60;
1323 $lastweek = $now - 7*24*60*60;
1324 $yesterday = $now - 24*60*60;
1326 $assign = $this->create_instance(array('duedate'=>$yesterday,
1327 'cutoffdate'=>$tomorrow,
1328 'assignsubmission_onlinetext_enabled'=>1));
1329 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1331 // Student should be able to see an add submission button.
1332 $this->setUser($this->students[0]);
1333 $output = $assign->view_student_summary($this->students[0], true);
1334 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1336 // Add a submission but don't submit now.
1337 $submission = $assign->get_user_submission($this->students[0]->id, true);
1338 $data = new stdClass();
1339 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1340 'text'=>'Submission text',
1341 'format'=>FORMAT_MOODLE);
1342 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1343 $plugin->save($submission, $data);
1345 // Create another instance with cut-off and due-date already passed.
1346 $this->setUser($this->editingteachers[0]);
1348 $assign = $this->create_instance(array('duedate'=>$lastweek,
1349 'cutoffdate'=>$yesterday,
1350 'assignsubmission_onlinetext_enabled'=>1));
1352 $this->setUser($this->students[0]);
1353 $output = $assign->view_student_summary($this->students[0], true);
1354 $this->assertNotContains($output, get_string('editsubmission', 'assign'),
1355 'Should not be able to edit after cutoff date.');
1356 $this->assertNotContains($output, get_string('submitassignment', 'assign'),
1357 'Should not be able to submit after cutoff date.');