weekly release 2.6dev
[moodle.git] / mod / assign / tests / locallib_test.php
CommitLineData
47f48152
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Unit tests for (some of) mod/assign/locallib.php.
19 *
20 * @package mod_assign
21 * @category phpunit
22 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30require_once($CFG->dirroot . '/mod/assign/locallib.php');
31require_once($CFG->dirroot . '/mod/assign/upgradelib.php');
9c986ee0 32require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
47f48152
DW
33
34/**
35 * Unit tests for (some of) mod/assign/locallib.php.
36 *
37 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
9c986ee0 40class mod_assign_locallib_testcase extends mod_assign_base_testcase {
47f48152
DW
41
42 public function test_return_links() {
c2114099 43 global $PAGE;
47f48152
DW
44 $this->setUser($this->editingteachers[0]);
45 $returnaction = 'RETURNACTION';
c2114099 46 $returnparams = array('param'=>'1');
47f48152 47 $assign = $this->create_instance();
c2114099 48 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
47f48152
DW
49 $assign->register_return_link($returnaction, $returnparams);
50 $this->assertEquals($returnaction, $assign->get_return_action());
51 $this->assertEquals($returnparams, $assign->get_return_params());
52 }
53
54 public function test_get_feedback_plugins() {
55 $this->setUser($this->editingteachers[0]);
56 $assign = $this->create_instance();
bd3b3bba 57 $installedplugins = array_keys(core_component::get_plugin_list('assignfeedback'));
11527706
DW
58
59 foreach ($assign->get_feedback_plugins() as $plugin) {
60 $this->assertContains($plugin->get_type(), $installedplugins, 'Feedback plugin not in list of installed plugins');
61 }
47f48152
DW
62 }
63
64 public function test_get_submission_plugins() {
65 $this->setUser($this->editingteachers[0]);
66 $assign = $this->create_instance();
bd3b3bba 67 $installedplugins = array_keys(core_component::get_plugin_list('assignsubmission'));
11527706
DW
68
69 foreach ($assign->get_submission_plugins() as $plugin) {
70 $this->assertContains($plugin->get_type(), $installedplugins, 'Submission plugin not in list of installed plugins');
71 }
47f48152
DW
72 }
73
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());
78
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')));
83
84 // Test students cannot reveal identities.
85 $nopermission = false;
05a6445a 86 $this->students[0]->ignoresesskey = true;
47f48152
DW
87 $this->setUser($this->students[0]);
88 $this->setExpectedException('required_capability_exception');
05a6445a
DW
89 $assign->reveal_identities();
90 $this->students[0]->ignoresesskey = false;
47f48152
DW
91
92 // Test teachers cannot reveal identities.
93 $nopermission = false;
05a6445a 94 $this->teachers[0]->ignoresesskey = true;
47f48152
DW
95 $this->setUser($this->teachers[0]);
96 $this->setExpectedException('required_capability_exception');
05a6445a
DW
97 $assign->reveal_identities();
98 $this->teachers[0]->ignoresesskey = false;
47f48152
DW
99
100 // Test sesskey is required.
47f48152
DW
101 $this->setUser($this->editingteachers[0]);
102 $this->setExpectedException('moodle_exception');
05a6445a 103 $assign->reveal_identities();
47f48152
DW
104
105 // Test editingteacher can reveal identities if sesskey is ignored.
106 $this->editingteachers[0]->ignoresesskey = true;
107 $this->setUser($this->editingteachers[0]);
05a6445a 108 $assign->reveal_identities();
47f48152 109 $this->assertEquals(false, $assign->is_blind_marking());
05a6445a 110 $this->editingteachers[0]->ignoresesskey = false;
47f48152
DW
111
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')));
116
117 // Set this back to default.
118 $this->editingteachers[0]->ignoresesskey = false;
119 }
120
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));
125
126 $this->assertEquals(true, $assign->testable_show_intro());
127
128 $tomorrow = time() + (24*60*60);
129
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());
137 }
138
139 public function test_has_submissions_or_grades() {
140 $this->setUser($this->editingteachers[0]);
141 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
142
143 $instance = $assign->get_instance();
144
145 // Should start empty.
146 $this->assertEquals(false, $assign->has_submissions_or_grades());
147
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);
157
158 // Now test again.
159 $this->assertEquals(true, $assign->has_submissions_or_grades());
160 // Set this back to default.
161 $this->students[0]->ignoresesskey = false;
162 }
163
164 public function test_delete_grades() {
165 $this->setUser($this->editingteachers[0]);
166 $assign = $this->create_instance();
167
168 // Simulate adding a grade.
169 $this->setUser($this->teachers[0]);
170 $data = new stdClass();
171 $data->grade = '50.0';
df211804 172 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
173
174 // Now see if the data is in the gradebook.
175 $gradinginfo = grade_get_grades($this->course->id,
176 'mod',
177 'assign',
178 $assign->get_instance()->id);
179
180 $this->assertNotEquals(0, count($gradinginfo->items));
181
182 $assign->testable_delete_grades();
183 $gradinginfo = grade_get_grades($this->course->id,
184 'mod',
185 'assign',
186 $assign->get_instance()->id);
187
188 $this->assertEquals(0, count($gradinginfo->items));
189 }
190
191 public function test_delete_instance() {
192 $this->setUser($this->editingteachers[0]);
193 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
194
195 // Simulate adding a grade.
196 $this->setUser($this->teachers[0]);
197 $data = new stdClass();
198 $data->grade = '50.0';
df211804 199 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
200
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);
210
211 // Now try and delete.
212 $this->assertEquals(true, $assign->delete_instance());
213 }
214
215 public function test_reset_userdata() {
216 global $DB;
217
218 $now = time();
219 $this->setUser($this->editingteachers[0]);
220 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1,
221 'duedate'=>$now));
222
223 // Simulate adding a grade.
224 $this->setUser($this->teachers[0]);
225 $data = new stdClass();
226 $data->grade = '50.0';
df211804 227 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
228
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);
238
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());
249
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);
253 }
254
255 public function test_plugin_settings() {
256 global $DB;
257
258 $now = time();
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));
263
264 $plugin = $assign->get_submission_plugin_by_type('file');
265 $this->assertEquals('12', $plugin->get_config('maxfilesubmissions'));
266 }
267
268 public function test_update_calendar() {
269 global $DB;
270
271 $now = time();
272 $this->setUser($this->editingteachers[0]);
273 $assign = $this->create_instance(array('duedate'=>$now));
274
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);
278
279 $this->assertEquals(false, empty($id));
280 }
281
282 public function test_update_instance() {
283 global $DB;
284
285 $this->setUser($this->editingteachers[0]);
286 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
287
288 $now = time();
289 $instance = $assign->get_instance();
290 $instance->duedate = $now;
291 $instance->instance = $instance->id;
292 $instance->assignsubmission_onlinetext_enabled = 1;
47f48152
DW
293
294 $assign->update_instance($instance);
295
296 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
297 $this->assertEquals($now, $instance->duedate);
298 }
299
8fd00a24
DW
300 public function test_cannot_submit_empty() {
301 global $PAGE;
302
303 $this->setUser($this->editingteachers[0]);
304 $assign = $this->create_instance(array('submissiondrafts'=>1));
305
306 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
307
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');
312
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;
318
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');
323
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');
335 }
336
47f48152 337 public function test_list_participants() {
df211804 338 $this->create_extra_users();
47f48152
DW
339 $this->setUser($this->editingteachers[0]);
340 $assign = $this->create_instance(array('grade'=>100));
341
a5c793c3 342 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true)));
e6cc5347
RT
343
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)));
349
1ecb8044 350 // Non-editing teacher should not see suspended users, even if user preference is set.
e6cc5347
RT
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)));
47f48152
DW
355 }
356
357 public function test_count_teams() {
df211804 358 $this->create_extra_users();
47f48152
DW
359 $this->setUser($this->editingteachers[0]);
360 $assign = $this->create_instance(array('teamsubmission'=>1));
361
a5c793c3 362 $this->assertEquals(self::GROUP_COUNT + 1, $assign->count_teams());
47f48152
DW
363 }
364
365 public function test_count_submissions() {
df211804 366 $this->create_extra_users();
47f48152
DW
367 $this->setUser($this->editingteachers[0]);
368 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
369
370 // Simulate a submission.
a5c793c3
DW
371 $this->setUser($this->extrastudents[0]);
372 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
47f48152
DW
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);
380
381 // Simulate adding a grade.
382 $this->setUser($this->teachers[0]);
383 $data = new stdClass();
384 $data->grade = '50.0';
df211804 385 $assign->testable_apply_grade_to_user($data, $this->extrastudents[0]->id, 0);
47f48152
DW
386
387 // Simulate a submission.
a5c793c3
DW
388 $this->setUser($this->extrastudents[1]);
389 $submission = $assign->get_user_submission($this->extrastudents[1]->id, true);
47f48152 390 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 391 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, false);
47f48152
DW
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);
398
399 // Simulate a submission.
a5c793c3
DW
400 $this->setUser($this->extrastudents[2]);
401 $submission = $assign->get_user_submission($this->extrastudents[2]->id, true);
47f48152 402 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 403 $assign->testable_update_submission($submission, $this->extrastudents[2]->id, true, false);
47f48152
DW
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);
410
411 // Simulate a submission.
a5c793c3
DW
412 $this->setUser($this->extrastudents[3]);
413 $submission = $assign->get_user_submission($this->extrastudents[3]->id, true);
47f48152 414 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 415 $assign->testable_update_submission($submission, $this->extrastudents[3]->id, true, false);
47f48152
DW
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);
422
e6cc5347
RT
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);
434
47f48152
DW
435 // Simulate adding a grade.
436 $this->setUser($this->teachers[0]);
437 $data = new stdClass();
438 $data->grade = '50.0';
df211804 439 $assign->testable_apply_grade_to_user($data, $this->extrastudents[3]->id, 0);
e6cc5347 440 $assign->testable_apply_grade_to_user($data, $this->extrasuspendedstudents[0]->id, 0);
47f48152
DW
441
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));
447 }
448
449 public function test_get_grading_userid_list() {
df211804 450 $this->create_extra_users();
47f48152
DW
451 $this->setUser($this->editingteachers[0]);
452 $assign = $this->create_instance();
453
454 $users = $assign->testable_get_grading_userid_list();
a5c793c3 455 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($users));
e6cc5347
RT
456
457 $this->setUser($this->editingteachers[0]);
458 set_user_preference('grade_report_showonlyactiveenrol', false);
459 $assign = $this->create_instance();
460
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));
47f48152
DW
463 }
464
465 public function test_cron() {
466 // First run cron so there are no messages waiting to be sent (from other tests).
467 cron_setup_user();
468 assign::cron();
469
470 // Now create an assignment and add some feedback.
471 $this->setUser($this->editingteachers[0]);
472 $assign = $this->create_instance();
473
474 // Simulate adding a grade.
475 $this->setUser($this->teachers[0]);
476 $data = new stdClass();
477 $data->grade = '50.0';
df211804 478 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
479
480 // Now run cron and see that one message was sent.
481 $this->preventResetByRollback();
482 $sink = $this->redirectMessages();
483 cron_setup_user();
484 $this->expectOutputRegex('/Done processing 1 assignment submissions/');
485 assign::cron();
486
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);
491 }
492
493 public function test_is_graded() {
494 $this->setUser($this->editingteachers[0]);
495 $assign = $this->create_instance();
496
497 // Simulate adding a grade.
498 $this->setUser($this->teachers[0]);
499 $data = new stdClass();
500 $data->grade = '50.0';
df211804 501 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
502
503 $this->assertEquals(true, $assign->testable_is_graded($this->students[0]->id));
504 $this->assertEquals(false, $assign->testable_is_graded($this->students[1]->id));
505 }
506
507 public function test_can_view_submission() {
e6cc5347 508 $this->create_extra_users();
47f48152
DW
509 $this->setUser($this->editingteachers[0]);
510 $assign = $this->create_instance();
511
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));
e6cc5347 520 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
47f48152
DW
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));
e6cc5347 525 $this->assertEquals(true, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
47f48152
DW
526 }
527
528
529 public function test_update_submission() {
df211804 530 $this->create_extra_users();
47f48152
DW
531 $this->setUser($this->editingteachers[0]);
532 $assign = $this->create_instance();
533
a5c793c3 534 $this->setUser($this->extrastudents[0]);
47f48152 535 $now = time();
a5c793c3
DW
536 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
537 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
47f48152
DW
538
539 $this->setUser($this->teachers[0]);
540 // Verify the gradebook update.
541 $gradinginfo = grade_get_grades($this->course->id,
542 'mod',
543 'assign',
544 $assign->get_instance()->id,
a5c793c3 545 $this->extrastudents[0]->id);
47f48152 546
a5c793c3
DW
547 $this->assertEquals($this->extrastudents[0]->id,
548 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
47f48152
DW
549
550 // Now verify group assignments.
551 $this->setUser($this->editingteachers[0]);
552 $assign = $this->create_instance(array('teamsubmission'=>1));
553
a5c793c3 554 $this->setUser($this->extrastudents[0]);
47f48152 555 $now = time();
a5c793c3
DW
556 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
557 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
47f48152 558
e6cc5347 559 // Check that at least 2 active members and 1 suspended member of the submission group had their submission updated.
47f48152
DW
560
561 $this->setUser($this->editingteachers[0]);
562 $gradinginfo = grade_get_grades($this->course->id,
563 'mod',
564 'assign',
565 $assign->get_instance()->id,
a5c793c3 566 $this->extrastudents[0]->id);
47f48152 567
a5c793c3
DW
568 $this->assertEquals($this->extrastudents[0]->id,
569 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
47f48152
DW
570
571 $gradinginfo = grade_get_grades($this->course->id,
572 'mod',
573 'assign',
574 $assign->get_instance()->id,
a5c793c3 575 $this->extrastudents[self::GROUP_COUNT]->id);
47f48152 576
a5c793c3
DW
577 $this->assertEquals($this->extrastudents[self::GROUP_COUNT]->id,
578 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT]->id]->usermodified);
47f48152 579
e6cc5347
RT
580 $gradinginfo = grade_get_grades($this->course->id,
581 'mod',
582 'assign',
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);
587
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));
591
592 $this->setUser($this->extrastudents[1]);
593 $now = time();
594 $submission = $assign->get_group_submission($this->extrastudents[1]->id, 0, true);
595 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, true);
596
597 $this->setUser($this->teachers[0]);
598 $gradinginfo = grade_get_grades($this->course->id,
599 'mod',
600 'assign',
601 $assign->get_instance()->id,
602 $this->extrastudents[1]->id);
603
604 $this->assertEquals($this->extrastudents[1]->id,
605 $gradinginfo->items[0]->grades[$this->extrastudents[1]->id]->usermodified);
606
607 $gradinginfo = grade_get_grades($this->course->id,
608 'mod',
609 'assign',
610 $assign->get_instance()->id,
611 $this->extrastudents[self::GROUP_COUNT+1]->id);
612
613 $this->assertEquals($this->extrastudents[self::GROUP_COUNT+1]->id,
614 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT+1]->id]->usermodified);
615
616 $gradinginfo = grade_get_grades($this->course->id,
617 'mod',
618 'assign',
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);
623
47f48152
DW
624 // Now verify blind marking.
625 $this->setUser($this->editingteachers[0]);
626 $assign = $this->create_instance(array('blindmarking'=>1));
627
a5c793c3 628 $this->setUser($this->extrastudents[0]);
47f48152 629 $now = time();
a5c793c3
DW
630 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
631 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
47f48152
DW
632
633 $this->setUser($this->editingteachers[0]);
634 $gradinginfo = grade_get_grades($this->course->id,
635 'mod',
636 'assign',
637 $assign->get_instance()->id,
a5c793c3 638 $this->extrastudents[0]->id);
47f48152 639
a5c793c3 640 $this->assertEquals(null, $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->datesubmitted);
47f48152
DW
641 }
642
643 public function test_submissions_open() {
644 $this->setUser($this->editingteachers[0]);
645
646 $now = time();
647 $tomorrow = $now + 24*60*60;
648 $oneweek = $now + 7*24*60*60;
649 $yesterday = $now - 24*60*60;
650
651 $assign = $this->create_instance();
652 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
653
654 $assign = $this->create_instance(array('duedate'=>$tomorrow));
655 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
656
657 $assign = $this->create_instance(array('duedate'=>$yesterday));
658 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
659
660 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$tomorrow));
661 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
662
663 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$yesterday));
664 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
665
666 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
667 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
668
669 $assign = $this->create_instance(array('submissiondrafts'=>1));
670 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
671
672 $this->setUser($this->students[0]);
673 $now = time();
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));
679 }
680
681 public function test_get_graders() {
df211804 682 $this->create_extra_users();
47f48152
DW
683 $this->setUser($this->editingteachers[0]);
684 $assign = $this->create_instance();
685
a5c793c3
DW
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));
47f48152
DW
691
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);
702
703 $this->setUser($this->students[1]);
a5c793c3 704 $this->assertCount(4, $assign->testable_get_graders($this->students[0]->id));
47f48152
DW
705 }
706
20b7dcfc
DW
707 public function test_group_members_only() {
708 global $CFG;
709
710 $this->setAdminUser();
711 $this->create_extra_users();
712 $CFG->enablegroupmembersonly = true;
713 $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $this->course->id));
714 groups_assign_grouping($grouping->id, $this->groups[0]->id);
715
716 // Force create an assignment with SEPARATEGROUPS.
717 $instance = $this->getDataGenerator()->create_module('assign', array('course'=>$this->course->id),
718 array('groupmembersonly' => SEPARATEGROUPS, 'groupingid' => $grouping->id));
719
720 $cm = get_coursemodule_from_instance('assign', $instance->id);
721 $context = context_module::instance($cm->id);
722 $assign = new testable_assign($context, $cm, $this->course);
723
724 $this->setUser($this->teachers[0]);
725 $this->assertCount(5, $assign->list_participants(0, true));
726
727 }
728
47f48152
DW
729 public function test_get_uniqueid_for_user() {
730 $this->setUser($this->editingteachers[0]);
731 $assign = $this->create_instance();
732
733 foreach ($this->students as $student) {
734 $uniqueid = $assign->get_uniqueid_for_user($student->id);
735 $this->assertEquals($student->id, $assign->get_user_id_for_uniqueid($uniqueid));
736 }
737 }
738
46692c3a 739 public function test_show_student_summary() {
c2114099 740 global $CFG, $PAGE;
46692c3a
DW
741
742 $this->setUser($this->editingteachers[0]);
743 $assign = $this->create_instance();
c2114099 744 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
46692c3a
DW
745
746 // No feedback should be available because this student has not been graded.
747 $this->setUser($this->students[0]);
748 $output = $assign->view_student_summary($this->students[0], true);
749 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if there is no grade');
750 // Simulate adding a grade.
751 $this->setUser($this->teachers[0]);
752 $data = new stdClass();
753 $data->grade = '50.0';
df211804 754 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
46692c3a 755
b0da618b 756 // Now we should see the feedback.
46692c3a
DW
757 $this->setUser($this->students[0]);
758 $output = $assign->view_student_summary($this->students[0], true);
759 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade');
760
761 // Now hide the grade in gradebook.
762 $this->setUser($this->teachers[0]);
763 require_once($CFG->libdir.'/gradelib.php');
764 $gradeitem = new grade_item(array(
765 'itemtype' => 'mod',
766 'itemmodule' => 'assign',
767 'iteminstance' => $assign->get_instance()->id,
768 'courseid' => $this->course->id));
769
770 $gradeitem->set_hidden(1, false);
771
772 // No feedback should be available because the grade is hidden.
773 $this->setUser($this->students[0]);
774 $output = $assign->view_student_summary($this->students[0], true);
775 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
776
b0da618b 777 // Do the same but add feedback.
46692c3a
DW
778 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
779
780 $this->setUser($this->teachers[0]);
781 $grade = $assign->get_user_grade($this->students[0]->id, true);
782 $data = new stdClass();
783 $data->assignfeedbackcomments_editor = array('text'=>'Tomato sauce',
784 'format'=>FORMAT_MOODLE);
785 $plugin = $assign->get_feedback_plugin_by_type('comments');
786 $plugin->save($grade, $data);
787
b0da618b 788 // Should have feedback but no grade.
46692c3a
DW
789 $this->setUser($this->students[0]);
790 $output = $assign->view_student_summary($this->students[0], true);
ea698284 791 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback even if there is no grade');
46692c3a
DW
792 $this->assertEquals(false, strpos($output, 'Grade'), 'Do not show grade when there is no grade.');
793 $this->assertEquals(false, strpos($output, 'Graded on'), 'Do not show graded date when there is no grade.');
45aac51a 794
ea698284
AD
795 // Now hide the grade in gradebook.
796 $this->setUser($this->teachers[0]);
797 $gradeitem = new grade_item(array(
798 'itemtype' => 'mod',
799 'itemmodule' => 'assign',
800 'iteminstance' => $assign->get_instance()->id,
801 'courseid' => $this->course->id));
802
803 $gradeitem->set_hidden(1, false);
804
805 // No feedback should be available because the grade is hidden.
806 $this->setUser($this->students[0]);
807 $output = $assign->view_student_summary($this->students[0], true);
808 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
46692c3a
DW
809 }
810
df211804
DW
811 public function test_attempt_reopen_method_manual() {
812 global $PAGE;
813
814 $this->setUser($this->editingteachers[0]);
815 $assign = $this->create_instance(array('attemptreopenmethod'=>ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
816 'maxattempts'=>3,
817 'submissiondrafts'=>1,
818 'assignsubmission_onlinetext_enabled'=>1));
819 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
820
821 // Student should be able to see an add submission button.
822 $this->setUser($this->students[0]);
823 $output = $assign->view_student_summary($this->students[0], true);
824 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
825
826 // Add a submission.
827 $now = time();
828 $submission = $assign->get_user_submission($this->students[0]->id, true);
829 $data = new stdClass();
830 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
831 'text'=>'Submission text',
832 'format'=>FORMAT_MOODLE);
833 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
834 $plugin->save($submission, $data);
835
836 // And now submit it for marking.
837 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
838 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
839
840 // Verify the student cannot make changes to the submission.
841 $output = $assign->view_student_summary($this->students[0], true);
842 $this->assertEquals(false, strpos($output, get_string('addsubmission', 'assign')));
843
844 // Mark the submission.
845 $this->setUser($this->teachers[0]);
846 $data = new stdClass();
847 $data->grade = '50.0';
848 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
849
850 // Check the student can see the grade.
851 $this->setUser($this->students[0]);
852 $output = $assign->view_student_summary($this->students[0], true);
853 $this->assertNotEquals(false, strpos($output, '50.0'));
854
855 // Allow the student another attempt.
856 $this->teachers[0]->ignoresesskey = true;
857 $this->setUser($this->teachers[0]);
858 $result = $assign->testable_process_add_attempt($this->students[0]->id);
859 $this->assertEquals(true, $result);
860
861 // Check that the previous attempt is now in the submission history table.
862 $this->setUser($this->students[0]);
863 $output = $assign->view_student_summary($this->students[0], true);
864 // Need a better check.
865 $this->assertNotEquals(false, strpos($output, 'Submission text'), 'Contains: Submission text');
866
867 // Check that the student now has a button for Add a new attempt".
868 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
869 // Check that the student now does not have a button for Submit.
870 $this->assertEquals(false, strpos($output, get_string('submitassignment', 'assign')));
871
872 // Check that the student now has a submission history.
873 $this->assertNotEquals(false, strpos($output, get_string('attempthistory', 'assign')));
874
875 $this->setUser($this->teachers[0]);
876 // Check that the grading table loads correctly and contains this user.
877 // This is also testing that we do not get duplicate rows in the grading table.
878 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
879 $output = $assign->get_renderer()->render($gradingtable);
880 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
881
882 // Should be 1 not 2.
883 $this->assertEquals(1, $assign->count_submissions());
884 $this->assertEquals(1, $assign->count_submissions_with_status('reopened'));
885 $this->assertEquals(0, $assign->count_submissions_need_grading());
886 $this->assertEquals(1, $assign->count_grades());
887
888 // Change max attempts to unlimited.
889 $formdata = clone($assign->get_instance());
890 $formdata->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS;
891 $formdata->instance = $formdata->id;
892 $assign->update_instance($formdata);
893
894 // Check we can repopen still.
895 $result = $assign->testable_process_add_attempt($this->students[0]->id);
896 $this->assertEquals(true, $result);
897
898 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id);
899 $this->assertEquals(50, (int)$grades[$this->students[0]->id]->rawgrade);
900
df211804 901 }
46692c3a 902
f8d107b3
DM
903 public function test_markingworkflow() {
904 global $PAGE;
905
906 $this->setUser($this->editingteachers[0]);
907 $assign = $this->create_instance(array('markingworkflow'=>1));
908 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
909
13e82f1c 910 // Mark the submission and set to notmarked.
f8d107b3
DM
911 $this->setUser($this->teachers[0]);
912 $data = new stdClass();
913 $data->grade = '50.0';
914 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED;
915 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
916
917 // Check the student can't see the grade.
918 $this->setUser($this->students[0]);
919 $output = $assign->view_student_summary($this->students[0], true);
920 $this->assertEquals(false, strpos($output, '50.0'));
921
13e82f1c 922 // Mark the submission and set to inmarking.
f8d107b3
DM
923 $this->setUser($this->teachers[0]);
924 $data = new stdClass();
925 $data->grade = '50.0';
926 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INMARKING;
927 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
928
929 // Check the student can't see the grade.
930 $this->setUser($this->students[0]);
931 $output = $assign->view_student_summary($this->students[0], true);
932 $this->assertEquals(false, strpos($output, '50.0'));
933
13e82f1c 934 // Mark the submission and set to readyforreview.
f8d107b3
DM
935 $this->setUser($this->teachers[0]);
936 $data = new stdClass();
937 $data->grade = '50.0';
938 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW;
939 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
940
941 // Check the student can't see the grade.
942 $this->setUser($this->students[0]);
943 $output = $assign->view_student_summary($this->students[0], true);
944 $this->assertEquals(false, strpos($output, '50.0'));
945
13e82f1c 946 // Mark the submission and set to inreview.
f8d107b3
DM
947 $this->setUser($this->teachers[0]);
948 $data = new stdClass();
949 $data->grade = '50.0';
950 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW;
951 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
952
953 // Check the student can't see the grade.
954 $this->setUser($this->students[0]);
955 $output = $assign->view_student_summary($this->students[0], true);
956 $this->assertEquals(false, strpos($output, '50.0'));
957
13e82f1c 958 // Mark the submission and set to readyforrelease.
f8d107b3
DM
959 $this->setUser($this->teachers[0]);
960 $data = new stdClass();
961 $data->grade = '50.0';
962 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE;
963 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
964
965 // Check the student can't see the grade.
966 $this->setUser($this->students[0]);
967 $output = $assign->view_student_summary($this->students[0], true);
968 $this->assertEquals(false, strpos($output, '50.0'));
969
13e82f1c 970 // Mark the submission and set to released.
f8d107b3
DM
971 $this->setUser($this->teachers[0]);
972 $data = new stdClass();
973 $data->grade = '50.0';
974 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_RELEASED;
975 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
976
977 // Check the student can see the grade.
978 $this->setUser($this->students[0]);
979 $output = $assign->view_student_summary($this->students[0], true);
980 $this->assertNotEquals(false, strpos($output, '50.0'));
981 }
982
983 public function test_markerallocation() {
984 global $PAGE;
985
986 $this->setUser($this->editingteachers[0]);
13e82f1c 987 $assign = $this->create_instance(array('markingworkflow'=>1, 'markingallocation'=>1));
f8d107b3
DM
988 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
989
13e82f1c 990 // Allocate marker to submission.
f8d107b3
DM
991 $data = new stdClass();
992 $data->allocatedmarker = $this->teachers[0]->id;
993 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
994
13e82f1c 995 // Check the allocated marker can view the submission.
f8d107b3
DM
996 $this->setUser($this->teachers[0]);
997 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
998 $output = $assign->get_renderer()->render($gradingtable);
999 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
1000
13e82f1c 1001 // Check that other teachers can't view this submission.
f8d107b3
DM
1002 $this->setUser($this->teachers[1]);
1003 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
1004 $output = $assign->get_renderer()->render($gradingtable);
1005 $this->assertNotEquals(true, strpos($output, $this->students[0]->lastname));
1006 }
76e77b05
FM
1007
1008 public function test_extension_granted_event() {
1009 $this->setUser($this->editingteachers[0]);
1010
1011 $tomorrow = time() + 24*60*60;
1012 $yesterday = time() - 24*60*60;
1013
1014 $assign = $this->create_instance(array('duedate' => $yesterday, 'cutoffdate' => $yesterday));
1015 $sink = $this->redirectEvents();
1016
1017 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
1018
1019 $events = $sink->get_events();
1020 $this->assertCount(1, $events);
1021 $event = reset($events);
1022 $this->assertInstanceOf('\mod_assign\event\extension_granted', $event);
1023 $this->assertEquals($assign->get_context(), $event->get_context());
1024 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1025 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1026 $expected = array(
1027 $assign->get_course()->id,
1028 'assign',
1029 'grant extension',
1030 'view.php?id=' . $assign->get_course_module()->id,
1031 $this->students[0]->id,
1032 $assign->get_course_module()->id,
1033 $this->editingteachers[0]->id
1034 );
1035 $this->assertEventLegacyLogData($expected, $event);
1036 $sink->close();
1037 }
1038
3d1331be
FM
1039 public function test_submission_locked_event() {
1040 $this->editingteachers[0]->ignoresesskey = true;
1041 $this->setUser($this->editingteachers[0]);
1042
1043 $assign = $this->create_instance();
1044 $sink = $this->redirectEvents();
1045
05a6445a 1046 $assign->lock_submission($this->students[0]->id);
3d1331be
FM
1047
1048 $events = $sink->get_events();
1049 $this->assertCount(1, $events);
1050 $event = reset($events);
1051 $this->assertInstanceOf('\mod_assign\event\submission_locked', $event);
1052 $this->assertEquals($assign->get_context(), $event->get_context());
1053 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1054 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1055 $expected = array(
1056 $assign->get_course()->id,
1057 'assign',
1058 'lock submission',
1059 'view.php?id=' . $assign->get_course_module()->id,
1060 get_string('locksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
1061 'fullname' => fullname($this->students[0]))),
1062 $assign->get_course_module()->id,
1063 $this->editingteachers[0]->id
1064 );
1065 $this->assertEventLegacyLogData($expected, $event);
1066 $sink->close();
1067
1068 // Revert to defaults.
1069 $this->editingteachers[0]->ignoresesskey = false;
1070 }
1071
ad10ad14
FM
1072 public function test_identities_revealed_event() {
1073 $this->editingteachers[0]->ignoresesskey = true;
1074 $this->setUser($this->editingteachers[0]);
1075
1076 $assign = $this->create_instance(array('blindmarking'=>1));
1077 $sink = $this->redirectEvents();
1078
05a6445a 1079 $assign->reveal_identities();
ad10ad14
FM
1080
1081 $events = $sink->get_events();
1082 $this->assertCount(1, $events);
1083 $event = reset($events);
1084 $this->assertInstanceOf('\mod_assign\event\identities_revealed', $event);
1085 $this->assertEquals($assign->get_context(), $event->get_context());
1086 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1087 $expected = array(
1088 $assign->get_course()->id,
1089 'assign',
1090 'reveal identities',
1091 'view.php?id=' . $assign->get_course_module()->id,
1092 get_string('revealidentities', 'assign'),
1093 $assign->get_course_module()->id,
1094 $this->editingteachers[0]->id
1095 );
1096 $this->assertEventLegacyLogData($expected, $event);
1097 $sink->close();
1098
1099 // Revert to defaults.
1100 $this->editingteachers[0]->ignoresesskey = false;
1101 }
1102
159b7f40
FM
1103 public function test_submission_status_updated_event() {
1104 $this->editingteachers[0]->ignoresesskey = true;
1105 $this->setUser($this->editingteachers[0]);
1106
1107 $assign = $this->create_instance();
1108 $submission = $assign->get_user_submission($this->students[0]->id, true);
1109 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1110 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1111
1112 $sink = $this->redirectEvents();
05a6445a 1113 $assign->revert_to_draft($this->students[0]->id);
159b7f40
FM
1114
1115 $events = $sink->get_events();
1116 $this->assertCount(1, $events);
1117 $event = reset($events);
1118 $this->assertInstanceOf('\mod_assign\event\submission_status_updated', $event);
1119 $this->assertEquals($assign->get_context(), $event->get_context());
1120 $this->assertEquals($submission->id, $event->objectid);
1121 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1122 $this->assertEquals(ASSIGN_SUBMISSION_STATUS_DRAFT, $event->other['newstatus']);
1123 $expected = array(
1124 $assign->get_course()->id,
1125 'assign',
1126 'revert submission to draft',
1127 'view.php?id=' . $assign->get_course_module()->id,
1128 get_string('reverttodraftforstudent', 'assign', array('id' => $this->students[0]->id,
1129 'fullname' => fullname($this->students[0]))),
1130 $assign->get_course_module()->id,
1131 $this->editingteachers[0]->id
1132 );
1133 $this->assertEventLegacyLogData($expected, $event);
1134 $sink->close();
1135
1136 // Revert to defaults.
1137 $this->editingteachers[0]->ignoresesskey = false;
1138 }
1139
e59a85ba
FM
1140 public function test_marker_updated_event() {
1141 $this->editingteachers[0]->ignoresesskey = true;
1142 $this->setUser($this->editingteachers[0]);
1143
1144 $assign = $this->create_instance();
1145
1146 $sink = $this->redirectEvents();
1147 $assign->testable_process_set_batch_marking_allocation($this->students[0]->id, $this->teachers[0]->id);
1148
1149 $events = $sink->get_events();
1150 $this->assertCount(1, $events);
1151 $event = reset($events);
1152 $this->assertInstanceOf('\mod_assign\event\marker_updated', $event);
1153 $this->assertEquals($assign->get_context(), $event->get_context());
1154 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1155 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1156 $this->assertEquals($this->editingteachers[0]->id, $event->userid);
1157 $this->assertEquals($this->teachers[0]->id, $event->other['markerid']);
1158 $expected = array(
1159 $assign->get_course()->id,
1160 'assign',
1161 'set marking allocation',
1162 'view.php?id=' . $assign->get_course_module()->id,
1163 get_string('setmarkerallocationforlog', 'assign', array('id' => $this->students[0]->id,
1164 'fullname' => fullname($this->students[0]), 'marker' => fullname($this->teachers[0]))),
1165 $assign->get_course_module()->id,
1166 $this->editingteachers[0]->id
1167 );
1168 $this->assertEventLegacyLogData($expected, $event);
1169 $sink->close();
1170
1171 // Revert to defaults.
1172 $this->editingteachers[0]->ignoresesskey = false;
1173 }
1174
8bb213eb
FM
1175 public function test_workflow_state_updated_event() {
1176 $this->editingteachers[0]->ignoresesskey = true;
1177 $this->setUser($this->editingteachers[0]);
1178
1179 $assign = $this->create_instance();
1180
1181 $sink = $this->redirectEvents();
1182 $assign->testable_process_set_batch_marking_workflow_state($this->students[0]->id, ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
1183
1184 $events = $sink->get_events();
1185 $this->assertCount(1, $events);
1186 $event = reset($events);
1187 $this->assertInstanceOf('\mod_assign\event\workflow_state_updated', $event);
1188 $this->assertEquals($assign->get_context(), $event->get_context());
1189 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1190 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1191 $this->assertEquals($this->editingteachers[0]->id, $event->userid);
1192 $this->assertEquals(ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW, $event->other['newstate']);
1193 $expected = array(
1194 $assign->get_course()->id,
1195 'assign',
1196 'set marking workflow state',
1197 'view.php?id=' . $assign->get_course_module()->id,
1198 get_string('setmarkingworkflowstateforlog', 'assign', array('id' => $this->students[0]->id,
1199 'fullname' => fullname($this->students[0]), 'state' => ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW)),
1200 $assign->get_course_module()->id,
1201 $this->editingteachers[0]->id
1202 );
1203 $this->assertEventLegacyLogData($expected, $event);
1204 $sink->close();
1205
1206 // Revert to defaults.
1207 $this->editingteachers[0]->ignoresesskey = false;
1208 }
89fbc202
FM
1209
1210 public function test_submission_duplicated_event() {
1211 $this->setUser($this->students[0]);
1212
1213 $assign = $this->create_instance();
1214 $submission1 = $assign->get_user_submission($this->students[0]->id, true, 0);
1215 $submission2 = $assign->get_user_submission($this->students[0]->id, true, 1);
1216 $submission2->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
1217 $assign->testable_update_submission($submission2, $this->students[0]->id, time(), $assign->get_instance()->teamsubmission);
1218
1219 $sink = $this->redirectEvents();
1220 $notices = null;
05a6445a 1221 $assign->copy_previous_attempt($notices);
89fbc202
FM
1222
1223 $events = $sink->get_events();
1224 $this->assertCount(1, $events);
1225 $event = reset($events);
1226 $this->assertInstanceOf('\mod_assign\event\submission_duplicated', $event);
1227 $this->assertEquals($assign->get_context(), $event->get_context());
1228 $this->assertEquals($submission2->id, $event->objectid);
1229 $this->assertEquals($this->students[0]->id, $event->userid);
1230 $submission2->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
1231 $expected = array(
1232 $assign->get_course()->id,
1233 'assign',
1234 'submissioncopied',
1235 'view.php?id=' . $assign->get_course_module()->id,
1236 $assign->testable_format_submission_for_log($submission2),
1237 $assign->get_course_module()->id,
1238 $this->students[0]->id
1239 );
1240 $this->assertEventLegacyLogData($expected, $event);
1241 $sink->close();
1242 }
1243
9a289c3d
FM
1244 public function test_submission_unlocked_event() {
1245 $this->editingteachers[0]->ignoresesskey = true;
1246 $this->setUser($this->editingteachers[0]);
1247
1248 $assign = $this->create_instance();
1249 $sink = $this->redirectEvents();
1250
05a6445a 1251 $assign->unlock_submission($this->students[0]->id);
9a289c3d
FM
1252
1253 $events = $sink->get_events();
1254 $this->assertCount(1, $events);
1255 $event = reset($events);
1256 $this->assertInstanceOf('\mod_assign\event\submission_unlocked', $event);
1257 $this->assertEquals($assign->get_context(), $event->get_context());
1258 $this->assertEquals($assign->get_instance()->id, $event->objectid);
1259 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1260 $expected = array(
1261 $assign->get_course()->id,
1262 'assign',
1263 'unlock submission',
1264 'view.php?id=' . $assign->get_course_module()->id,
1265 get_string('unlocksubmissionforstudent', 'assign', array('id' => $this->students[0]->id,
1266 'fullname' => fullname($this->students[0]))),
1267 $assign->get_course_module()->id,
1268 $this->editingteachers[0]->id
1269 );
1270 $this->assertEventLegacyLogData($expected, $event);
1271 $sink->close();
1272
1273 // Revert to defaults.
1274 $this->editingteachers[0]->ignoresesskey = false;
1275 }
1276
bd2e9829
FM
1277 public function test_submission_graded_event() {
1278 $this->setUser($this->editingteachers[0]);
1279 $assign = $this->create_instance();
1280
1281 // Test apply_grade_to_user.
1282 $sink = $this->redirectEvents();
1283
1284 $data = new stdClass();
1285 $data->grade = '50.0';
1286 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1287 $grade = $assign->get_user_grade($this->students[0]->id, false, 0);
1288
1289 $events = $sink->get_events();
1290 $this->assertCount(1, $events);
1291 $event = reset($events);
1292 $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
1293 $this->assertEquals($assign->get_context(), $event->get_context());
1294 $this->assertEquals($grade->id, $event->objectid);
1295 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1296 $expected = array(
1297 $assign->get_course()->id,
1298 'assign',
1299 'grade submission',
1300 'view.php?id=' . $assign->get_course_module()->id,
1301 $assign->format_grade_for_log($grade),
1302 $assign->get_course_module()->id,
1303 $this->editingteachers[0]->id
1304 );
1305 $this->assertEventLegacyLogData($expected, $event);
1306 $sink->close();
1307
1308 // Test process_save_quick_grades.
1309 $sink = $this->redirectEvents();
1310
1311 $data = array(
1312 'grademodified_' . $this->students[0]->id => time(),
1313 'quickgrade_' . $this->students[0]->id => '60.0'
1314 );
1315 $assign->testable_process_save_quick_grades($data);
1316 $grade = $assign->get_user_grade($this->students[0]->id, false);
1317 $this->assertEquals('60.0', $grade->grade);
1318
1319 $events = $sink->get_events();
1320 $this->assertCount(1, $events);
1321 $event = reset($events);
1322 $this->assertInstanceOf('\mod_assign\event\submission_graded', $event);
1323 $this->assertEquals($assign->get_context(), $event->get_context());
1324 $this->assertEquals($grade->id, $event->objectid);
1325 $this->assertEquals($this->students[0]->id, $event->relateduserid);
1326 $expected = array(
1327 $assign->get_course()->id,
1328 'assign',
1329 'grade submission',
1330 'view.php?id=' . $assign->get_course_module()->id,
1331 $assign->format_grade_for_log($grade),
1332 $assign->get_course_module()->id,
1333 $this->editingteachers[0]->id
1334 );
1335 $this->assertEventLegacyLogData($expected, $event);
1336 $sink->close();
1337 }
1338
9054c04d 1339 public function test_disable_submit_after_cutoff_date() {
1340 global $PAGE;
1341
1342 $this->setUser($this->editingteachers[0]);
1343 $now = time();
1344 $tomorrow = $now + 24*60*60;
1345 $lastweek = $now - 7*24*60*60;
1346 $yesterday = $now - 24*60*60;
1347
1348 $assign = $this->create_instance(array('duedate'=>$yesterday,
1349 'cutoffdate'=>$tomorrow,
1350 'assignsubmission_onlinetext_enabled'=>1));
1351 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1352
1353 // Student should be able to see an add submission button.
1354 $this->setUser($this->students[0]);
1355 $output = $assign->view_student_summary($this->students[0], true);
1356 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1357
1358 // Add a submission but don't submit now.
1359 $submission = $assign->get_user_submission($this->students[0]->id, true);
1360 $data = new stdClass();
1361 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1362 'text'=>'Submission text',
1363 'format'=>FORMAT_MOODLE);
1364 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1365 $plugin->save($submission, $data);
1366
1367 // Create another instance with cut-off and due-date already passed.
1368 $this->setUser($this->editingteachers[0]);
1369 $now = time();
1370 $assign = $this->create_instance(array('duedate'=>$lastweek,
1371 'cutoffdate'=>$yesterday,
1372 'assignsubmission_onlinetext_enabled'=>1));
1373
1374 $this->setUser($this->students[0]);
1375 $output = $assign->view_student_summary($this->students[0], true);
1376 $this->assertNotContains($output, get_string('editsubmission', 'assign'),
1377 'Should not be able to edit after cutoff date.');
1378 $this->assertNotContains($output, get_string('submitassignment', 'assign'),
1379 'Should not be able to submit after cutoff date.');
1380 }
47f48152
DW
1381}
1382