Merge branch 'MDL-48235-assign-reopen-until-pass' of git://github.com/mpetrowi/moodle
[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
79397b56
DB
121 /**
122 * Test submissions with extension date.
123 */
124 public function test_gradingtable_extension_due_date() {
125 global $PAGE;
126
127 // Setup the assignment.
128 $this->create_extra_users();
129 $this->setUser($this->editingteachers[0]);
130 $assign = $this->create_instance(array(
131 'assignsubmission_onlinetext_enabled'=>1,
132 'duedate' => time() - 4 * 24 * 60 * 60,
133 ));
134 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array(
135 'id' => $assign->get_course_module()->id,
136 'action' => 'grading',
137 )));
138
139 // Check that the assignment is late.
140 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
141 $output = $assign->get_renderer()->render($gradingtable);
142 $this->assertContains(get_string('submissionstatus_', 'assign'), $output);
143 $this->assertContains(get_string('overdue', 'assign', format_time(4*24*60*60)), $output);
144
145 // Grant an extension.
5b460d65
MG
146 $extendedtime = time() + 2 * 24 * 60 * 60;
147 $assign->testable_save_user_extension($this->students[0]->id, $extendedtime);
79397b56
DB
148 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
149 $output = $assign->get_renderer()->render($gradingtable);
150 $this->assertContains(get_string('submissionstatus_', 'assign'), $output);
5b460d65 151 $this->assertContains(get_string('userextensiondate', 'assign', userdate($extendedtime)), $output);
79397b56
DB
152
153 // Simulate a submission.
154 $this->setUser($this->students[0]);
155 $submission = $assign->get_user_submission($this->students[0]->id, true);
156 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
157 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
158 $data = new stdClass();
159 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
160 'text'=>'Submission text',
161 'format'=>FORMAT_MOODLE);
162 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
163 $plugin->save($submission, $data);
164
165 // Verify output.
166 $this->setUser($this->editingteachers[0]);
167 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
168 $output = $assign->get_renderer()->render($gradingtable);
169 $this->assertContains(get_string('submissionstatus_submitted', 'assign'), $output);
5b460d65 170 $this->assertContains(get_string('userextensiondate', 'assign', userdate($extendedtime)), $output);
79397b56
DB
171 }
172
173 /**
174 * Test that late submissions with extension date calculate correctly.
175 */
176 public function test_gradingtable_extension_date_calculation_for_lateness() {
177 global $PAGE;
178
179 // Setup the assignment.
180 $this->create_extra_users();
181 $this->setUser($this->editingteachers[0]);
a0f8db77 182 $time = time();
79397b56
DB
183 $assign = $this->create_instance(array(
184 'assignsubmission_onlinetext_enabled'=>1,
a0f8db77 185 'duedate' => $time - 4 * 24 * 60 * 60,
79397b56
DB
186 ));
187 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array(
188 'id' => $assign->get_course_module()->id,
189 'action' => 'grading',
190 )));
191
192 // Check that the assignment is late.
193 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
194 $output = $assign->get_renderer()->render($gradingtable);
195 $this->assertContains(get_string('submissionstatus_', 'assign'), $output);
a0f8db77
DW
196 $difftime = time() - $time;
197 $this->assertContains(get_string('overdue', 'assign', format_time(4*24*60*60 + $difftime)), $output);
79397b56
DB
198
199 // Grant an extension that is in the past.
a0f8db77 200 $assign->testable_save_user_extension($this->students[0]->id, $time - 2 * 24 * 60 * 60);
79397b56
DB
201 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
202 $output = $assign->get_renderer()->render($gradingtable);
203 $this->assertContains(get_string('submissionstatus_', 'assign'), $output);
a0f8db77
DW
204 $this->assertContains(get_string('userextensiondate', 'assign', userdate($time - 2*24*60*60)), $output);
205 $difftime = time() - $time;
206 $this->assertContains(get_string('overdue', 'assign', format_time(2*24*60*60 + $difftime)), $output);
79397b56
DB
207
208 // Simulate a submission.
209 $this->setUser($this->students[0]);
210 $submission = $assign->get_user_submission($this->students[0]->id, true);
211 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
212 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
213 $data = new stdClass();
214 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
215 'text'=>'Submission text',
216 'format'=>FORMAT_MOODLE);
217 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
218 $plugin->save($submission, $data);
a0f8db77 219 $submittedtime = time();
79397b56
DB
220
221 // Verify output.
222 $this->setUser($this->editingteachers[0]);
223 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
224 $output = $assign->get_renderer()->render($gradingtable);
225 $this->assertContains(get_string('submissionstatus_submitted', 'assign'), $output);
a0f8db77
DW
226 $this->assertContains(get_string('userextensiondate', 'assign', userdate($time - 2*24*60*60)), $output);
227
228 $difftime = $submittedtime - $time;
229 $this->assertContains(get_string('submittedlateshort', 'assign', format_time(2*24*60*60 + $difftime)), $output);
79397b56
DB
230 }
231
232 /**
233 * Check that group submission information is rendered correctly in the
234 * grading table.
235 */
236 public function test_gradingtable_group_submissions_rendering() {
237 global $PAGE;
238
239 $this->create_extra_users();
240 // Now verify group assignments.
241 $this->setUser($this->teachers[0]);
242 $assign = $this->create_instance(array(
243 'teamsubmission' => 1,
244 'assignsubmission_onlinetext_enabled' => 1,
245 'submissiondrafts' => 1,
246 'requireallteammemberssubmit' => 0,
247 ));
248 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array(
249 'id' => $assign->get_course_module()->id,
250 'action' => 'grading',
251 )));
252
253 // Add a submission.
254 $this->setUser($this->extrastudents[0]);
255 $data = new stdClass();
256 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
257 'text'=>'Submission text',
258 'format'=>FORMAT_MOODLE);
259 $notices = array();
260 $assign->save_submission($data, $notices);
261
262 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
263 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
264 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
265
266 // Check output.
267 $this->setUser($this->teachers[0]);
268 $gradingtable = new assign_grading_table($assign, 4, '', 0, true);
269 $output = $assign->get_renderer()->render($gradingtable);
270 $document = new DOMDocument();
271 $document->loadHTML($output);
272 $xpath = new DOMXPath($document);
273
274 // Check status.
275 $this->assertSame(get_string('submissionstatus_submitted', 'assign'), $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c4"]/div[@class="submissionstatussubmitted"])'));
276 $this->assertSame(get_string('submissionstatus_submitted', 'assign'), $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c4"]/div[@class="submissionstatussubmitted"])'));
277
278 // Check submission last modified date
279 $this->assertGreaterThan(0, strtotime($xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c8"])')));
280 $this->assertGreaterThan(0, strtotime($xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c8"])')));
281
282 // Check group.
283 $this->assertSame($this->groups[0]->name, $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c5"])'));
284 $this->assertSame($this->groups[0]->name, $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c5"])'));
285
286 // Check submission text.
287 $this->assertSame('Submission text', $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c9"]/div/div)'));
288 $this->assertSame('Submission text', $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c9"]/div/div)'));
289
290 // Check comments can be made.
291 $this->assertSame(1, (int)$xpath->evaluate('count(//td[@id="mod_assign_grading_r0_c10"]//textarea)'));
292 $this->assertSame(1, (int)$xpath->evaluate('count(//td[@id="mod_assign_grading_r3_c10"]//textarea)'));
293 }
294
47f48152
DW
295 public function test_show_intro() {
296 // Test whether we are showing the intro at the correct times.
297 $this->setUser($this->editingteachers[0]);
298 $assign = $this->create_instance(array('alwaysshowdescription'=>1));
299
300 $this->assertEquals(true, $assign->testable_show_intro());
301
302 $tomorrow = time() + (24*60*60);
303
304 $assign = $this->create_instance(array('alwaysshowdescription'=>0,
305 'allowsubmissionsfromdate'=>$tomorrow));
306 $this->assertEquals(false, $assign->testable_show_intro());
307 $yesterday = time() - (24*60*60);
308 $assign = $this->create_instance(array('alwaysshowdescription'=>0,
309 'allowsubmissionsfromdate'=>$yesterday));
310 $this->assertEquals(true, $assign->testable_show_intro());
311 }
312
313 public function test_has_submissions_or_grades() {
314 $this->setUser($this->editingteachers[0]);
315 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
316
317 $instance = $assign->get_instance();
318
319 // Should start empty.
320 $this->assertEquals(false, $assign->has_submissions_or_grades());
321
322 // Simulate a submission.
323 $this->setUser($this->students[0]);
324 $submission = $assign->get_user_submission($this->students[0]->id, true);
ab14ab74
FM
325
326 // The submission is still new.
327 $this->assertEquals(false, $assign->has_submissions_or_grades());
328
329 // Submit the submission.
330 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
331 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
47f48152
DW
332 $data = new stdClass();
333 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
334 'text'=>'Submission text',
335 'format'=>FORMAT_MOODLE);
336 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
337 $plugin->save($submission, $data);
338
339 // Now test again.
340 $this->assertEquals(true, $assign->has_submissions_or_grades());
341 // Set this back to default.
342 $this->students[0]->ignoresesskey = false;
343 }
344
345 public function test_delete_grades() {
346 $this->setUser($this->editingteachers[0]);
347 $assign = $this->create_instance();
348
349 // Simulate adding a grade.
350 $this->setUser($this->teachers[0]);
351 $data = new stdClass();
352 $data->grade = '50.0';
df211804 353 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
354
355 // Now see if the data is in the gradebook.
356 $gradinginfo = grade_get_grades($this->course->id,
357 'mod',
358 'assign',
359 $assign->get_instance()->id);
360
361 $this->assertNotEquals(0, count($gradinginfo->items));
362
363 $assign->testable_delete_grades();
364 $gradinginfo = grade_get_grades($this->course->id,
365 'mod',
366 'assign',
367 $assign->get_instance()->id);
368
369 $this->assertEquals(0, count($gradinginfo->items));
370 }
371
372 public function test_delete_instance() {
373 $this->setUser($this->editingteachers[0]);
374 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
375
376 // Simulate adding a grade.
377 $this->setUser($this->teachers[0]);
378 $data = new stdClass();
379 $data->grade = '50.0';
df211804 380 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
381
382 // Simulate a submission.
383 $this->setUser($this->students[0]);
384 $submission = $assign->get_user_submission($this->students[0]->id, true);
385 $data = new stdClass();
386 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
387 'text'=>'Submission text',
388 'format'=>FORMAT_MOODLE);
389 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
390 $plugin->save($submission, $data);
391
392 // Now try and delete.
393 $this->assertEquals(true, $assign->delete_instance());
394 }
395
396 public function test_reset_userdata() {
397 global $DB;
398
399 $now = time();
400 $this->setUser($this->editingteachers[0]);
401 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1,
402 'duedate'=>$now));
403
404 // Simulate adding a grade.
405 $this->setUser($this->teachers[0]);
406 $data = new stdClass();
407 $data->grade = '50.0';
df211804 408 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
409
410 // Simulate a submission.
411 $this->setUser($this->students[0]);
412 $submission = $assign->get_user_submission($this->students[0]->id, true);
413 $data = new stdClass();
414 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
415 'text'=>'Submission text',
416 'format'=>FORMAT_MOODLE);
417 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
418 $plugin->save($submission, $data);
419
420 $this->assertEquals(true, $assign->has_submissions_or_grades());
421 // Now try and reset.
422 $data = new stdClass();
423 $data->reset_assign_submissions = 1;
424 $data->reset_gradebook_grades = 1;
425 $data->courseid = $this->course->id;
426 $data->timeshift = 24*60*60;
427 $this->setUser($this->editingteachers[0]);
428 $assign->reset_userdata($data);
429 $this->assertEquals(false, $assign->has_submissions_or_grades());
430
431 // Reload the instance data.
432 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
433 $this->assertEquals($now + 24*60*60, $instance->duedate);
e63515ba
RT
434
435 // Test reset using assign_reset_userdata().
436 $assignduedate = $instance->duedate; // Keep old updated value for comparison.
437 $data->timeshift = 2*24*60*60;
438 assign_reset_userdata($data);
439 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id));
440 $this->assertEquals($assignduedate + 2*24*60*60, $instance->duedate);
441
442 // Create one more assignment and reset, make sure time shifted for previous assignment is not changed.
443 $assign2 = $this->create_instance(array('assignsubmission_onlinetext_enabled' => 1,
444 'duedate' => $now));
445 $assignduedate = $instance->duedate;
446 $data->timeshift = 3*24*60*60;
447 $assign2->reset_userdata($data);
448 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id));
449 $this->assertEquals($assignduedate, $instance->duedate);
450 $instance2 = $DB->get_record('assign', array('id' => $assign2->get_instance()->id));
451 $this->assertEquals($now + 3*24*60*60, $instance2->duedate);
452
453 // Reset both assignments using assign_reset_userdata() and make sure both assignments have same date.
454 $assignduedate = $instance->duedate;
455 $assign2duedate = $instance2->duedate;
456 $data->timeshift = 4*24*60*60;
457 assign_reset_userdata($data);
458 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id));
459 $this->assertEquals($assignduedate + 4*24*60*60, $instance->duedate);
460 $instance2 = $DB->get_record('assign', array('id' => $assign2->get_instance()->id));
461 $this->assertEquals($assign2duedate + 4*24*60*60, $instance2->duedate);
47f48152
DW
462 }
463
464 public function test_plugin_settings() {
465 global $DB;
466
467 $now = time();
468 $this->setUser($this->editingteachers[0]);
469 $assign = $this->create_instance(array('assignsubmission_file_enabled'=>1,
470 'assignsubmission_file_maxfiles'=>12,
471 'assignsubmission_file_maxsizebytes'=>10));
472
473 $plugin = $assign->get_submission_plugin_by_type('file');
474 $this->assertEquals('12', $plugin->get_config('maxfilesubmissions'));
475 }
476
477 public function test_update_calendar() {
478 global $DB;
479
47f48152 480 $this->setUser($this->editingteachers[0]);
f588ea50
FM
481 $userctx = context_user::instance($this->editingteachers[0]->id)->id;
482
483 // Hack to pretend that there was an editor involved. We need both $_POST and $_REQUEST, and a sesskey.
484 $draftid = file_get_unused_draft_itemid();
485 $_REQUEST['introeditor'] = $draftid;
486 $_POST['introeditor'] = $draftid;
487 $_POST['sesskey'] = sesskey();
488
489 // Write links to a draft area.
490 $fakearealink1 = file_rewrite_pluginfile_urls('<a href="@@PLUGINFILE@@/pic.gif">link</a>', 'draftfile.php', $userctx,
491 'user', 'draft', $draftid);
492 $fakearealink2 = file_rewrite_pluginfile_urls('<a href="@@PLUGINFILE@@/pic.gif">new</a>', 'draftfile.php', $userctx,
493 'user', 'draft', $draftid);
494
495 // Create a new assignment with links to a draft area.
496 $now = time();
497 $assign = $this->create_instance(array(
498 'duedate' => $now,
499 'intro' => $fakearealink1,
500 'introformat' => FORMAT_HTML
501 ));
47f48152
DW
502
503 // See if there is an event in the calendar.
504 $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id);
f588ea50
FM
505 $event = $DB->get_record('event', $params);
506 $this->assertNotEmpty($event);
507 $this->assertSame('link', $event->description); // The pluginfile links are removed.
47f48152 508
f588ea50
FM
509 // Make sure the same works when updating the assignment.
510 $instance = $assign->get_instance();
511 $instance->instance = $instance->id;
512 $instance->intro = $fakearealink2;
513 $instance->introformat = FORMAT_HTML;
514 $assign->update_instance($instance);
515 $params = array('modulename' => 'assign', 'instance' => $assign->get_instance()->id);
516 $event = $DB->get_record('event', $params);
517 $this->assertNotEmpty($event);
518 $this->assertSame('new', $event->description); // The pluginfile links are removed.
ae7638f7
DW
519
520 // Create an assignment with a description that should be hidden.
521 $assign = $this->create_instance(array('duedate'=>$now + 160,
522 'alwaysshowdescription'=>false,
8112670d 523 'allowsubmissionsfromdate'=>$now + 60,
ae7638f7
DW
524 'intro'=>'Some text'));
525
526 // Get the event from the calendar.
527 $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id);
528 $event = $DB->get_record('event', $params);
529
530 $this->assertEmpty($event->description);
8112670d
DW
531
532 // Change the allowsubmissionfromdate to the past - do this directly in the DB
533 // because if we call the assignment update method - it will update the calendar
534 // and we want to test that this works from cron.
535 $DB->set_field('assign', 'allowsubmissionsfromdate', $now - 60, array('id'=>$assign->get_instance()->id));
ae7638f7
DW
536 // Run cron to update the event in the calendar.
537 assign::cron();
538 $event = $DB->get_record('event', $params);
539
540 $this->assertContains('Some text', $event->description);
541
47f48152
DW
542 }
543
544 public function test_update_instance() {
545 global $DB;
546
547 $this->setUser($this->editingteachers[0]);
548 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
549
550 $now = time();
551 $instance = $assign->get_instance();
552 $instance->duedate = $now;
553 $instance->instance = $instance->id;
554 $instance->assignsubmission_onlinetext_enabled = 1;
47f48152
DW
555
556 $assign->update_instance($instance);
557
558 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
559 $this->assertEquals($now, $instance->duedate);
560 }
561
8fd00a24
DW
562 public function test_cannot_submit_empty() {
563 global $PAGE;
564
565 $this->setUser($this->editingteachers[0]);
566 $assign = $this->create_instance(array('submissiondrafts'=>1));
567
568 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
569
570 // Test you cannot see the submit button for an offline assignment regardless.
571 $this->setUser($this->students[0]);
572 $output = $assign->view_student_summary($this->students[0], true);
573 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Can submit empty offline assignment');
574
575 // Test you cannot see the submit button for an online text assignment with no submission.
576 $this->setUser($this->editingteachers[0]);
577 $instance = $assign->get_instance();
578 $instance->instance = $instance->id;
579 $instance->assignsubmission_onlinetext_enabled = 1;
580
581 $assign->update_instance($instance);
582 $this->setUser($this->students[0]);
583 $output = $assign->view_student_summary($this->students[0], true);
584 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Cannot submit empty onlinetext assignment');
585
586 // Simulate a submission.
587 $submission = $assign->get_user_submission($this->students[0]->id, true);
588 $data = new stdClass();
589 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
590 'text'=>'Submission text',
591 'format'=>FORMAT_MOODLE);
592 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
593 $plugin->save($submission, $data);
594 // Test you can see the submit button for an online text assignment with a submission.
595 $output = $assign->view_student_summary($this->students[0], true);
596 $this->assertContains(get_string('submitassignment', 'assign'), $output, 'Can submit non empty onlinetext assignment');
597 }
598
47f48152 599 public function test_list_participants() {
c13ac85d 600 global $CFG, $DB;
601
df211804 602 $this->create_extra_users();
47f48152
DW
603 $this->setUser($this->editingteachers[0]);
604 $assign = $this->create_instance(array('grade'=>100));
605
a5c793c3 606 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true)));
e6cc5347
RT
607
608 // Teacher with user preference set should see suspended users as well.
609 set_user_preference('grade_report_showonlyactiveenrol', false);
610 $assign = $this->create_instance(array('grade'=>100));
611 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT,
612 count($assign->list_participants(null, true)));
613
1ecb8044 614 // Non-editing teacher should not see suspended users, even if user preference is set.
e6cc5347
RT
615 $this->setUser($this->teachers[0]);
616 set_user_preference('grade_report_showonlyactiveenrol', false);
617 $assign = $this->create_instance(array('grade'=>100));
618 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true)));
c13ac85d 619
620 // Turn on availability and a group restriction, and check that it doesn't
621 // show users who aren't in the group.
622 $CFG->enableavailability = true;
623 $specialgroup = $this->getDataGenerator()->create_group(
624 array('courseid' => $this->course->id));
625 $assign = $this->create_instance(array('grade' => 100,
626 'availability' => json_encode(\core_availability\tree::get_root_json(
627 array(\availability_group\condition::get_json($specialgroup->id))))));
628 groups_add_member($specialgroup, $this->students[0]);
629 groups_add_member($specialgroup, $this->students[1]);
630 $this->assertEquals(2, count($assign->list_participants(null, true)));
47f48152
DW
631 }
632
633 public function test_count_teams() {
df211804 634 $this->create_extra_users();
47f48152
DW
635 $this->setUser($this->editingteachers[0]);
636 $assign = $this->create_instance(array('teamsubmission'=>1));
637
a5c793c3 638 $this->assertEquals(self::GROUP_COUNT + 1, $assign->count_teams());
47f48152
DW
639 }
640
e2d2d8a1
DW
641 public function test_submit_to_default_group() {
642 global $DB;
643
644 $this->preventResetByRollback();
645 $sink = $this->redirectMessages();
646
647 $this->setUser($this->editingteachers[0]);
648 $params = array('teamsubmission' => 1,
649 'assignsubmission_onlinetext_enabled' => 1,
650 'submissiondrafts'=>0);
651 $assign = $this->create_instance($params);
652
653 $newstudent = $this->getDataGenerator()->create_user();
654 $studentrole = $DB->get_record('role', array('shortname'=>'student'));
655 $this->getDataGenerator()->enrol_user($newstudent->id,
656 $this->course->id,
657 $studentrole->id);
658 $this->setUser($newstudent);
659 $data = new stdClass();
660 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
661 'text'=>'Submission text',
662 'format'=>FORMAT_MOODLE);
663 $notices = array();
664
665 $group = $assign->get_submission_group($newstudent->id);
666 $this->assertFalse($group, 'New student is in default group');
667 $assign->save_submission($data, $notices);
668 $this->assertEmpty($notices, 'No errors on save submission');
669
670 $sink->close();
671 }
672
47f48152 673 public function test_count_submissions() {
df211804 674 $this->create_extra_users();
47f48152
DW
675 $this->setUser($this->editingteachers[0]);
676 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
677
678 // Simulate a submission.
a5c793c3
DW
679 $this->setUser($this->extrastudents[0]);
680 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
9e3eee67
DW
681 $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
682 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
47f48152
DW
683 // Leave this one as DRAFT.
684 $data = new stdClass();
685 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
686 'text'=>'Submission text',
687 'format'=>FORMAT_MOODLE);
688 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
689 $plugin->save($submission, $data);
690
691 // Simulate adding a grade.
692 $this->setUser($this->teachers[0]);
693 $data = new stdClass();
694 $data->grade = '50.0';
df211804 695 $assign->testable_apply_grade_to_user($data, $this->extrastudents[0]->id, 0);
47f48152
DW
696
697 // Simulate a submission.
a5c793c3
DW
698 $this->setUser($this->extrastudents[1]);
699 $submission = $assign->get_user_submission($this->extrastudents[1]->id, true);
47f48152 700 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 701 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, false);
47f48152
DW
702 $data = new stdClass();
703 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
704 'text'=>'Submission text',
705 'format'=>FORMAT_MOODLE);
706 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
707 $plugin->save($submission, $data);
708
709 // Simulate a submission.
a5c793c3
DW
710 $this->setUser($this->extrastudents[2]);
711 $submission = $assign->get_user_submission($this->extrastudents[2]->id, true);
47f48152 712 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 713 $assign->testable_update_submission($submission, $this->extrastudents[2]->id, true, false);
47f48152
DW
714 $data = new stdClass();
715 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
716 'text'=>'Submission text',
717 'format'=>FORMAT_MOODLE);
718 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
719 $plugin->save($submission, $data);
720
721 // Simulate a submission.
a5c793c3
DW
722 $this->setUser($this->extrastudents[3]);
723 $submission = $assign->get_user_submission($this->extrastudents[3]->id, true);
47f48152 724 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
a5c793c3 725 $assign->testable_update_submission($submission, $this->extrastudents[3]->id, true, false);
47f48152
DW
726 $data = new stdClass();
727 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
728 'text'=>'Submission text',
729 'format'=>FORMAT_MOODLE);
730 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
731 $plugin->save($submission, $data);
732
e6cc5347
RT
733 // Simulate a submission for suspended user, this will never be counted.
734 $this->setUser($this->extrastudents[3]);
735 $submission = $assign->get_user_submission($this->extrasuspendedstudents[0]->id, true);
736 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
737 $assign->testable_update_submission($submission, $this->extrasuspendedstudents[0]->id, true, false);
738 $data = new stdClass();
739 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
740 'text'=>'Submission text',
741 'format'=>FORMAT_MOODLE);
742 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
743 $plugin->save($submission, $data);
744
47f48152
DW
745 // Simulate adding a grade.
746 $this->setUser($this->teachers[0]);
747 $data = new stdClass();
748 $data->grade = '50.0';
df211804 749 $assign->testable_apply_grade_to_user($data, $this->extrastudents[3]->id, 0);
e6cc5347 750 $assign->testable_apply_grade_to_user($data, $this->extrasuspendedstudents[0]->id, 0);
47f48152 751
ab14ab74
FM
752 // Create a new submission with status NEW.
753 $this->setUser($this->extrastudents[4]);
754 $submission = $assign->get_user_submission($this->extrastudents[4]->id, true);
755
47f48152
DW
756 $this->assertEquals(2, $assign->count_grades());
757 $this->assertEquals(4, $assign->count_submissions());
ab14ab74 758 $this->assertEquals(5, $assign->count_submissions(true));
47f48152
DW
759 $this->assertEquals(2, $assign->count_submissions_need_grading());
760 $this->assertEquals(3, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED));
761 $this->assertEquals(1, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT));
762 }
763
ab14ab74
FM
764 public function test_count_submissions_for_groups() {
765 $this->create_extra_users();
766 $groupid = null;
767 $this->setUser($this->editingteachers[0]);
768 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled' => 1, 'teamsubmission' => 1));
769
770 // Simulate a submission.
771 $this->setUser($this->extrastudents[0]);
772 $submission = $assign->get_group_submission($this->extrastudents[0]->id, $groupid, true);
773 $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
774 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
775 // Leave this one as DRAFT.
776 $data = new stdClass();
777 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
778 'text' => 'Submission text',
779 'format' => FORMAT_MOODLE);
780 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
781 $plugin->save($submission, $data);
782
783 // Simulate adding a grade.
784 $this->setUser($this->teachers[0]);
785 $data = new stdClass();
786 $data->grade = '50.0';
787 $assign->testable_apply_grade_to_user($data, $this->extrastudents[0]->id, 0);
788
789 // Simulate a submission.
790 $this->setUser($this->extrastudents[1]);
791 $submission = $assign->get_group_submission($this->extrastudents[1]->id, $groupid, true);
792 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
793 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, false);
794 $data = new stdClass();
795 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
796 'text' => 'Submission text',
797 'format' => FORMAT_MOODLE);
798 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
799 $plugin->save($submission, $data);
800
801 // Simulate a submission.
802 $this->setUser($this->extrastudents[2]);
803 $submission = $assign->get_group_submission($this->extrastudents[2]->id, $groupid, true);
804 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
805 $assign->testable_update_submission($submission, $this->extrastudents[2]->id, true, false);
806 $data = new stdClass();
807 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
808 'text' => 'Submission text',
809 'format' => FORMAT_MOODLE);
810 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
811 $plugin->save($submission, $data);
812
813 // Simulate a submission.
814 $this->setUser($this->extrastudents[3]);
815 $submission = $assign->get_group_submission($this->extrastudents[3]->id, $groupid, true);
816 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
817 $assign->testable_update_submission($submission, $this->extrastudents[3]->id, true, false);
818 $data = new stdClass();
819 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
820 'text' => 'Submission text',
821 'format' => FORMAT_MOODLE);
822 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
823 $plugin->save($submission, $data);
824
825 // Simulate adding a grade.
826 $this->setUser($this->teachers[0]);
827 $data = new stdClass();
828 $data->grade = '50.0';
829 $assign->testable_apply_grade_to_user($data, $this->extrastudents[3]->id, 0);
830 $assign->testable_apply_grade_to_user($data, $this->extrasuspendedstudents[0]->id, 0);
831
832 // Create a new submission with status NEW.
833 $this->setUser($this->extrastudents[4]);
834 $submission = $assign->get_group_submission($this->extrastudents[4]->id, $groupid, true);
835
836 $this->assertEquals(2, $assign->count_grades());
837 $this->assertEquals(4, $assign->count_submissions());
838 $this->assertEquals(5, $assign->count_submissions(true));
839 $this->assertEquals(3, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED));
840 $this->assertEquals(1, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT));
841 }
842
47f48152 843 public function test_get_grading_userid_list() {
df211804 844 $this->create_extra_users();
47f48152
DW
845 $this->setUser($this->editingteachers[0]);
846 $assign = $this->create_instance();
847
848 $users = $assign->testable_get_grading_userid_list();
a5c793c3 849 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($users));
e6cc5347
RT
850
851 $this->setUser($this->editingteachers[0]);
852 set_user_preference('grade_report_showonlyactiveenrol', false);
853 $assign = $this->create_instance();
854
855 $users = $assign->testable_get_grading_userid_list();
856 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT, count($users));
47f48152
DW
857 }
858
859 public function test_cron() {
860 // First run cron so there are no messages waiting to be sent (from other tests).
861 cron_setup_user();
862 assign::cron();
863
864 // Now create an assignment and add some feedback.
865 $this->setUser($this->editingteachers[0]);
8e1266bf 866 $assign = $this->create_instance(array('sendstudentnotifications'=>1));
47f48152
DW
867
868 // Simulate adding a grade.
869 $this->setUser($this->teachers[0]);
870 $data = new stdClass();
871 $data->grade = '50.0';
df211804 872 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
4d2bd673 873 $assign->testable_apply_grade_to_user($data, $this->students[1]->id, 0);
47f48152 874
f7dc9871
DW
875 $data->sendstudentnotifications = false;
876 $assign->testable_apply_grade_to_user($data, $this->students[2]->id, 0);
877
47f48152
DW
878 // Now run cron and see that one message was sent.
879 $this->preventResetByRollback();
880 $sink = $this->redirectMessages();
881 cron_setup_user();
4d2bd673 882 $this->expectOutputRegex('/Done processing 2 assignment submissions/');
47f48152
DW
883 assign::cron();
884
885 $messages = $sink->get_messages();
f7dc9871 886 // The sent count should be 2, because the 3rd one was marked as do not send notifications.
4d2bd673 887 $this->assertEquals(2, count($messages));
47f48152
DW
888 $this->assertEquals(1, $messages[0]->notification);
889 $this->assertEquals($assign->get_instance()->name, $messages[0]->contexturlname);
890 }
891
892 public function test_is_graded() {
893 $this->setUser($this->editingteachers[0]);
894 $assign = $this->create_instance();
895
896 // Simulate adding a grade.
897 $this->setUser($this->teachers[0]);
898 $data = new stdClass();
899 $data->grade = '50.0';
df211804 900 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
47f48152
DW
901
902 $this->assertEquals(true, $assign->testable_is_graded($this->students[0]->id));
903 $this->assertEquals(false, $assign->testable_is_graded($this->students[1]->id));
904 }
905
4a47008c
DW
906 public function test_can_grade() {
907 global $DB;
908
909 $this->setUser($this->editingteachers[0]);
910 $assign = $this->create_instance();
911
912 $this->setUser($this->students[0]);
913 $this->assertEquals(false, $assign->can_grade());
914 $this->setUser($this->editingteachers[0]);
915 $this->assertEquals(true, $assign->can_grade());
916 $this->setUser($this->teachers[0]);
917 $this->assertEquals(true, $assign->can_grade());
918
919 // Test the viewgrades capability - without mod/assign:grade.
920 $this->setUser($this->students[0]);
921 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
922 assign_capability('mod/assign:viewgrades', CAP_ALLOW, $studentrole->id, $assign->get_context()->id);
923 $this->assertEquals(false, $assign->can_grade());
924 }
925
47f48152 926 public function test_can_view_submission() {
4a47008c
DW
927 global $DB;
928
e6cc5347 929 $this->create_extra_users();
47f48152
DW
930 $this->setUser($this->editingteachers[0]);
931 $assign = $this->create_instance();
932
933 $this->setUser($this->students[0]);
934 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
935 $this->assertEquals(false, $assign->can_view_submission($this->students[1]->id));
936 $this->assertEquals(false, $assign->can_view_submission($this->teachers[0]->id));
937 $this->setUser($this->teachers[0]);
938 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
939 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
940 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
e6cc5347 941 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
47f48152
DW
942 $this->setUser($this->editingteachers[0]);
943 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
944 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
945 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
e6cc5347 946 $this->assertEquals(true, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
4a47008c
DW
947
948 // Test the viewgrades capability - without mod/assign:grade.
949 $this->setUser($this->students[0]);
950 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
951 assign_capability('mod/assign:viewgrades', CAP_ALLOW, $studentrole->id, $assign->get_context()->id);
952 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
953 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
954 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
955 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id));
47f48152
DW
956 }
957
958
959 public function test_update_submission() {
df211804 960 $this->create_extra_users();
47f48152
DW
961 $this->setUser($this->editingteachers[0]);
962 $assign = $this->create_instance();
963
a5c793c3 964 $this->setUser($this->extrastudents[0]);
47f48152 965 $now = time();
a5c793c3
DW
966 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
967 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
47f48152
DW
968
969 $this->setUser($this->teachers[0]);
970 // Verify the gradebook update.
971 $gradinginfo = grade_get_grades($this->course->id,
972 'mod',
973 'assign',
974 $assign->get_instance()->id,
a5c793c3 975 $this->extrastudents[0]->id);
47f48152 976
a5c793c3
DW
977 $this->assertEquals($this->extrastudents[0]->id,
978 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
47f48152
DW
979
980 // Now verify group assignments.
981 $this->setUser($this->editingteachers[0]);
982 $assign = $this->create_instance(array('teamsubmission'=>1));
983
a5c793c3 984 $this->setUser($this->extrastudents[0]);
47f48152 985 $now = time();
a5c793c3
DW
986 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
987 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
47f48152 988
e6cc5347 989 // Check that at least 2 active members and 1 suspended member of the submission group had their submission updated.
47f48152
DW
990
991 $this->setUser($this->editingteachers[0]);
992 $gradinginfo = grade_get_grades($this->course->id,
993 'mod',
994 'assign',
995 $assign->get_instance()->id,
a5c793c3 996 $this->extrastudents[0]->id);
47f48152 997
a5c793c3
DW
998 $this->assertEquals($this->extrastudents[0]->id,
999 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified);
47f48152
DW
1000
1001 $gradinginfo = grade_get_grades($this->course->id,
1002 'mod',
1003 'assign',
1004 $assign->get_instance()->id,
a5c793c3 1005 $this->extrastudents[self::GROUP_COUNT]->id);
47f48152 1006
a5c793c3
DW
1007 $this->assertEquals($this->extrastudents[self::GROUP_COUNT]->id,
1008 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT]->id]->usermodified);
47f48152 1009
e6cc5347
RT
1010 $gradinginfo = grade_get_grades($this->course->id,
1011 'mod',
1012 'assign',
1013 $assign->get_instance()->id,
1014 $this->extrasuspendedstudents[0]->id);
1015 $this->assertEquals($this->extrasuspendedstudents[0]->id,
1016 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[0]->id]->usermodified);
1017
1018 // Check the same with non-editing teacher and make sure submission is not updated for suspended user.
1019 $this->setUser($this->editingteachers[0]);
1020 $assign = $this->create_instance(array('teamsubmission'=>1));
1021
1022 $this->setUser($this->extrastudents[1]);
1023 $now = time();
1024 $submission = $assign->get_group_submission($this->extrastudents[1]->id, 0, true);
1025 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, true);
1026
1027 $this->setUser($this->teachers[0]);
1028 $gradinginfo = grade_get_grades($this->course->id,
1029 'mod',
1030 'assign',
1031 $assign->get_instance()->id,
1032 $this->extrastudents[1]->id);
1033
1034 $this->assertEquals($this->extrastudents[1]->id,
1035 $gradinginfo->items[0]->grades[$this->extrastudents[1]->id]->usermodified);
1036
1037 $gradinginfo = grade_get_grades($this->course->id,
1038 'mod',
1039 'assign',
1040 $assign->get_instance()->id,
1041 $this->extrastudents[self::GROUP_COUNT+1]->id);
1042
1043 $this->assertEquals($this->extrastudents[self::GROUP_COUNT+1]->id,
1044 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT+1]->id]->usermodified);
1045
1046 $gradinginfo = grade_get_grades($this->course->id,
1047 'mod',
1048 'assign',
1049 $assign->get_instance()->id,
1050 $this->extrasuspendedstudents[1]->id);
1051 $this->assertEquals($this->extrasuspendedstudents[1]->id,
1052 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[1]->id]->usermodified);
1053
47f48152
DW
1054 // Now verify blind marking.
1055 $this->setUser($this->editingteachers[0]);
1056 $assign = $this->create_instance(array('blindmarking'=>1));
1057
a5c793c3 1058 $this->setUser($this->extrastudents[0]);
47f48152 1059 $now = time();
a5c793c3
DW
1060 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true);
1061 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false);
47f48152
DW
1062
1063 $this->setUser($this->editingteachers[0]);
1064 $gradinginfo = grade_get_grades($this->course->id,
1065 'mod',
1066 'assign',
1067 $assign->get_instance()->id,
a5c793c3 1068 $this->extrastudents[0]->id);
47f48152 1069
a5c793c3 1070 $this->assertEquals(null, $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->datesubmitted);
47f48152
DW
1071 }
1072
79397b56 1073 public function test_group_submissions_submit_for_marking_requireallteammemberssubmit() {
2bd27878
DW
1074 global $PAGE;
1075
1076 $this->create_extra_users();
1077 // Now verify group assignments.
1078 $this->setUser($this->editingteachers[0]);
1079 $assign = $this->create_instance(array('teamsubmission'=>1,
1080 'assignsubmission_onlinetext_enabled'=>1,
1081 'submissiondrafts'=>1,
1082 'requireallteammemberssubmit'=>1));
1083 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1084
2bd27878 1085 // Add a submission.
79397b56 1086 $this->setUser($this->extrastudents[0]);
2bd27878
DW
1087 $data = new stdClass();
1088 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1089 'text'=>'Submission text',
1090 'format'=>FORMAT_MOODLE);
1091
1092 $notices = array();
1093 $assign->save_submission($data, $notices);
1094
1095 // Check we can see the submit button.
1096 $output = $assign->view_student_summary($this->extrastudents[0], true);
1097 $this->assertContains(get_string('submitassignment', 'assign'), $output);
1098
1099 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
1100 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1101 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
1102
1103 // Check that the student does not see "Submit" button.
1104 $output = $assign->view_student_summary($this->extrastudents[0], true);
1105 $this->assertNotContains(get_string('submitassignment', 'assign'), $output);
1106
1107 // Change to another user in the same group.
1108 $this->setUser($this->extrastudents[self::GROUP_COUNT]);
1109 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true);
1110 $this->assertContains(get_string('submitassignment', 'assign'), $output);
1111
1112 $submission = $assign->get_group_submission($this->extrastudents[self::GROUP_COUNT]->id, 0, true);
1113 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1114 $assign->testable_update_submission($submission, $this->extrastudents[self::GROUP_COUNT]->id, true, true);
1115 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true);
1116 $this->assertNotContains(get_string('submitassignment', 'assign'), $output);
1117 }
1118
79397b56
DB
1119 public function test_group_submissions_submit_for_marking() {
1120 global $PAGE;
1121
1122 $this->create_extra_users();
1123 // Now verify group assignments.
1124 $this->setUser($this->editingteachers[0]);
a0f8db77 1125 $time = time();
79397b56
DB
1126 $assign = $this->create_instance(array('teamsubmission'=>1,
1127 'assignsubmission_onlinetext_enabled'=>1,
1128 'submissiondrafts'=>1,
1129 'requireallteammemberssubmit'=>0,
a0f8db77 1130 'duedate' => $time - 2*24*60*60));
79397b56
DB
1131 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1132
1133 $this->setUser($this->extrastudents[0]);
1134 // Add a submission.
1135 $data = new stdClass();
1136 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1137 'text'=>'Submission text',
1138 'format'=>FORMAT_MOODLE);
1139
1140 $notices = array();
1141 $assign->save_submission($data, $notices);
1142
1143 // Check we can see the submit button.
1144 $output = $assign->view_student_summary($this->extrastudents[0], true);
1145 $this->assertContains(get_string('submitassignment', 'assign'), $output);
1146 $this->assertContains(get_string('timeremaining', 'assign'), $output);
a0f8db77
DW
1147 $difftime = time() - $time;
1148 $this->assertContains(get_string('overdue', 'assign', format_time(2*24*60*60 + $difftime)), $output);
79397b56
DB
1149
1150 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true);
1151 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1152 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true);
1153
1154 // Check that the student does not see "Submit" button.
1155 $output = $assign->view_student_summary($this->extrastudents[0], true);
1156 $this->assertNotContains(get_string('submitassignment', 'assign'), $output);
1157
1158 // Change to another user in the same group.
1159 $this->setUser($this->extrastudents[self::GROUP_COUNT]);
1160 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true);
1161 $this->assertNotContains(get_string('submitassignment', 'assign'), $output);
1162
1163 // Check that time remaining is not overdue.
1164 $this->assertContains(get_string('timeremaining', 'assign'), $output);
a0f8db77
DW
1165 $difftime = time() - $time;
1166 $this->assertContains(get_string('submittedlate', 'assign', format_time(2*24*60*60 + $difftime)), $output);
79397b56
DB
1167
1168 $submission = $assign->get_group_submission($this->extrastudents[self::GROUP_COUNT]->id, 0, true);
1169 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1170 $assign->testable_update_submission($submission, $this->extrastudents[self::GROUP_COUNT]->id, true, true);
1171 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true);
1172 $this->assertNotContains(get_string('submitassignment', 'assign'), $output);
1173 }
1174
47f48152
DW
1175 public function test_submissions_open() {
1176 $this->setUser($this->editingteachers[0]);
1177
1178 $now = time();
1179 $tomorrow = $now + 24*60*60;
1180 $oneweek = $now + 7*24*60*60;
1181 $yesterday = $now - 24*60*60;
1182
1183 $assign = $this->create_instance();
1184 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1185
1186 $assign = $this->create_instance(array('duedate'=>$tomorrow));
1187 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1188
1189 $assign = $this->create_instance(array('duedate'=>$yesterday));
1190 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1191
1192 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$tomorrow));
1193 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1194
1195 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$yesterday));
1196 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
1197
1198 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
1199 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1200
1201 $assign = $this->create_instance(array('submissiondrafts'=>1));
1202 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
1203
1204 $this->setUser($this->students[0]);
1205 $now = time();
1206 $submission = $assign->get_user_submission($this->students[0]->id, true);
1207 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1208 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1209 $this->setUser($this->editingteachers[0]);
1210 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
1211 }
1212
1213 public function test_get_graders() {
df211804 1214 $this->create_extra_users();
47f48152 1215 $this->setUser($this->editingteachers[0]);
47f48152 1216
f268fb5d
DW
1217 // Create an assignment with no groups.
1218 $assign = $this->create_instance();
a5c793c3
DW
1219 $this->assertCount(self::DEFAULT_TEACHER_COUNT +
1220 self::DEFAULT_EDITING_TEACHER_COUNT +
1221 self::EXTRA_TEACHER_COUNT +
1222 self::EXTRA_EDITING_TEACHER_COUNT,
1223 $assign->testable_get_graders($this->students[0]->id));
47f48152 1224
47f48152 1225 // Force create an assignment with SEPARATEGROUPS.
f268fb5d
DW
1226 $data = new stdClass();
1227 $data->courseid = $this->course->id;
1228 $data->name = 'Grouping';
1229 $groupingid = groups_create_grouping($data);
1230 groups_assign_grouping($groupingid, $this->groups[0]->id);
1231 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS));
47f48152
DW
1232
1233 $this->setUser($this->students[1]);
a5c793c3 1234 $this->assertCount(4, $assign->testable_get_graders($this->students[0]->id));
f268fb5d
DW
1235 // Note the second student is in a group that is not in the grouping.
1236 // This means that we get all graders that are not in a group in the grouping.
1237 $this->assertCount(10, $assign->testable_get_graders($this->students[1]->id));
47f48152
DW
1238 }
1239
83360c8d
S
1240 public function test_get_notified_users() {
1241 global $CFG, $DB;
1242
1243 $capability = 'mod/assign:receivegradernotifications';
1244 $coursecontext = context_course::instance($this->course->id);
1245 $role = $DB->get_record('role', array('shortname' => 'teacher'));
1246
1247 $this->create_extra_users();
1248 $this->setUser($this->editingteachers[0]);
1249
1250 // Create an assignment with no groups.
1251 $assign = $this->create_instance();
1252
1253 $this->assertCount(self::DEFAULT_TEACHER_COUNT +
1254 self::DEFAULT_EDITING_TEACHER_COUNT +
1255 self::EXTRA_TEACHER_COUNT +
1256 self::EXTRA_EDITING_TEACHER_COUNT,
1257 $assign->testable_get_notifiable_users($this->students[0]->id));
1258
1259 // Change nonediting teachers role to not receive grader notifications.
1260 assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext);
1261
1262 $this->assertCount(self::DEFAULT_EDITING_TEACHER_COUNT +
1263 self::EXTRA_EDITING_TEACHER_COUNT,
1264 $assign->testable_get_notifiable_users($this->students[0]->id));
1265
1266 // Reset nonediting teachers role to default.
1267 unassign_capability($capability, $role->id, $coursecontext);
1268
1269 // Force create an assignment with SEPARATEGROUPS.
1270 $data = new stdClass();
1271 $data->courseid = $this->course->id;
1272 $data->name = 'Grouping';
1273 $groupingid = groups_create_grouping($data);
1274 groups_assign_grouping($groupingid, $this->groups[0]->id);
1275 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS));
1276
1277 $this->setUser($this->students[1]);
1278 $this->assertCount(4, $assign->testable_get_notifiable_users($this->students[0]->id));
1279 // Note the second student is in a group that is not in the grouping.
1280 // This means that we get all graders that are not in a group in the grouping.
1281 $this->assertCount(10, $assign->testable_get_notifiable_users($this->students[1]->id));
1282
1283 // Change nonediting teachers role to not receive grader notifications.
1284 assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext);
1285
1286 $this->assertCount(2, $assign->testable_get_notifiable_users($this->students[0]->id));
1287 // Note the second student is in a group that is not in the grouping.
1288 // This means that we get all graders that are not in a group in the grouping.
1289 $this->assertCount(5, $assign->testable_get_notifiable_users($this->students[1]->id));
1290 }
1291
20b7dcfc
DW
1292 public function test_group_members_only() {
1293 global $CFG;
1294
1295 $this->setAdminUser();
1296 $this->create_extra_users();
c13ac85d 1297 $CFG->enableavailability = true;
20b7dcfc
DW
1298 $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $this->course->id));
1299 groups_assign_grouping($grouping->id, $this->groups[0]->id);
1300
1301 // Force create an assignment with SEPARATEGROUPS.
1302 $instance = $this->getDataGenerator()->create_module('assign', array('course'=>$this->course->id),
c13ac85d 1303 array('availability' => json_encode(\core_availability\tree::get_root_json(array(
1304 \availability_grouping\condition::get_json()))),
1305 'groupingid' => $grouping->id));
20b7dcfc
DW
1306
1307 $cm = get_coursemodule_from_instance('assign', $instance->id);
1308 $context = context_module::instance($cm->id);
1309 $assign = new testable_assign($context, $cm, $this->course);
1310
1311 $this->setUser($this->teachers[0]);
8270f0d0 1312 get_fast_modinfo($this->course, 0, true);
20b7dcfc
DW
1313 $this->assertCount(5, $assign->list_participants(0, true));
1314
1315 }
1316
47f48152
DW
1317 public function test_get_uniqueid_for_user() {
1318 $this->setUser($this->editingteachers[0]);
1319 $assign = $this->create_instance();
1320
1321 foreach ($this->students as $student) {
1322 $uniqueid = $assign->get_uniqueid_for_user($student->id);
1323 $this->assertEquals($student->id, $assign->get_user_id_for_uniqueid($uniqueid));
1324 }
1325 }
1326
46692c3a 1327 public function test_show_student_summary() {
c2114099 1328 global $CFG, $PAGE;
46692c3a
DW
1329
1330 $this->setUser($this->editingteachers[0]);
1331 $assign = $this->create_instance();
c2114099 1332 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
46692c3a
DW
1333
1334 // No feedback should be available because this student has not been graded.
1335 $this->setUser($this->students[0]);
1336 $output = $assign->view_student_summary($this->students[0], true);
1337 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if there is no grade');
1338 // Simulate adding a grade.
1339 $this->setUser($this->teachers[0]);
1340 $data = new stdClass();
1341 $data->grade = '50.0';
df211804 1342 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
46692c3a 1343
b0da618b 1344 // Now we should see the feedback.
46692c3a
DW
1345 $this->setUser($this->students[0]);
1346 $output = $assign->view_student_summary($this->students[0], true);
1347 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade');
1348
1349 // Now hide the grade in gradebook.
1350 $this->setUser($this->teachers[0]);
1351 require_once($CFG->libdir.'/gradelib.php');
1352 $gradeitem = new grade_item(array(
1353 'itemtype' => 'mod',
1354 'itemmodule' => 'assign',
1355 'iteminstance' => $assign->get_instance()->id,
1356 'courseid' => $this->course->id));
1357
1358 $gradeitem->set_hidden(1, false);
1359
1360 // No feedback should be available because the grade is hidden.
1361 $this->setUser($this->students[0]);
1362 $output = $assign->view_student_summary($this->students[0], true);
1363 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
1364
b0da618b 1365 // Do the same but add feedback.
46692c3a
DW
1366 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
1367
1368 $this->setUser($this->teachers[0]);
1369 $grade = $assign->get_user_grade($this->students[0]->id, true);
1370 $data = new stdClass();
1371 $data->assignfeedbackcomments_editor = array('text'=>'Tomato sauce',
1372 'format'=>FORMAT_MOODLE);
1373 $plugin = $assign->get_feedback_plugin_by_type('comments');
1374 $plugin->save($grade, $data);
1375
b0da618b 1376 // Should have feedback but no grade.
46692c3a
DW
1377 $this->setUser($this->students[0]);
1378 $output = $assign->view_student_summary($this->students[0], true);
ea698284 1379 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback even if there is no grade');
46692c3a
DW
1380 $this->assertEquals(false, strpos($output, 'Grade'), 'Do not show grade when there is no grade.');
1381 $this->assertEquals(false, strpos($output, 'Graded on'), 'Do not show graded date when there is no grade.');
45aac51a 1382
ea698284
AD
1383 // Now hide the grade in gradebook.
1384 $this->setUser($this->teachers[0]);
1385 $gradeitem = new grade_item(array(
1386 'itemtype' => 'mod',
1387 'itemmodule' => 'assign',
1388 'iteminstance' => $assign->get_instance()->id,
1389 'courseid' => $this->course->id));
1390
1391 $gradeitem->set_hidden(1, false);
1392
1393 // No feedback should be available because the grade is hidden.
1394 $this->setUser($this->students[0]);
1395 $output = $assign->view_student_summary($this->students[0], true);
1396 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
46692c3a
DW
1397 }
1398
df211804
DW
1399 public function test_attempt_reopen_method_manual() {
1400 global $PAGE;
1401
1402 $this->setUser($this->editingteachers[0]);
1403 $assign = $this->create_instance(array('attemptreopenmethod'=>ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
1404 'maxattempts'=>3,
1405 'submissiondrafts'=>1,
1406 'assignsubmission_onlinetext_enabled'=>1));
1407 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1408
1409 // Student should be able to see an add submission button.
1410 $this->setUser($this->students[0]);
1411 $output = $assign->view_student_summary($this->students[0], true);
1412 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1413
1414 // Add a submission.
1415 $now = time();
1416 $submission = $assign->get_user_submission($this->students[0]->id, true);
1417 $data = new stdClass();
1418 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1419 'text'=>'Submission text',
1420 'format'=>FORMAT_MOODLE);
1421 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1422 $plugin->save($submission, $data);
1423
1424 // And now submit it for marking.
1425 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1426 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1427
1428 // Verify the student cannot make changes to the submission.
1429 $output = $assign->view_student_summary($this->students[0], true);
1430 $this->assertEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1431
1432 // Mark the submission.
1433 $this->setUser($this->teachers[0]);
1434 $data = new stdClass();
1435 $data->grade = '50.0';
1436 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1437
1438 // Check the student can see the grade.
1439 $this->setUser($this->students[0]);
1440 $output = $assign->view_student_summary($this->students[0], true);
1441 $this->assertNotEquals(false, strpos($output, '50.0'));
1442
1443 // Allow the student another attempt.
1444 $this->teachers[0]->ignoresesskey = true;
1445 $this->setUser($this->teachers[0]);
1446 $result = $assign->testable_process_add_attempt($this->students[0]->id);
1447 $this->assertEquals(true, $result);
1448
1449 // Check that the previous attempt is now in the submission history table.
1450 $this->setUser($this->students[0]);
1451 $output = $assign->view_student_summary($this->students[0], true);
1452 // Need a better check.
1453 $this->assertNotEquals(false, strpos($output, 'Submission text'), 'Contains: Submission text');
1454
1455 // Check that the student now has a button for Add a new attempt".
1456 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1457 // Check that the student now does not have a button for Submit.
1458 $this->assertEquals(false, strpos($output, get_string('submitassignment', 'assign')));
1459
1460 // Check that the student now has a submission history.
1461 $this->assertNotEquals(false, strpos($output, get_string('attempthistory', 'assign')));
1462
1463 $this->setUser($this->teachers[0]);
1464 // Check that the grading table loads correctly and contains this user.
1465 // This is also testing that we do not get duplicate rows in the grading table.
1466 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
1467 $output = $assign->get_renderer()->render($gradingtable);
1468 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
1469
1470 // Should be 1 not 2.
1471 $this->assertEquals(1, $assign->count_submissions());
1472 $this->assertEquals(1, $assign->count_submissions_with_status('reopened'));
1473 $this->assertEquals(0, $assign->count_submissions_need_grading());
1474 $this->assertEquals(1, $assign->count_grades());
1475
1476 // Change max attempts to unlimited.
1477 $formdata = clone($assign->get_instance());
1478 $formdata->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS;
1479 $formdata->instance = $formdata->id;
1480 $assign->update_instance($formdata);
1481
9e3eee67
DW
1482 // Mark the submission again.
1483 $data = new stdClass();
1484 $data->grade = '60.0';
1485 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 1);
1486
1487 // Check the grade exists.
1488 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id);
1489 $this->assertEquals(60, (int)$grades[$this->students[0]->id]->rawgrade);
1490
1491 // Check we can reopen still.
df211804
DW
1492 $result = $assign->testable_process_add_attempt($this->students[0]->id);
1493 $this->assertEquals(true, $result);
1494
9e3eee67 1495 // Should no longer have a grade because there is no grade for the latest attempt.
df211804 1496 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id);
9e3eee67 1497 $this->assertEmpty($grades);
df211804 1498
df211804 1499 }
46692c3a 1500
e77bacab
MP
1501 /**
1502 * Test reopen behavior when in "Reopen until pass" mode.
1503 */
1504 public function test_attempt_reopen_method_untilpass() {
1505 global $PAGE;
1506
1507 $this->setUser($this->editingteachers[0]);
1508 $assign = $this->create_instance(array('attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_UNTILPASS,
1509 'maxattempts' => 3,
1510 'submissiondrafts' => 1,
1511 'assignsubmission_onlinetext_enabled' => 1));
1512 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1513
1514 // Set grade to pass to 80.
1515 $gradeitem = $assign->get_grade_item();
1516 $gradeitem->gradepass = '80.0';
1517 $gradeitem->update();
1518
1519 // Student should be able to see an add submission button.
1520 $this->setUser($this->students[0]);
1521 $output = $assign->view_student_summary($this->students[0], true);
1522 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1523
1524 // Add a submission.
1525 $now = time();
1526 $submission = $assign->get_user_submission($this->students[0]->id, true);
1527 $data = new stdClass();
1528 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
1529 'text' => 'Submission text',
1530 'format' => FORMAT_MOODLE);
1531 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1532 $plugin->save($submission, $data);
1533
1534 // And now submit it for marking.
1535 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1536 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1537
1538 // Verify the student cannot make a new attempt.
1539 $output = $assign->view_student_summary($this->students[0], true);
1540 $this->assertEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1541
1542 // Mark the submission as non-passing.
1543 $this->setUser($this->teachers[0]);
1544 $data = new stdClass();
1545 $data->grade = '50.0';
1546 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1547
1548 // Check the student can see the grade.
1549 $this->setUser($this->students[0]);
1550 $output = $assign->view_student_summary($this->students[0], true);
1551 $this->assertNotEquals(false, strpos($output, '50.0'));
1552
1553 // Check that the student now has a button for Add a new attempt.
1554 $output = $assign->view_student_summary($this->students[0], true);
1555 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1556
1557 // Check that the student now does not have a button for Submit.
1558 $this->assertEquals(false, strpos($output, get_string('submitassignment', 'assign')));
1559
1560 // Check that the student now has a submission history.
1561 $this->assertNotEquals(false, strpos($output, get_string('attempthistory', 'assign')));
1562
1563 // Add a second submission.
1564 $now = time();
1565 $submission = $assign->get_user_submission($this->students[0]->id, true, 1);
1566 $data = new stdClass();
1567 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
1568 'text' => 'Submission text',
1569 'format' => FORMAT_MOODLE);
1570 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1571 $plugin->save($submission, $data);
1572
1573 // And now submit it for marking.
1574 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1575 $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
1576
1577 // Mark the submission as passing.
1578 $this->setUser($this->teachers[0]);
1579 $data = new stdClass();
1580 $data->grade = '80.0';
1581 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 1);
1582
1583 // Check that the student does not have a button for Add a new attempt.
1584 $this->setUser($this->students[0]);
1585 $output = $assign->view_student_summary($this->students[0], true);
1586 $this->assertEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1587
1588 // Re-mark the submission as not passing.
1589 $this->setUser($this->teachers[0]);
1590 $data = new stdClass();
1591 $data->grade = '50.0';
1592 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 1);
1593
1594 // Check that the student now has a button for Add a new attempt.
1595 $this->setUser($this->students[0]);
1596 $output = $assign->view_student_summary($this->students[0], true);
1597 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1598
1599 // Add a submission as a second student.
1600 $this->setUser($this->students[1]);
1601 $now = time();
1602 $submission = $assign->get_user_submission($this->students[1]->id, true);
1603 $data = new stdClass();
1604 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
1605 'text' => 'Submission text',
1606 'format' => FORMAT_MOODLE);
1607 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1608 $plugin->save($submission, $data);
1609
1610 // And now submit it for marking.
1611 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1612 $assign->testable_update_submission($submission, $this->students[1]->id, true, false);
1613
1614 // Mark the submission as passing.
1615 $this->setUser($this->teachers[0]);
1616 $data = new stdClass();
1617 $data->grade = '100.0';
1618 $assign->testable_apply_grade_to_user($data, $this->students[1]->id, 0);
1619
1620 // Check the student can see the grade.
1621 $this->setUser($this->students[1]);
1622 $output = $assign->view_student_summary($this->students[1], true);
1623 $this->assertNotEquals(false, strpos($output, '100.0'));
1624
1625 // Check that the student does not have a button for Add a new attempt.
1626 $output = $assign->view_student_summary($this->students[1], true);
1627 $this->assertEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1628
1629 // Set grade to pass to 0, so that no attempts should reopen.
1630 $gradeitem = $assign->get_grade_item();
1631 $gradeitem->gradepass = '0';
1632 $gradeitem->update();
1633
1634 // Add another submission.
1635 $this->setUser($this->students[2]);
1636 $now = time();
1637 $submission = $assign->get_user_submission($this->students[2]->id, true);
1638 $data = new stdClass();
1639 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(),
1640 'text' => 'Submission text',
1641 'format' => FORMAT_MOODLE);
1642 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1643 $plugin->save($submission, $data);
1644
1645 // And now submit it for marking.
1646 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1647 $assign->testable_update_submission($submission, $this->students[2]->id, true, false);
1648
1649 // Mark the submission as graded.
1650 $this->setUser($this->teachers[0]);
1651 $data = new stdClass();
1652 $data->grade = '0.0';
1653 $assign->testable_apply_grade_to_user($data, $this->students[2]->id, 0);
1654
1655 // Check the student can see the grade.
1656 $this->setUser($this->students[2]);
1657 $output = $assign->view_student_summary($this->students[2], true);
1658 $this->assertNotEquals(false, strpos($output, '0.0'));
1659
1660 // Check that the student does not have a button for Add a new attempt.
1661 $output = $assign->view_student_summary($this->students[2], true);
1662 $this->assertEquals(false, strpos($output, get_string('addnewattempt', 'assign')));
1663 }
1664
1665
f8d107b3
DM
1666 public function test_markingworkflow() {
1667 global $PAGE;
1668
1669 $this->setUser($this->editingteachers[0]);
1670 $assign = $this->create_instance(array('markingworkflow'=>1));
1671 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1672
13e82f1c 1673 // Mark the submission and set to notmarked.
f8d107b3
DM
1674 $this->setUser($this->teachers[0]);
1675 $data = new stdClass();
1676 $data->grade = '50.0';
1677 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED;
1678 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1679
1680 // Check the student can't see the grade.
1681 $this->setUser($this->students[0]);
1682 $output = $assign->view_student_summary($this->students[0], true);
1683 $this->assertEquals(false, strpos($output, '50.0'));
1684
13e82f1c 1685 // Mark the submission and set to inmarking.
f8d107b3
DM
1686 $this->setUser($this->teachers[0]);
1687 $data = new stdClass();
1688 $data->grade = '50.0';
1689 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INMARKING;
1690 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1691
1692 // Check the student can't see the grade.
1693 $this->setUser($this->students[0]);
1694 $output = $assign->view_student_summary($this->students[0], true);
1695 $this->assertEquals(false, strpos($output, '50.0'));
1696
13e82f1c 1697 // Mark the submission and set to readyforreview.
f8d107b3
DM
1698 $this->setUser($this->teachers[0]);
1699 $data = new stdClass();
1700 $data->grade = '50.0';
1701 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW;
1702 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1703
1704 // Check the student can't see the grade.
1705 $this->setUser($this->students[0]);
1706 $output = $assign->view_student_summary($this->students[0], true);
1707 $this->assertEquals(false, strpos($output, '50.0'));
1708
13e82f1c 1709 // Mark the submission and set to inreview.
f8d107b3
DM
1710 $this->setUser($this->teachers[0]);
1711 $data = new stdClass();
1712 $data->grade = '50.0';
1713 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW;
1714 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1715
1716 // Check the student can't see the grade.
1717 $this->setUser($this->students[0]);
1718 $output = $assign->view_student_summary($this->students[0], true);
1719 $this->assertEquals(false, strpos($output, '50.0'));
1720
13e82f1c 1721 // Mark the submission and set to readyforrelease.
f8d107b3
DM
1722 $this->setUser($this->teachers[0]);
1723 $data = new stdClass();
1724 $data->grade = '50.0';
1725 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE;
1726 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1727
1728 // Check the student can't see the grade.
1729 $this->setUser($this->students[0]);
1730 $output = $assign->view_student_summary($this->students[0], true);
1731 $this->assertEquals(false, strpos($output, '50.0'));
1732
13e82f1c 1733 // Mark the submission and set to released.
f8d107b3
DM
1734 $this->setUser($this->teachers[0]);
1735 $data = new stdClass();
1736 $data->grade = '50.0';
1737 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_RELEASED;
1738 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1739
1740 // Check the student can see the grade.
1741 $this->setUser($this->students[0]);
1742 $output = $assign->view_student_summary($this->students[0], true);
1743 $this->assertNotEquals(false, strpos($output, '50.0'));
1744 }
1745
1746 public function test_markerallocation() {
1747 global $PAGE;
1748
1749 $this->setUser($this->editingteachers[0]);
13e82f1c 1750 $assign = $this->create_instance(array('markingworkflow'=>1, 'markingallocation'=>1));
f8d107b3
DM
1751 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1752
13e82f1c 1753 // Allocate marker to submission.
f8d107b3
DM
1754 $data = new stdClass();
1755 $data->allocatedmarker = $this->teachers[0]->id;
1756 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
1757
13e82f1c 1758 // Check the allocated marker can view the submission.
f8d107b3
DM
1759 $this->setUser($this->teachers[0]);
1760 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
1761 $output = $assign->get_renderer()->render($gradingtable);
1762 $this->assertEquals(true, strpos($output, $this->students[0]->lastname));
1763
13e82f1c 1764 // Check that other teachers can't view this submission.
f8d107b3
DM
1765 $this->setUser($this->teachers[1]);
1766 $gradingtable = new assign_grading_table($assign, 100, '', 0, true);
1767 $output = $assign->get_renderer()->render($gradingtable);
1768 $this->assertNotEquals(true, strpos($output, $this->students[0]->lastname));
1769 }
76e77b05 1770
3d1331be 1771
159b7f40 1772
57fbd5f9
DW
1773 public function test_teacher_submit_for_student() {
1774 global $PAGE;
1775
1776 $this->preventResetByRollback();
1777 $sink = $this->redirectMessages();
1778
1779 $this->setUser($this->editingteachers[0]);
1780
1781 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1));
1782 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1783
1784 $this->setUser($this->students[0]);
1785 // Simulate a submission.
1786 $data = new stdClass();
1787 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1788 'text'=>'Student submission text',
1789 'format'=>FORMAT_MOODLE);
1790
1791 $notices = array();
1792 $assign->save_submission($data, $notices);
1793
1794 // Check that the submission text was saved.
1795 $output = $assign->view_student_summary($this->students[0], true);
1796 $this->assertContains('Student submission text', $output, 'Contains student submission text');
1797
1798 // Check that a teacher teacher with the extra capability can edit a students submission.
1799 $this->setUser($this->teachers[0]);
1800 $data = new stdClass();
1801 $data->userid = $this->students[0]->id;
1802 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1803 'text'=>'Teacher edited submission text',
1804 'format'=>FORMAT_MOODLE);
1805
1806 // Add the required capability.
1807 $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
1808 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
1809 role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id);
1810 accesslib_clear_all_caches_for_unit_testing();
1811
1812 // Try to save the submission.
1813 $notices = array();
1814 $assign->save_submission($data, $notices);
1815
1816 // Check that the teacher can submit the students work.
1817 $data = new stdClass();
1818 $data->userid = $this->students[0]->id;
1819 $notices = array();
1820 $assign->submit_for_grading($data, $notices);
1821
1822 // Revert to draft so the student can edit it.
1823 $assign->revert_to_draft($this->students[0]->id);
1824
1825 $this->setUser($this->students[0]);
1826
1827 // Check that the submission text was saved.
1828 $output = $assign->view_student_summary($this->students[0], true);
1829 $this->assertContains('Teacher edited submission text', $output, 'Contains student submission text');
1830
1831 // Check that the student can submit their work.
1832 $data = new stdClass();
1833 $assign->submit_for_grading($data, $notices);
1834
1835 $output = $assign->view_student_summary($this->students[0], true);
1836 $this->assertNotContains(get_string('addsubmission', 'assign'), $output);
1837
1838 // Set to a default editing teacher who should not be able to edit this submission.
1839 $this->setUser($this->editingteachers[1]);
1840
1841 // Revert to draft so the submission is editable.
1842 $assign->revert_to_draft($this->students[0]->id);
1843
1844 $data = new stdClass();
1845 $data->userid = $this->students[0]->id;
1846 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1847 'text'=>'Teacher 2 edited submission text',
1848 'format'=>FORMAT_MOODLE);
1849
1850 $notices = array();
1851 $this->setExpectedException('moodle_exception');
1852 $assign->save_submission($data, $notices);
1853
1854 $sink->close();
1855 }
1856
9054c04d 1857 public function test_disable_submit_after_cutoff_date() {
1858 global $PAGE;
1859
1860 $this->setUser($this->editingteachers[0]);
1861 $now = time();
1862 $tomorrow = $now + 24*60*60;
1863 $lastweek = $now - 7*24*60*60;
1864 $yesterday = $now - 24*60*60;
1865
1866 $assign = $this->create_instance(array('duedate'=>$yesterday,
1867 'cutoffdate'=>$tomorrow,
1868 'assignsubmission_onlinetext_enabled'=>1));
1869 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
1870
1871 // Student should be able to see an add submission button.
1872 $this->setUser($this->students[0]);
1873 $output = $assign->view_student_summary($this->students[0], true);
1874 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
1875
1876 // Add a submission but don't submit now.
1877 $submission = $assign->get_user_submission($this->students[0]->id, true);
1878 $data = new stdClass();
1879 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1880 'text'=>'Submission text',
1881 'format'=>FORMAT_MOODLE);
1882 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1883 $plugin->save($submission, $data);
1884
1885 // Create another instance with cut-off and due-date already passed.
1886 $this->setUser($this->editingteachers[0]);
1887 $now = time();
1888 $assign = $this->create_instance(array('duedate'=>$lastweek,
1889 'cutoffdate'=>$yesterday,
1890 'assignsubmission_onlinetext_enabled'=>1));
1891
1892 $this->setUser($this->students[0]);
1893 $output = $assign->view_student_summary($this->students[0], true);
1894 $this->assertNotContains($output, get_string('editsubmission', 'assign'),
1895 'Should not be able to edit after cutoff date.');
1896 $this->assertNotContains($output, get_string('submitassignment', 'assign'),
1897 'Should not be able to submit after cutoff date.');
1898 }
f159ad73 1899 /**
1900 * Testing for submission comment plugin settings
1901 */
1902 public function test_submission_comment_plugin_settings() {
1903 global $CFG;
1904
1905 $commentconfig = false;
1906 if (!empty($CFG->usecomments)) {
1907 $commentconfig = $CFG->usecomments;
1908 }
1909
1910 $CFG->usecomments = true;
1911 $assign = $this->create_instance();
1912 $plugin = $assign->get_submission_plugin_by_type('comments');
1913 $this->assertEquals(1, $plugin->is_enabled('enabled'));
1914
1915 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 0));
1916 $plugin = $assign->get_submission_plugin_by_type('comments');
1917 $this->assertEquals(1, $plugin->is_enabled('enabled'));
1918
1919 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 1));
1920 $plugin = $assign->get_submission_plugin_by_type('comments');
1921 $this->assertEquals(1, $plugin->is_enabled('enabled'));
1922
1923 $CFG->usecomments = false;
1924 $assign = $this->create_instance();
1925 $plugin = $assign->get_submission_plugin_by_type('comments');
1926 $this->assertEquals(0, $plugin->is_enabled('enabled'));
1927
1928 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 0));
1929 $plugin = $assign->get_submission_plugin_by_type('comments');
1930 $this->assertEquals(0, $plugin->is_enabled('enabled'));
1931
1932 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 1));
1933 $plugin = $assign->get_submission_plugin_by_type('comments');
1934 $this->assertEquals(0, $plugin->is_enabled('enabled'));
1935
1936 $CFG->usecomments = $commentconfig;
1937 }
1938
c7a73689
DW
1939 /**
1940 * Testing for comment inline settings
1941 */
1942 public function test_feedback_comment_commentinline() {
1943 global $CFG;
1944
1945 $sourcetext = "Hello!
1946
1947I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness.
1948
1949URL outside a tag: https://moodle.org/logo/logo-240x60.gif
1950Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif
1951
1952External link 1:<img src='https://moodle.org/logo/logo-240x60.gif' alt='Moodle'/>
1953External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\"/>
1954Internal link 1:<img src='@@PLUGINFILE@@/logo-240x60.gif' alt='Moodle'/>
1955Internal link 2:<img alt=\"Moodle\" src=\"@@PLUGINFILE@@logo-240x60.gif\"/>
1956Anchor link 1:<a href=\"@@PLUGINFILE@@logo-240x60.gif\" alt=\"bananas\">Link text</a>
1957Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
1958";
1959
1960 // Note the internal images have been stripped and the html is purified (quotes fixed in this case).
1961 $filteredtext = "Hello!
1962
1963I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness.
1964
1965URL outside a tag: https://moodle.org/logo/logo-240x60.gif
1966Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif
1967
1968External link 1:<img src=\"https://moodle.org/logo/logo-240x60.gif\" alt=\"Moodle\" />
1969External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\" />
1970Internal link 1:
1971Internal link 2:
1972Anchor link 1:Link text
1973Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
1974";
1975
1976 $this->setUser($this->editingteachers[0]);
1977 $params = array('assignsubmission_onlinetext_enabled' => 1,
1978 'assignfeedback_comments_enabled' => 1,
1979 'assignfeedback_comments_commentinline' => 1);
1980 $assign = $this->create_instance($params);
1981
1982 $this->setUser($this->students[0]);
1983 // Add a submission but don't submit now.
1984 $submission = $assign->get_user_submission($this->students[0]->id, true);
1985 $data = new stdClass();
1986
1987 // Test the internal link is stripped, but the external one is not.
1988 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
1989 'text'=>$sourcetext,
1990 'format'=>FORMAT_MOODLE);
1991
1992 $plugin = $assign->get_submission_plugin_by_type('onlinetext');
1993 $plugin->save($submission, $data);
1994
1995 $this->setUser($this->editingteachers[0]);
1996
1997 $data = new stdClass();
1998 require_once($CFG->dirroot . '/mod/assign/gradeform.php');
1999 $pagination = array('userid'=>$this->students[0]->id,
2000 'rownum'=>0,
2001 'last'=>true,
2002 'useridlistid'=>time(),
2003 'attemptnumber'=>0);
2004 $formparams = array($assign, $data, $pagination);
2005 $mform = new mod_assign_grade_form(null, $formparams);
2006
2007 $this->assertEquals($filteredtext, $data->assignfeedbackcomments_editor['text']);
2008 }
2009
f159ad73 2010 /**
2011 * Testing for feedback comment plugin settings
2012 */
2013 public function test_feedback_plugin_settings() {
2014
2015 $assign = $this->create_instance();
2016 $plugin = $assign->get_feedback_plugin_by_type('comments');
2017 $this->assertEquals(0, $plugin->is_enabled('enabled'));
2018
2019 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 0));
2020 $plugin = $assign->get_feedback_plugin_by_type('comments');
2021 $this->assertEquals(0, $plugin->is_enabled('enabled'));
2022
2023 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
2024 $plugin = $assign->get_feedback_plugin_by_type('comments');
2025 $this->assertEquals(1, $plugin->is_enabled('enabled'));
2026 }
456d7bc7
RT
2027
2028 /**
2029 * Testing if gradebook feedback plugin is enabled.
2030 */
2031 public function test_is_gradebook_feedback_enabled() {
2032 $adminconfig = get_config('assign');
2033 $gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
2034
2035 // Create assignment with gradebook feedback enabled and grade = 0.
2036 $assign = $this->create_instance(array($gradebookplugin . '_enabled' => 1, 'grades' => 0));
2037
2038 // Get gradebook feedback plugin.
2039 $gradebookplugintype = str_replace('assignfeedback_', '', $gradebookplugin);
2040 $plugin = $assign->get_feedback_plugin_by_type($gradebookplugintype);
2041 $this->assertEquals(1, $plugin->is_enabled('enabled'));
2042 $this->assertEquals(1, $assign->is_gradebook_feedback_enabled());
2043
2044 // Create assignment with gradebook feedback disabled and grade = 0.
2045 $assign = $this->create_instance(array($gradebookplugin . '_enabled' => 0, 'grades' => 0));
2046 $plugin = $assign->get_feedback_plugin_by_type($gradebookplugintype);
2047 $this->assertEquals(0, $plugin->is_enabled('enabled'));
2048 }
57fbd5f9
DW
2049
2050 /**
2051 * Testing can_edit_submission
2052 */
2053 public function test_can_edit_submission() {
2054 global $PAGE, $DB;
2055 $this->create_extra_users();
2056
2057 $this->setAdminUser();
2058 // Create assignment (onlinetext).
2059 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1));
2060 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
2061
2062 // Check student can edit their own submission.
2063 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->students[0]->id));
2064 // Check student cannot edit others submission.
2065 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->students[1]->id));
2066
2067 // Check teacher cannot (by default) edit a students submission.
2068 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id));
2069
2070 // Add the required capability to edit a student submission.
2071 $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
2072 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
2073 role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id);
2074 accesslib_clear_all_caches_for_unit_testing();
2075 // Retest - should now have access.
2076 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id));
2077
2078 // Force create an assignment with SEPARATEGROUPS.
2079 $data = new stdClass();
2080 $data->courseid = $this->course->id;
2081 $data->name = 'Grouping';
2082 $groupingid = groups_create_grouping($data);
2083 groups_assign_grouping($groupingid, $this->groups[0]->id);
2084 groups_assign_grouping($groupingid, $this->groups[1]->id);
2085 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS));
2086
2087 // Add the capability to the new assignment for extra students 0 and 1.
2088 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
2089 role_assign($roleid, $this->extrastudents[0]->id, $assign->get_context()->id);
2090 role_assign($roleid, $this->extrastudents[1]->id, $assign->get_context()->id);
2091 accesslib_clear_all_caches_for_unit_testing();
2092
2093 // Verify the extra student does not have the capability to edit a submission not in their group.
2094 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[1]->id));
2095 // Verify the extra student does have the capability to edit a submission in their group.
2096 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[0]->id));
2097
2098 }
323f221b
MH
2099
2100 /**
2101 * Test if the view blind details capability works
2102 */
2103 public function test_can_view_blind_details() {
2104 global $PAGE, $DB;
2105 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
2106 $managerrole = $DB->get_record('role', array('shortname' => 'manager'));
2107
2108 $student = $this->students[0];// Get a student user.
2109 // Create a teacher. Shouldn't be able to view blind marking ID.
2110 $teacher = $this->getDataGenerator()->create_user();
2111
2112 $this->getDataGenerator()->enrol_user($teacher->id,
2113 $this->course->id,
2114 $teacherrole->id);
2115
2116 // Create a manager.. Should be able to view blind marking ID.
2117 $manager = $this->getDataGenerator()->create_user();
e28d6b29
MG
2118 $this->getDataGenerator()->enrol_user($manager->id,
2119 $this->course->id,
323f221b
MH
2120 $managerrole->id);
2121
2122 // Generate blind marking assignment.
e28d6b29 2123 $assign = $this->create_instance(array('blindmarking' => 1));
323f221b
MH
2124 $this->assertEquals(true, $assign->is_blind_marking());
2125
2126 // Test student names are hidden to teacher.
e28d6b29
MG
2127 $this->setUser($teacher);
2128 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
2129 $output = $assign->get_renderer()->render($gradingtable);
323f221b
MH
2130 $this->assertEquals(true, strpos($output, get_string('hiddenuser', 'assign'))); // "Participant" is somewhere on the page.
2131 $this->assertEquals(false, strpos($output, fullname($student))); // Students full name doesn't appear.
2132
2133 // Test student names are visible to manager.
e28d6b29
MG
2134 $this->setUser($manager);
2135 $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
2136 $output = $assign->get_renderer()->render($gradingtable);
8c674e80 2137 $this->assertEquals(false, strpos($output, get_string('hiddenuser', 'assign')));
323f221b
MH
2138 $this->assertEquals(true, strpos($output, fullname($student))); //students full name doesn't appear.
2139 }
47f48152
DW
2140}
2141