Merge branch 'MDL-56486-master-workshopfiletypes' of git://github.com/mudrd8mz/moodle
[moodle.git] / mod / workshop / 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 workshop api class defined in mod/workshop/locallib.php
19  *
20  * @package    mod_workshop
21  * @category   phpunit
22  * @copyright  2009 David Mudrak <david.mudrak@gmail.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/mod/workshop/locallib.php'); // Include the code to test
30 require_once(__DIR__ . '/fixtures/testable.php');
33 /**
34  * Test cases for the internal workshop api
35  */
36 class mod_workshop_internal_api_testcase extends advanced_testcase {
38     /** @var object */
39     protected $course;
41     /** @var workshop */
42     protected $workshop;
44     /** setup testing environment */
45     protected function setUp() {
46         parent::setUp();
47         $this->setAdminUser();
48         $this->course = $this->getDataGenerator()->create_course();
49         $workshop = $this->getDataGenerator()->create_module('workshop', array('course' => $this->course));
50         $cm = get_coursemodule_from_instance('workshop', $workshop->id, $this->course->id, false, MUST_EXIST);
51         $this->workshop = new testable_workshop($workshop, $cm, $this->course);
52     }
54     protected function tearDown() {
55         $this->workshop = null;
56         parent::tearDown();
57     }
59     public function test_aggregate_submission_grades_process_notgraded() {
60         $this->resetAfterTest(true);
62         // fixture set-up
63         $batch = array();   // batch of a submission's assessments
64         $batch[] = (object)array('submissionid' => 12, 'submissiongrade' => null, 'weight' => 1, 'grade' => null);
65         //$DB->expectNever('update_record');
66         // exercise SUT
67         $this->workshop->aggregate_submission_grades_process($batch);
68     }
70     public function test_aggregate_submission_grades_process_single() {
71         $this->resetAfterTest(true);
73         // fixture set-up
74         $batch = array();   // batch of a submission's assessments
75         $batch[] = (object)array('submissionid' => 12, 'submissiongrade' => null, 'weight' => 1, 'grade' => 10.12345);
76         $expected = 10.12345;
77         //$DB->expectOnce('update_record');
78         // exercise SUT
79         $this->workshop->aggregate_submission_grades_process($batch);
80     }
82     public function test_aggregate_submission_grades_process_null_doesnt_influence() {
83         $this->resetAfterTest(true);
85         // fixture set-up
86         $batch = array();   // batch of a submission's assessments
87         $batch[] = (object)array('submissionid' => 12, 'submissiongrade' => null, 'weight' => 1, 'grade' => 45.54321);
88         $batch[] = (object)array('submissionid' => 12, 'submissiongrade' => null, 'weight' => 1, 'grade' => null);
89         $expected = 45.54321;
90         //$DB->expectOnce('update_record');
91         // exercise SUT
92         $this->workshop->aggregate_submission_grades_process($batch);
93     }
95     public function test_aggregate_submission_grades_process_weighted_single() {
96         $this->resetAfterTest(true);
98         // fixture set-up
99         $batch = array();   // batch of a submission's assessments
100         $batch[] = (object)array('submissionid' => 12, 'submissiongrade' => null, 'weight' => 4, 'grade' => 14.00012);
101         $expected = 14.00012;
102         //$DB->expectOnce('update_record');
103         // exercise SUT
104         $this->workshop->aggregate_submission_grades_process($batch);
105     }
107     public function test_aggregate_submission_grades_process_mean() {
108         $this->resetAfterTest(true);
110         // fixture set-up
111         $batch = array();   // batch of a submission's assessments
112         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 56.12000);
113         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 12.59000);
114         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 10.00000);
115         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 0.00000);
116         $expected = 19.67750;
117         //$DB->expectOnce('update_record');
118         // exercise SUT
119         $this->workshop->aggregate_submission_grades_process($batch);
120     }
122     public function test_aggregate_submission_grades_process_mean_changed() {
123         $this->resetAfterTest(true);
125         // fixture set-up
126         $batch = array();   // batch of a submission's assessments
127         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 12.57750, 'weight' => 1, 'grade' => 56.12000);
128         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 12.57750, 'weight' => 1, 'grade' => 12.59000);
129         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 12.57750, 'weight' => 1, 'grade' => 10.00000);
130         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 12.57750, 'weight' => 1, 'grade' => 0.00000);
131         $expected = 19.67750;
132         //$DB->expectOnce('update_record');
133         // exercise SUT
134         $this->workshop->aggregate_submission_grades_process($batch);
135     }
137     public function test_aggregate_submission_grades_process_mean_nochange() {
138         $this->resetAfterTest(true);
140         // fixture set-up
141         $batch = array();   // batch of a submission's assessments
142         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 19.67750, 'weight' => 1, 'grade' => 56.12000);
143         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 19.67750, 'weight' => 1, 'grade' => 12.59000);
144         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 19.67750, 'weight' => 1, 'grade' => 10.00000);
145         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => 19.67750, 'weight' => 1, 'grade' => 0.00000);
146         //$DB->expectNever('update_record');
147         // exercise SUT
148         $this->workshop->aggregate_submission_grades_process($batch);
149     }
151     public function test_aggregate_submission_grades_process_rounding() {
152         $this->resetAfterTest(true);
154         // fixture set-up
155         $batch = array();   // batch of a submission's assessments
156         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 4.00000);
157         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 2.00000);
158         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 1.00000);
159         $expected = 2.33333;
160         //$DB->expectOnce('update_record');
161         // exercise SUT
162         $this->workshop->aggregate_submission_grades_process($batch);
163     }
165     public function test_aggregate_submission_grades_process_weighted_mean() {
166         $this->resetAfterTest(true);
168         // fixture set-up
169         $batch = array();   // batch of a submission's assessments
170         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 3, 'grade' => 12.00000);
171         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 2, 'grade' => 30.00000);
172         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 1, 'grade' => 10.00000);
173         $batch[] = (object)array('submissionid' => 45, 'submissiongrade' => null, 'weight' => 0, 'grade' => 1000.00000);
174         $expected = 17.66667;
175         //$DB->expectOnce('update_record');
176         // exercise SUT
177         $this->workshop->aggregate_submission_grades_process($batch);
178     }
180     public function test_aggregate_grading_grades_process_nograding() {
181         $this->resetAfterTest(true);
182         // fixture set-up
183         $batch = array();
184         $batch[] = (object)array('reviewerid'=>2, 'gradinggrade'=>null, 'gradinggradeover'=>null, 'aggregationid'=>null, 'aggregatedgrade'=>null);
185         // expectation
186         //$DB->expectNever('update_record');
187         // excersise SUT
188         $this->workshop->aggregate_grading_grades_process($batch);
189     }
191     public function test_aggregate_grading_grades_process_single_grade_new() {
192         $this->resetAfterTest(true);
193         // fixture set-up
194         $batch = array();
195         $batch[] = (object)array('reviewerid'=>3, 'gradinggrade'=>82.87670, 'gradinggradeover'=>null, 'aggregationid'=>null, 'aggregatedgrade'=>null);
196         // expectation
197         $now = time();
198         $expected = new stdclass();
199         $expected->workshopid = $this->workshop->id;
200         $expected->userid = 3;
201         $expected->gradinggrade = 82.87670;
202         $expected->timegraded = $now;
203         //$DB->expectOnce('insert_record', array('workshop_aggregations', $expected));
204         // excersise SUT
205         $this->workshop->aggregate_grading_grades_process($batch, $now);
206     }
208     public function test_aggregate_grading_grades_process_single_grade_update() {
209         $this->resetAfterTest(true);
210         // fixture set-up
211         $batch = array();
212         $batch[] = (object)array('reviewerid'=>3, 'gradinggrade'=>90.00000, 'gradinggradeover'=>null, 'aggregationid'=>1, 'aggregatedgrade'=>82.87670);
213         // expectation
214         //$DB->expectOnce('update_record');
215         // excersise SUT
216         $this->workshop->aggregate_grading_grades_process($batch);
217     }
219     public function test_aggregate_grading_grades_process_single_grade_uptodate() {
220         $this->resetAfterTest(true);
221         // fixture set-up
222         $batch = array();
223         $batch[] = (object)array('reviewerid'=>3, 'gradinggrade'=>90.00000, 'gradinggradeover'=>null, 'aggregationid'=>1, 'aggregatedgrade'=>90.00000);
224         // expectation
225         //$DB->expectNever('update_record');
226         // excersise SUT
227         $this->workshop->aggregate_grading_grades_process($batch);
228     }
230     public function test_aggregate_grading_grades_process_single_grade_overridden() {
231         $this->resetAfterTest(true);
232         // fixture set-up
233         $batch = array();
234         $batch[] = (object)array('reviewerid'=>4, 'gradinggrade'=>91.56700, 'gradinggradeover'=>82.32105, 'aggregationid'=>2, 'aggregatedgrade'=>91.56700);
235         // expectation
236         //$DB->expectOnce('update_record');
237         // excersise SUT
238         $this->workshop->aggregate_grading_grades_process($batch);
239     }
241     public function test_aggregate_grading_grades_process_multiple_grades_new() {
242         $this->resetAfterTest(true);
243         // fixture set-up
244         $batch = array();
245         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>99.45670, 'gradinggradeover'=>null, 'aggregationid'=>null, 'aggregatedgrade'=>null);
246         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>87.34311, 'gradinggradeover'=>null, 'aggregationid'=>null, 'aggregatedgrade'=>null);
247         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>51.12000, 'gradinggradeover'=>null, 'aggregationid'=>null, 'aggregatedgrade'=>null);
248         // expectation
249         $now = time();
250         $expected = new stdclass();
251         $expected->workshopid = $this->workshop->id;
252         $expected->userid = 5;
253         $expected->gradinggrade = 79.3066;
254         $expected->timegraded = $now;
255         //$DB->expectOnce('insert_record', array('workshop_aggregations', $expected));
256         // excersise SUT
257         $this->workshop->aggregate_grading_grades_process($batch, $now);
258     }
260     public function test_aggregate_grading_grades_process_multiple_grades_update() {
261         $this->resetAfterTest(true);
262         // fixture set-up
263         $batch = array();
264         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>56.23400, 'gradinggradeover'=>null, 'aggregationid'=>2, 'aggregatedgrade'=>79.30660);
265         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>87.34311, 'gradinggradeover'=>null, 'aggregationid'=>2, 'aggregatedgrade'=>79.30660);
266         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>51.12000, 'gradinggradeover'=>null, 'aggregationid'=>2, 'aggregatedgrade'=>79.30660);
267         // expectation
268         //$DB->expectOnce('update_record');
269         // excersise SUT
270         $this->workshop->aggregate_grading_grades_process($batch);
271     }
273     public function test_aggregate_grading_grades_process_multiple_grades_overriden() {
274         $this->resetAfterTest(true);
275         // fixture set-up
276         $batch = array();
277         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>56.23400, 'gradinggradeover'=>99.45670, 'aggregationid'=>2, 'aggregatedgrade'=>64.89904);
278         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>87.34311, 'gradinggradeover'=>null, 'aggregationid'=>2, 'aggregatedgrade'=>64.89904);
279         $batch[] = (object)array('reviewerid'=>5, 'gradinggrade'=>51.12000, 'gradinggradeover'=>null, 'aggregationid'=>2, 'aggregatedgrade'=>64.89904);
280         // expectation
281         //$DB->expectOnce('update_record');
282         // excersise SUT
283         $this->workshop->aggregate_grading_grades_process($batch);
284     }
286     public function test_aggregate_grading_grades_process_multiple_grades_one_missing() {
287         $this->resetAfterTest(true);
288         // fixture set-up
289         $batch = array();
290         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>50.00000, 'gradinggradeover'=>null, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
291         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>null, 'gradinggradeover'=>null, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
292         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>52.20000, 'gradinggradeover'=>null, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
293         // expectation
294         //$DB->expectOnce('update_record');
295         // excersise SUT
296         $this->workshop->aggregate_grading_grades_process($batch);
297     }
299     public function test_aggregate_grading_grades_process_multiple_grades_missing_overridden() {
300         $this->resetAfterTest(true);
301         // fixture set-up
302         $batch = array();
303         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>50.00000, 'gradinggradeover'=>null, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
304         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>null, 'gradinggradeover'=>69.00000, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
305         $batch[] = (object)array('reviewerid'=>6, 'gradinggrade'=>52.20000, 'gradinggradeover'=>null, 'aggregationid'=>3, 'aggregatedgrade'=>100.00000);
306         // expectation
307         //$DB->expectOnce('update_record');
308         // excersise SUT
309         $this->workshop->aggregate_grading_grades_process($batch);
310     }
312     public function test_percent_to_value() {
313         $this->resetAfterTest(true);
314         // fixture setup
315         $total = 185;
316         $percent = 56.6543;
317         // exercise SUT
318         $part = workshop::percent_to_value($percent, $total);
319         // verify
320         $this->assertEquals($part, $total * $percent / 100);
321     }
323     /**
324      * @expectedException coding_exception
325      */
326     public function test_percent_to_value_negative() {
327         $this->resetAfterTest(true);
328         // fixture setup
329         $total = 185;
330         $percent = -7.098;
332         // exercise SUT
333         $part = workshop::percent_to_value($percent, $total);
334     }
336     /**
337      * @expectedException coding_exception
338      */
339     public function test_percent_to_value_over_hundred() {
340         $this->resetAfterTest(true);
341         // fixture setup
342         $total = 185;
343         $percent = 121.08;
345         // exercise SUT
346         $part = workshop::percent_to_value($percent, $total);
347     }
349     public function test_lcm() {
350         $this->resetAfterTest(true);
351         // fixture setup + exercise SUT + verify in one step
352         $this->assertEquals(workshop::lcm(1,4), 4);
353         $this->assertEquals(workshop::lcm(2,4), 4);
354         $this->assertEquals(workshop::lcm(4,2), 4);
355         $this->assertEquals(workshop::lcm(2,3), 6);
356         $this->assertEquals(workshop::lcm(6,4), 12);
357     }
359     public function test_lcm_array() {
360         $this->resetAfterTest(true);
361         // fixture setup
362         $numbers = array(5,3,15);
363         // excersise SUT
364         $lcm = array_reduce($numbers, 'workshop::lcm', 1);
365         // verify
366         $this->assertEquals($lcm, 15);
367     }
369     public function test_prepare_example_assessment() {
370         $this->resetAfterTest(true);
371         // fixture setup
372         $fakerawrecord = (object)array(
373             'id'                => 42,
374             'submissionid'      => 56,
375             'weight'            => 0,
376             'timecreated'       => time() - 10,
377             'timemodified'      => time() - 5,
378             'grade'             => null,
379             'gradinggrade'      => null,
380             'gradinggradeover'  => null,
381             'feedbackauthor'    => null,
382             'feedbackauthorformat' => 0,
383             'feedbackauthorattachment' => 0,
384         );
385         // excersise SUT
386         $a = $this->workshop->prepare_example_assessment($fakerawrecord);
387         // verify
388         $this->assertTrue($a instanceof workshop_example_assessment);
389         $this->assertTrue($a->url instanceof moodle_url);
391         // modify setup
392         $fakerawrecord->weight = 1;
393         $this->expectException('coding_exception');
394         // excersise SUT
395         $a = $this->workshop->prepare_example_assessment($fakerawrecord);
396     }
398     public function test_prepare_example_reference_assessment() {
399         global $USER;
400         $this->resetAfterTest(true);
401         // fixture setup
402         $fakerawrecord = (object)array(
403             'id'                => 38,
404             'submissionid'      => 56,
405             'weight'            => 1,
406             'timecreated'       => time() - 100,
407             'timemodified'      => time() - 50,
408             'grade'             => 0.75000,
409             'gradinggrade'      => 1.00000,
410             'gradinggradeover'  => null,
411             'feedbackauthor'    => null,
412             'feedbackauthorformat' => 0,
413             'feedbackauthorattachment' => 0,
414         );
415         // excersise SUT
416         $a = $this->workshop->prepare_example_reference_assessment($fakerawrecord);
417         // verify
418         $this->assertTrue($a instanceof workshop_example_reference_assessment);
420         // modify setup
421         $fakerawrecord->weight = 0;
422         $this->expectException('coding_exception');
423         // excersise SUT
424         $a = $this->workshop->prepare_example_reference_assessment($fakerawrecord);
425     }
427     /**
428      * Tests user restrictions, as they affect lists of users returned by
429      * core API functions.
430      *
431      * This includes the groupingid option (when group mode is in use), and
432      * standard activity restrictions using the availability API.
433      */
434     public function test_user_restrictions() {
435         global $DB, $CFG;
437         $this->resetAfterTest();
439         // Use existing sample course from setUp.
440         $courseid = $this->workshop->course->id;
442         // Make a test grouping and two groups.
443         $generator = $this->getDataGenerator();
444         $grouping = $generator->create_grouping(array('courseid' => $courseid));
445         $group1 = $generator->create_group(array('courseid' => $courseid));
446         groups_assign_grouping($grouping->id, $group1->id);
447         $group2 = $generator->create_group(array('courseid' => $courseid));
448         groups_assign_grouping($grouping->id, $group2->id);
450         // Group 3 is not in the grouping.
451         $group3 = $generator->create_group(array('courseid' => $courseid));
453         // Enrol some students.
454         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
455         $student1 = $generator->create_user();
456         $student2 = $generator->create_user();
457         $student3 = $generator->create_user();
458         $generator->enrol_user($student1->id, $courseid, $roleids['student']);
459         $generator->enrol_user($student2->id, $courseid, $roleids['student']);
460         $generator->enrol_user($student3->id, $courseid, $roleids['student']);
462         // Place students in groups (except student 3).
463         groups_add_member($group1, $student1);
464         groups_add_member($group2, $student2);
465         groups_add_member($group3, $student3);
467         // The existing workshop doesn't have any restrictions, so user lists
468         // should include all three users.
469         $allusers = get_enrolled_users(context_course::instance($courseid));
470         $result = $this->workshop->get_grouped($allusers);
471         $this->assertCount(4, $result);
472         $users = array_keys($result[0]);
473         sort($users);
474         $this->assertEquals(array($student1->id, $student2->id, $student3->id), $users);
475         $this->assertEquals(array($student1->id), array_keys($result[$group1->id]));
476         $this->assertEquals(array($student2->id), array_keys($result[$group2->id]));
477         $this->assertEquals(array($student3->id), array_keys($result[$group3->id]));
479         // Test get_users_with_capability_sql (via get_potential_authors).
480         $users = $this->workshop->get_potential_authors(false);
481         $this->assertCount(3, $users);
482         $users = $this->workshop->get_potential_authors(false, $group2->id);
483         $this->assertEquals(array($student2->id), array_keys($users));
485         // Create another test workshop with grouping set.
486         $workshopitem = $this->getDataGenerator()->create_module('workshop',
487                 array('course' => $courseid, 'groupmode' => SEPARATEGROUPS,
488                 'groupingid' => $grouping->id));
489         $cm = get_coursemodule_from_instance('workshop', $workshopitem->id,
490                 $courseid, false, MUST_EXIST);
491         $workshopgrouping = new testable_workshop($workshopitem, $cm, $this->workshop->course);
493         // This time the result should only include users and groups in the
494         // selected grouping.
495         $result = $workshopgrouping->get_grouped($allusers);
496         $this->assertCount(3, $result);
497         $users = array_keys($result[0]);
498         sort($users);
499         $this->assertEquals(array($student1->id, $student2->id), $users);
500         $this->assertEquals(array($student1->id), array_keys($result[$group1->id]));
501         $this->assertEquals(array($student2->id), array_keys($result[$group2->id]));
503         // Test get_users_with_capability_sql (via get_potential_authors).
504         $users = $workshopgrouping->get_potential_authors(false);
505         $userids = array_keys($users);
506         sort($userids);
507         $this->assertEquals(array($student1->id, $student2->id), $userids);
508         $users = $workshopgrouping->get_potential_authors(false, $group2->id);
509         $this->assertEquals(array($student2->id), array_keys($users));
511         // Enable the availability system and create another test workshop with
512         // availability restriction on grouping.
513         $CFG->enableavailability = true;
514         $workshopitem = $this->getDataGenerator()->create_module('workshop',
515                 array('course' => $courseid, 'availability' => json_encode(
516                     \core_availability\tree::get_root_json(array(
517                     \availability_grouping\condition::get_json($grouping->id)),
518                     \core_availability\tree::OP_AND, false))));
519         $cm = get_coursemodule_from_instance('workshop', $workshopitem->id,
520                 $courseid, false, MUST_EXIST);
521         $workshoprestricted = new testable_workshop($workshopitem, $cm, $this->workshop->course);
523         // The get_grouped function isn't intended to apply this restriction,
524         // so it should be the same as the base workshop. (Note: in reality,
525         // get_grouped is always run with the parameter being the result of
526         // one of the get_potential_xxx functions, so it works.)
527         $result = $workshoprestricted->get_grouped($allusers);
528         $this->assertCount(4, $result);
529         $this->assertCount(3, $result[0]);
531         // The get_users_with_capability_sql-based functions should apply it.
532         $users = $workshoprestricted->get_potential_authors(false);
533         $userids = array_keys($users);
534         sort($userids);
535         $this->assertEquals(array($student1->id, $student2->id), $userids);
536         $users = $workshoprestricted->get_potential_authors(false, $group2->id);
537         $this->assertEquals(array($student2->id), array_keys($users));
538     }
540     /**
541      * Test the workshop reset feature.
542      */
543     public function test_reset_phase() {
544         $this->resetAfterTest(true);
546         $this->workshop->switch_phase(workshop::PHASE_CLOSED);
547         $this->assertEquals(workshop::PHASE_CLOSED, $this->workshop->phase);
549         $settings = (object)array(
550             'reset_workshop_phase' => 0,
551         );
552         $status = $this->workshop->reset_userdata($settings);
553         $this->assertEquals(workshop::PHASE_CLOSED, $this->workshop->phase);
555         $settings = (object)array(
556             'reset_workshop_phase' => 1,
557         );
558         $status = $this->workshop->reset_userdata($settings);
559         $this->assertEquals(workshop::PHASE_SETUP, $this->workshop->phase);
560         foreach ($status as $result) {
561             $this->assertFalse($result['error']);
562         }
563     }
565     /**
566      * Test deleting assessments related data on workshop reset.
567      */
568     public function test_reset_userdata_assessments() {
569         global $DB;
570         $this->resetAfterTest(true);
572         $student1 = $this->getDataGenerator()->create_user();
573         $student2 = $this->getDataGenerator()->create_user();
575         $this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
576         $this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id);
578         $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
580         $subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
581         $subid2 = $workshopgenerator->create_submission($this->workshop->id, $student2->id);
583         $asid1 = $workshopgenerator->create_assessment($subid1, $student2->id);
584         $asid2 = $workshopgenerator->create_assessment($subid2, $student1->id);
586         $settings = (object)array(
587             'reset_workshop_assessments' => 1,
588         );
589         $status = $this->workshop->reset_userdata($settings);
591         foreach ($status as $result) {
592             $this->assertFalse($result['error']);
593         }
595         $this->assertEquals(2, $DB->count_records('workshop_submissions', array('workshopid' => $this->workshop->id)));
596         $this->assertEquals(0, $DB->count_records('workshop_assessments'));
597     }
599     /**
600      * Test deleting submissions related data on workshop reset.
601      */
602     public function test_reset_userdata_submissions() {
603         global $DB;
604         $this->resetAfterTest(true);
606         $student1 = $this->getDataGenerator()->create_user();
607         $student2 = $this->getDataGenerator()->create_user();
609         $this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
610         $this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id);
612         $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
614         $subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
615         $subid2 = $workshopgenerator->create_submission($this->workshop->id, $student2->id);
617         $asid1 = $workshopgenerator->create_assessment($subid1, $student2->id);
618         $asid2 = $workshopgenerator->create_assessment($subid2, $student1->id);
620         $settings = (object)array(
621             'reset_workshop_submissions' => 1,
622         );
623         $status = $this->workshop->reset_userdata($settings);
625         foreach ($status as $result) {
626             $this->assertFalse($result['error']);
627         }
629         $this->assertEquals(0, $DB->count_records('workshop_submissions', array('workshopid' => $this->workshop->id)));
630         $this->assertEquals(0, $DB->count_records('workshop_assessments'));
631     }
633     /**
634      * Test normalizing list of extensions.
635      */
636     public function test_normalize_file_extensions() {
637         $this->resetAfterTest(true);
639         workshop::normalize_file_extensions('');
640         $this->assertDebuggingCalled();
641     }
643     /**
644      * Test cleaning list of extensions.
645      */
646     public function test_clean_file_extensions() {
647         $this->resetAfterTest(true);
649         workshop::clean_file_extensions('');
650         $this->assertDebuggingCalledCount(2);
651     }
653     /**
654      * Test validation of the list of file extensions.
655      */
656     public function test_invalid_file_extensions() {
657         $this->resetAfterTest(true);
659         workshop::invalid_file_extensions('', '');
660         $this->assertDebuggingCalledCount(3);
661     }
663     /**
664      * Test checking file name against the list of allowed extensions.
665      */
666     public function test_is_allowed_file_type() {
667         $this->resetAfterTest(true);
669         workshop::is_allowed_file_type('', '');
670         $this->assertDebuggingCalledCount(2);
671     }
673     /**
674      * Test workshop::check_group_membership() functionality.
675      */
676     public function test_check_group_membership() {
677         global $DB, $CFG;
679         $this->resetAfterTest();
681         $courseid = $this->course->id;
682         $generator = $this->getDataGenerator();
684         // Make test groups.
685         $group1 = $generator->create_group(array('courseid' => $courseid));
686         $group2 = $generator->create_group(array('courseid' => $courseid));
687         $group3 = $generator->create_group(array('courseid' => $courseid));
689         // Revoke the accessallgroups from non-editing teachers (tutors).
690         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
691         unassign_capability('moodle/site:accessallgroups', $roleids['teacher']);
693         // Create test use accounts.
694         $teacher1 = $generator->create_user();
695         $tutor1 = $generator->create_user();
696         $tutor2 = $generator->create_user();
697         $student1 = $generator->create_user();
698         $student2 = $generator->create_user();
699         $student3 = $generator->create_user();
701         // Enrol the teacher (has the access all groups permission).
702         $generator->enrol_user($teacher1->id, $courseid, $roleids['editingteacher']);
704         // Enrol tutors (can not access all groups).
705         $generator->enrol_user($tutor1->id, $courseid, $roleids['teacher']);
706         $generator->enrol_user($tutor2->id, $courseid, $roleids['teacher']);
708         // Enrol students.
709         $generator->enrol_user($student1->id, $courseid, $roleids['student']);
710         $generator->enrol_user($student2->id, $courseid, $roleids['student']);
711         $generator->enrol_user($student3->id, $courseid, $roleids['student']);
713         // Add users in groups.
714         groups_add_member($group1, $tutor1);
715         groups_add_member($group2, $tutor2);
716         groups_add_member($group1, $student1);
717         groups_add_member($group2, $student2);
718         groups_add_member($group3, $student3);
720         // Workshop with no groups.
721         $workshopitem1 = $this->getDataGenerator()->create_module('workshop', [
722             'course' => $courseid,
723             'groupmode' => NOGROUPS,
724         ]);
725         $cm = get_coursemodule_from_instance('workshop', $workshopitem1->id, $courseid, false, MUST_EXIST);
726         $workshop1 = new testable_workshop($workshopitem1, $cm, $this->course);
728         $this->setUser($teacher1);
729         $this->assertTrue($workshop1->check_group_membership($student1->id));
730         $this->assertTrue($workshop1->check_group_membership($student2->id));
731         $this->assertTrue($workshop1->check_group_membership($student3->id));
733         $this->setUser($tutor1);
734         $this->assertTrue($workshop1->check_group_membership($student1->id));
735         $this->assertTrue($workshop1->check_group_membership($student2->id));
736         $this->assertTrue($workshop1->check_group_membership($student3->id));
738         // Workshop in visible groups mode.
739         $workshopitem2 = $this->getDataGenerator()->create_module('workshop', [
740             'course' => $courseid,
741             'groupmode' => VISIBLEGROUPS,
742         ]);
743         $cm = get_coursemodule_from_instance('workshop', $workshopitem2->id, $courseid, false, MUST_EXIST);
744         $workshop2 = new testable_workshop($workshopitem2, $cm, $this->course);
746         $this->setUser($teacher1);
747         $this->assertTrue($workshop2->check_group_membership($student1->id));
748         $this->assertTrue($workshop2->check_group_membership($student2->id));
749         $this->assertTrue($workshop2->check_group_membership($student3->id));
751         $this->setUser($tutor1);
752         $this->assertTrue($workshop2->check_group_membership($student1->id));
753         $this->assertTrue($workshop2->check_group_membership($student2->id));
754         $this->assertTrue($workshop2->check_group_membership($student3->id));
756         // Workshop in separate groups mode.
757         $workshopitem3 = $this->getDataGenerator()->create_module('workshop', [
758             'course' => $courseid,
759             'groupmode' => SEPARATEGROUPS,
760         ]);
761         $cm = get_coursemodule_from_instance('workshop', $workshopitem3->id, $courseid, false, MUST_EXIST);
762         $workshop3 = new testable_workshop($workshopitem3, $cm, $this->course);
764         $this->setUser($teacher1);
765         $this->assertTrue($workshop3->check_group_membership($student1->id));
766         $this->assertTrue($workshop3->check_group_membership($student2->id));
767         $this->assertTrue($workshop3->check_group_membership($student3->id));
769         $this->setUser($tutor1);
770         $this->assertTrue($workshop3->check_group_membership($student1->id));
771         $this->assertFalse($workshop3->check_group_membership($student2->id));
772         $this->assertFalse($workshop3->check_group_membership($student3->id));
774         $this->setUser($tutor2);
775         $this->assertFalse($workshop3->check_group_membership($student1->id));
776         $this->assertTrue($workshop3->check_group_membership($student2->id));
777         $this->assertFalse($workshop3->check_group_membership($student3->id));
778     }