MDL-37337 Assignment: Restructure assignment settings screen to make it "wieldy"
[moodle.git] / mod / assign / tests / locallib_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * 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  */
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
30 require_once($CFG->dirroot . '/mod/assign/locallib.php');
31 require_once($CFG->dirroot . '/mod/assign/upgradelib.php');
33 /**
34  * Unit tests for (some of) mod/assign/locallib.php.
35  *
36  * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class mod_assign_locallib_testcase extends advanced_testcase {
41     /** @var stdClass $course New course created to hold the assignments */
42     protected $course = null;
44     /** @var array $teachers List of 5 default teachers in the course*/
45     protected $teachers = null;
47     /** @var array $editingteachers List of 5 default editing teachers in the course*/
48     protected $editingteachers = null;
50     /** @var array $students List of 100 default students in the course*/
51     protected $students = null;
53     /** @var array $groups List of 10 groups in the course */
54     protected $groups = null;
56     /**
57      * Setup function - we will create a course and add an assign instance to it.
58      */
59     protected function setUp() {
60         global $DB, $CFG;
62         $this->resetAfterTest(true);
64         $this->course = $this->getDataGenerator()->create_course();
65         $this->teachers = array();
66         for ($i = 0; $i < 5; $i++) {
67             array_push($this->teachers, $this->getDataGenerator()->create_user());
68         }
70         $this->editingteachers = array();
71         for ($i = 0; $i < 5; $i++) {
72             array_push($this->editingteachers, $this->getDataGenerator()->create_user());
73         }
75         $this->students = array();
76         for ($i = 0; $i < 100; $i++) {
77             array_push($this->students, $this->getDataGenerator()->create_user());
78         }
80         $this->groups = array();
81         for ($i = 0; $i < 10; $i++) {
82             array_push($this->groups, $this->getDataGenerator()->create_group(array('courseid'=>$this->course->id)));
83         }
85         $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
86         foreach ($this->teachers as $i => $teacher) {
87             $this->getDataGenerator()->enrol_user($teacher->id,
88                                                   $this->course->id,
89                                                   $teacherrole->id);
90             groups_add_member($this->groups[$i % 10], $teacher);
91         }
93         $editingteacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'));
94         foreach ($this->editingteachers as $i => $editingteacher) {
95             $this->getDataGenerator()->enrol_user($editingteacher->id,
96                                                   $this->course->id,
97                                                   $editingteacherrole->id);
98             groups_add_member($this->groups[$i % 10], $editingteacher);
99         }
101         $studentrole = $DB->get_record('role', array('shortname'=>'student'));
102         foreach ($this->students as $i => $student) {
103             $this->getDataGenerator()->enrol_user($student->id,
104                                                   $this->course->id,
105                                                   $studentrole->id);
106             if ($i < 80) {
107                 groups_add_member($this->groups[$i % 10], $student);
108             }
109         }
110     }
112     private function create_instance($params=array()) {
113         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
114         $params['course'] = $this->course->id;
115         $instance = $generator->create_instance($params);
116         $cm = get_coursemodule_from_instance('assign', $instance->id);
117         $context = context_module::instance($cm->id);
118         return new testable_assign($context, $cm, $this->course);
119     }
121     public function test_return_links() {
122         $this->setUser($this->editingteachers[0]);
123         $returnaction = 'RETURNACTION';
124         $returnparams = array('param'=>1);
125         $assign = $this->create_instance();
126         $assign->register_return_link($returnaction, $returnparams);
127         $this->assertEquals($returnaction, $assign->get_return_action());
128         $this->assertEquals($returnparams, $assign->get_return_params());
129     }
131     public function test_get_feedback_plugins() {
132         $this->setUser($this->editingteachers[0]);
133         $assign = $this->create_instance();
134         $this->assertEquals(3, count($assign->get_feedback_plugins()));
135     }
137     public function test_get_submission_plugins() {
138         $this->setUser($this->editingteachers[0]);
139         $assign = $this->create_instance();
140         $this->assertEquals(3, count($assign->get_submission_plugins()));
141     }
143     public function test_is_blind_marking() {
144         $this->setUser($this->editingteachers[0]);
145         $assign = $this->create_instance(array('blindmarking'=>1));
146         $this->assertEquals(true, $assign->is_blind_marking());
148         // Test cannot see student names.
149         $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
150         $output = $assign->get_renderer()->render($gradingtable);
151         $this->assertEquals(true, strpos($output, get_string('hiddenuser', 'assign')));
153         // Test students cannot reveal identities.
154         $nopermission = false;
155         $this->setUser($this->students[0]);
156         $this->setExpectedException('required_capability_exception');
157         $assign->testable_process_reveal_identities();
159         // Test teachers cannot reveal identities.
160         $nopermission = false;
161         $this->setUser($this->teachers[0]);
162         $this->setExpectedException('required_capability_exception');
163         $assign->testable_process_reveal_identities();
165         // Test sesskey is required.
166         $nosesskey = true;
167         $this->setUser($this->editingteachers[0]);
168         $this->setExpectedException('moodle_exception');
169         $assign->testable_process_reveal_identities();
171         // Test editingteacher can reveal identities if sesskey is ignored.
172         $this->editingteachers[0]->ignoresesskey = true;
173         $this->setUser($this->editingteachers[0]);
174         $assign->testable_process_reveal_identities();
175         $this->assertEquals(false, $assign->is_blind_marking());
177         // Test student names are visible.
178         $gradingtable = new assign_grading_table($assign, 1, '', 0, true);
179         $output = $assign->get_renderer()->render($gradingtable);
180         $this->assertEquals(false, strpos($output, get_string('hiddenuser', 'assign')));
182         // Set this back to default.
183         $this->editingteachers[0]->ignoresesskey = false;
184     }
186     public function test_show_intro() {
187         // Test whether we are showing the intro at the correct times.
188         $this->setUser($this->editingteachers[0]);
189         $assign = $this->create_instance(array('alwaysshowdescription'=>1));
191         $this->assertEquals(true, $assign->testable_show_intro());
193         $tomorrow = time() + (24*60*60);
195         $assign = $this->create_instance(array('alwaysshowdescription'=>0,
196                                                'allowsubmissionsfromdate'=>$tomorrow));
197         $this->assertEquals(false, $assign->testable_show_intro());
198         $yesterday = time() - (24*60*60);
199         $assign = $this->create_instance(array('alwaysshowdescription'=>0,
200                                                'allowsubmissionsfromdate'=>$yesterday));
201         $this->assertEquals(true, $assign->testable_show_intro());
202     }
204     public function test_has_submissions_or_grades() {
205         $this->setUser($this->editingteachers[0]);
206         $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
208         $instance = $assign->get_instance();
210         // Should start empty.
211         $this->assertEquals(false, $assign->has_submissions_or_grades());
213         // Simulate a submission.
214         $this->setUser($this->students[0]);
215         $submission = $assign->get_user_submission($this->students[0]->id, true);
216         $data = new stdClass();
217         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
218                                          'text'=>'Submission text',
219                                          'format'=>FORMAT_MOODLE);
220         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
221         $plugin->save($submission, $data);
223         // Now test again.
224         $this->assertEquals(true, $assign->has_submissions_or_grades());
225         // Set this back to default.
226         $this->students[0]->ignoresesskey = false;
227     }
229     public function test_delete_grades() {
230         $this->setUser($this->editingteachers[0]);
231         $assign = $this->create_instance();
233         // Simulate adding a grade.
234         $this->setUser($this->teachers[0]);
235         $data = new stdClass();
236         $data->grade = '50.0';
237         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
239         // Now see if the data is in the gradebook.
240         $gradinginfo = grade_get_grades($this->course->id,
241                                         'mod',
242                                         'assign',
243                                         $assign->get_instance()->id);
245         $this->assertNotEquals(0, count($gradinginfo->items));
247         $assign->testable_delete_grades();
248         $gradinginfo = grade_get_grades($this->course->id,
249                                         'mod',
250                                         'assign',
251                                         $assign->get_instance()->id);
253         $this->assertEquals(0, count($gradinginfo->items));
254     }
256     public function test_delete_instance() {
257         $this->setUser($this->editingteachers[0]);
258         $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
260         // Simulate adding a grade.
261         $this->setUser($this->teachers[0]);
262         $data = new stdClass();
263         $data->grade = '50.0';
264         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
266         // Simulate a submission.
267         $this->setUser($this->students[0]);
268         $submission = $assign->get_user_submission($this->students[0]->id, true);
269         $data = new stdClass();
270         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
271                                          'text'=>'Submission text',
272                                          'format'=>FORMAT_MOODLE);
273         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
274         $plugin->save($submission, $data);
276         // Now try and delete.
277         $this->assertEquals(true, $assign->delete_instance());
278     }
280     public function test_reset_userdata() {
281         global $DB;
283         $now = time();
284         $this->setUser($this->editingteachers[0]);
285         $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1,
286                                                'duedate'=>$now));
288         // Simulate adding a grade.
289         $this->setUser($this->teachers[0]);
290         $data = new stdClass();
291         $data->grade = '50.0';
292         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
294         // Simulate a submission.
295         $this->setUser($this->students[0]);
296         $submission = $assign->get_user_submission($this->students[0]->id, true);
297         $data = new stdClass();
298         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
299                                          'text'=>'Submission text',
300                                          'format'=>FORMAT_MOODLE);
301         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
302         $plugin->save($submission, $data);
304         $this->assertEquals(true, $assign->has_submissions_or_grades());
305         // Now try and reset.
306         $data = new stdClass();
307         $data->reset_assign_submissions = 1;
308         $data->reset_gradebook_grades = 1;
309         $data->courseid = $this->course->id;
310         $data->timeshift = 24*60*60;
311         $this->setUser($this->editingteachers[0]);
312         $assign->reset_userdata($data);
313         $this->assertEquals(false, $assign->has_submissions_or_grades());
315         // Reload the instance data.
316         $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
317         $this->assertEquals($now + 24*60*60, $instance->duedate);
318     }
320     public function test_plugin_settings() {
321         global $DB;
323         $now = time();
324         $this->setUser($this->editingteachers[0]);
325         $assign = $this->create_instance(array('assignsubmission_file_enabled'=>1,
326                                                'assignsubmission_file_maxfiles'=>12,
327                                                'assignsubmission_file_maxsizebytes'=>10));
329         $plugin = $assign->get_submission_plugin_by_type('file');
330         $this->assertEquals('12', $plugin->get_config('maxfilesubmissions'));
331     }
333     public function test_update_calendar() {
334         global $DB;
336         $now = time();
337         $this->setUser($this->editingteachers[0]);
338         $assign = $this->create_instance(array('duedate'=>$now));
340         // See if there is an event in the calendar.
341         $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id);
342         $id = $DB->get_field('event', 'id', $params);
344         $this->assertEquals(false, empty($id));
345     }
347     public function test_update_instance() {
348         global $DB;
350         $this->setUser($this->editingteachers[0]);
351         $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
353         $now = time();
354         $instance = $assign->get_instance();
355         $instance->duedate = $now;
356         $instance->instance = $instance->id;
357         $instance->assignsubmission_onlinetext_enabled = 1;
358         $instance->assignsubmission_file_enabled = 0;
359         $instance->assignsubmission_comments_enabled = 0;
360         $instance->assignfeedback_comments_enabled = 0;
361         $instance->assignfeedback_file_enabled = 0;
362         $instance->assignfeedback_offline_enabled = 0;
364         $assign->update_instance($instance);
366         $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id));
367         $this->assertEquals($now, $instance->duedate);
368     }
370     public function test_list_participants() {
371         $this->setUser($this->editingteachers[0]);
372         $assign = $this->create_instance(array('grade'=>100));
374         $this->assertEquals(100, count($assign->list_participants(null, true)));
375     }
377     public function test_count_teams() {
378         $this->setUser($this->editingteachers[0]);
379         $assign = $this->create_instance(array('teamsubmission'=>1));
381         $this->assertEquals(11, $assign->count_teams());
382     }
384     public function test_count_submissions() {
385         $this->setUser($this->editingteachers[0]);
386         $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1));
388         // Simulate a submission.
389         $this->setUser($this->students[0]);
390         $submission = $assign->get_user_submission($this->students[0]->id, true);
391         // Leave this one as DRAFT.
392         $data = new stdClass();
393         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
394                                          'text'=>'Submission text',
395                                          'format'=>FORMAT_MOODLE);
396         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
397         $plugin->save($submission, $data);
399         // Simulate adding a grade.
400         $this->setUser($this->teachers[0]);
401         $data = new stdClass();
402         $data->grade = '50.0';
403         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
405         // Simulate a submission.
406         $this->setUser($this->students[1]);
407         $submission = $assign->get_user_submission($this->students[1]->id, true);
408         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
409         $assign->testable_update_submission($submission, $this->students[1]->id, true, false);
410         $data = new stdClass();
411         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
412                                          'text'=>'Submission text',
413                                          'format'=>FORMAT_MOODLE);
414         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
415         $plugin->save($submission, $data);
417         // Simulate a submission.
418         $this->setUser($this->students[2]);
419         $submission = $assign->get_user_submission($this->students[2]->id, true);
420         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
421         $assign->testable_update_submission($submission, $this->students[2]->id, true, false);
422         $data = new stdClass();
423         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
424                                          'text'=>'Submission text',
425                                          'format'=>FORMAT_MOODLE);
426         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
427         $plugin->save($submission, $data);
429         // Simulate a submission.
430         $this->setUser($this->students[3]);
431         $submission = $assign->get_user_submission($this->students[3]->id, true);
432         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
433         $assign->testable_update_submission($submission, $this->students[3]->id, true, false);
434         $data = new stdClass();
435         $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
436                                          'text'=>'Submission text',
437                                          'format'=>FORMAT_MOODLE);
438         $plugin = $assign->get_submission_plugin_by_type('onlinetext');
439         $plugin->save($submission, $data);
441         // Simulate adding a grade.
442         $this->setUser($this->teachers[0]);
443         $data = new stdClass();
444         $data->grade = '50.0';
445         $assign->testable_apply_grade_to_user($data, $this->students[3]->id);
447         $this->assertEquals(2, $assign->count_grades());
448         $this->assertEquals(4, $assign->count_submissions());
449         $this->assertEquals(2, $assign->count_submissions_need_grading());
450         $this->assertEquals(3, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED));
451         $this->assertEquals(1, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT));
452     }
454     public function test_get_grading_userid_list() {
455         $this->setUser($this->editingteachers[0]);
456         $assign = $this->create_instance();
458         $users = $assign->testable_get_grading_userid_list();
459         $this->assertEquals(100, count($users));
460     }
462     public function test_cron() {
463         // First run cron so there are no messages waiting to be sent (from other tests).
464         cron_setup_user();
465         assign::cron();
467         // Now create an assignment and add some feedback.
468         $this->setUser($this->editingteachers[0]);
469         $assign = $this->create_instance();
471         // Simulate adding a grade.
472         $this->setUser($this->teachers[0]);
473         $data = new stdClass();
474         $data->grade = '50.0';
475         $assign->testable_apply_grade_to_user($data, $this->students[3]->id);
477         // Now run cron and see that one message was sent.
478         $this->preventResetByRollback();
479         $sink = $this->redirectMessages();
480         cron_setup_user();
481         $this->expectOutputRegex('/Done processing 1 assignment submissions/');
482         assign::cron();
484         $messages = $sink->get_messages();
485         $this->assertEquals(1, count($messages));
486         $this->assertEquals(1, $messages[0]->notification);
487         $this->assertEquals($assign->get_instance()->name, $messages[0]->contexturlname);
488     }
490     public function test_is_graded() {
491         $this->setUser($this->editingteachers[0]);
492         $assign = $this->create_instance();
494         // Simulate adding a grade.
495         $this->setUser($this->teachers[0]);
496         $data = new stdClass();
497         $data->grade = '50.0';
498         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
500         $this->assertEquals(true, $assign->testable_is_graded($this->students[0]->id));
501         $this->assertEquals(false, $assign->testable_is_graded($this->students[1]->id));
502     }
504     public function test_can_view_submission() {
505         $this->setUser($this->editingteachers[0]);
506         $assign = $this->create_instance();
508         $this->setUser($this->students[0]);
509         $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
510         $this->assertEquals(false, $assign->can_view_submission($this->students[1]->id));
511         $this->assertEquals(false, $assign->can_view_submission($this->teachers[0]->id));
512         $this->setUser($this->teachers[0]);
513         $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
514         $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
515         $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
516         $this->setUser($this->editingteachers[0]);
517         $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id));
518         $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id));
519         $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id));
520     }
523     public function test_update_submission() {
524         $this->setUser($this->editingteachers[0]);
525         $assign = $this->create_instance();
527         $this->setUser($this->students[0]);
528         $now = time();
529         $submission = $assign->get_user_submission($this->students[0]->id, true);
530         $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
532         $this->setUser($this->teachers[0]);
533         // Verify the gradebook update.
534         $gradinginfo = grade_get_grades($this->course->id,
535                                         'mod',
536                                         'assign',
537                                         $assign->get_instance()->id,
538                                         $this->students[0]->id);
540         $this->assertEquals($this->students[0]->id,
541                             $gradinginfo->items[0]->grades[$this->students[0]->id]->usermodified);
543         // Now verify group assignments.
544         $this->setUser($this->editingteachers[0]);
545         $assign = $this->create_instance(array('teamsubmission'=>1));
547         $this->setUser($this->students[0]);
548         $now = time();
549         $submission = $assign->get_group_submission($this->students[0]->id, 0, true);
550         $assign->testable_update_submission($submission, $this->students[0]->id, true, true);
552         // Check that at least 2 members of the submission group had their submission updated.
554         $this->setUser($this->editingteachers[0]);
555         $gradinginfo = grade_get_grades($this->course->id,
556                                         'mod',
557                                         'assign',
558                                         $assign->get_instance()->id,
559                                         $this->students[0]->id);
561         $this->assertEquals($this->students[0]->id,
562                             $gradinginfo->items[0]->grades[$this->students[0]->id]->usermodified);
564         $gradinginfo = grade_get_grades($this->course->id,
565                                         'mod',
566                                         'assign',
567                                         $assign->get_instance()->id,
568                                         $this->students[10]->id);
570         $this->assertEquals($this->students[10]->id,
571                             $gradinginfo->items[0]->grades[$this->students[10]->id]->usermodified);
573         // Now verify blind marking.
574         $this->setUser($this->editingteachers[0]);
575         $assign = $this->create_instance(array('blindmarking'=>1));
577         $this->setUser($this->students[0]);
578         $now = time();
579         $submission = $assign->get_user_submission($this->students[0]->id, true);
580         $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
582         $this->setUser($this->editingteachers[0]);
583         $gradinginfo = grade_get_grades($this->course->id,
584                                         'mod',
585                                         'assign',
586                                         $assign->get_instance()->id,
587                                         $this->students[0]->id);
589         $this->assertEquals(null, $gradinginfo->items[0]->grades[$this->students[0]->id]->datesubmitted);
590     }
592     public function test_submissions_open() {
593         $this->setUser($this->editingteachers[0]);
595         $now = time();
596         $tomorrow = $now + 24*60*60;
597         $oneweek = $now + 7*24*60*60;
598         $yesterday = $now - 24*60*60;
600         $assign = $this->create_instance();
601         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
603         $assign = $this->create_instance(array('duedate'=>$tomorrow));
604         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
606         $assign = $this->create_instance(array('duedate'=>$yesterday));
607         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
609         $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$tomorrow));
610         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
612         $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$yesterday));
613         $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
615         $assign->testable_save_user_extension($this->students[0]->id, $tomorrow);
616         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
618         $assign = $this->create_instance(array('submissiondrafts'=>1));
619         $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id));
621         $this->setUser($this->students[0]);
622         $now = time();
623         $submission = $assign->get_user_submission($this->students[0]->id, true);
624         $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
625         $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
626         $this->setUser($this->editingteachers[0]);
627         $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id));
628     }
630     public function test_get_graders() {
631         $this->setUser($this->editingteachers[0]);
632         $assign = $this->create_instance();
634         $this->assertCount(10, $assign->testable_get_graders($this->students[0]->id));
636         $assign = $this->create_instance();
637         // Force create an assignment with SEPARATEGROUPS.
638         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
639         $params = array('course'=>$this->course->id);
640         $instance = $generator->create_instance($params);
641         $cm = get_coursemodule_from_instance('assign', $instance->id);
642         set_coursemodule_groupmode($cm->id, SEPARATEGROUPS);
643         $cm->groupmode = SEPARATEGROUPS;
644         $context = context_module::instance($cm->id);
645         $assign = new testable_assign($context, $cm, $this->course);
647         $this->setUser($this->students[1]);
648         $this->assertCount(2, $assign->testable_get_graders($this->students[0]->id));
649     }
651     public function test_get_uniqueid_for_user() {
652         $this->setUser($this->editingteachers[0]);
653         $assign = $this->create_instance();
655         foreach ($this->students as $student) {
656             $uniqueid = $assign->get_uniqueid_for_user($student->id);
657             $this->assertEquals($student->id, $assign->get_user_id_for_uniqueid($uniqueid));
658         }
659     }
661     public function test_show_student_summary() {
662         global $CFG;
664         $this->setUser($this->editingteachers[0]);
665         $assign = $this->create_instance();
667         // No feedback should be available because this student has not been graded.
668         $this->setUser($this->students[0]);
669         $output = $assign->view_student_summary($this->students[0], true);
670         $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if there is no grade');
671         // Simulate adding a grade.
672         $this->setUser($this->teachers[0]);
673         $data = new stdClass();
674         $data->grade = '50.0';
675         $assign->testable_apply_grade_to_user($data, $this->students[0]->id);
677         // Now we should see the feedback.
678         $this->setUser($this->students[0]);
679         $output = $assign->view_student_summary($this->students[0], true);
680         $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade');
682         // Now hide the grade in gradebook.
683         $this->setUser($this->teachers[0]);
684         require_once($CFG->libdir.'/gradelib.php');
685         $gradeitem = new grade_item(array(
686             'itemtype'      => 'mod',
687             'itemmodule'    => 'assign',
688             'iteminstance'  => $assign->get_instance()->id,
689             'courseid'      => $this->course->id));
691         $gradeitem->set_hidden(1, false);
693         // No feedback should be available because the grade is hidden.
694         $this->setUser($this->students[0]);
695         $output = $assign->view_student_summary($this->students[0], true);
696         $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook');
698         // Do the same but add feedback.
699         $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1));
701         $this->setUser($this->teachers[0]);
702         $grade = $assign->get_user_grade($this->students[0]->id, true);
703         $data = new stdClass();
704         $data->assignfeedbackcomments_editor = array('text'=>'Tomato sauce',
705                                          'format'=>FORMAT_MOODLE);
706         $plugin = $assign->get_feedback_plugin_by_type('comments');
707         $plugin->save($grade, $data);
709         // Should have feedback but no grade.
710         $this->setUser($this->students[0]);
711         $output = $assign->view_student_summary($this->students[0], true);
712         $this->assertNotEquals(false, strpos($output, 'Tomato sauce'), 'Show feedback even if there is no grade');
713         $this->assertEquals(false, strpos($output, 'Grade'), 'Do not show grade when there is no grade.');
714         $this->assertEquals(false, strpos($output, 'Graded on'), 'Do not show graded date when there is no grade.');
715     }
720 /**
721  * Test subclass that makes all the protected methods we want to test public.
722  */
723 class testable_assign extends assign {
725     public function testable_process_reveal_identities() {
726         return parent::process_reveal_identities();
727     }
729     public function testable_show_intro() {
730         return parent::show_intro();
731     }
733     public function testable_delete_grades() {
734         return parent::delete_grades();
735     }
737     public function testable_apply_grade_to_user($formdata, $userid) {
738         return parent::apply_grade_to_user($formdata, $userid);
739     }
741     public function testable_get_grading_userid_list() {
742         return parent::get_grading_userid_list();
743     }
745     public function testable_is_graded($userid) {
746         return parent::is_graded($userid);
747     }
749     public function testable_update_submission(stdClass $submission, $userid, $updatetime, $teamsubmission) {
750         return parent::update_submission($submission, $userid, $updatetime, $teamsubmission);
751     }
753     public function testable_submissions_open($userid = 0) {
754         return parent::submissions_open($userid);
755     }
757     public function testable_save_user_extension($userid, $extensionduedate) {
758         return parent::save_user_extension($userid, $extensionduedate);
759     }
761     public function testable_get_graders($userid) {
762         // Changed method from protected to public.
763         return parent::get_graders($userid);
764     }