Merge branch 'MDL-62397-master' of git://github.com/andrewnicols/moodle
[moodle.git] / group / tests / externallib_test.php
blobfff4079f1e723aa90da9e060e73bf8e9c291dc98
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.
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 * Group external PHPunit tests
20 * @package core_group
21 * @category external
22 * @copyright 2012 Jerome Mouneyrac
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since Moodle 2.4
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32 require_once($CFG->dirroot . '/group/externallib.php');
33 require_once($CFG->dirroot . '/group/lib.php');
35 class core_group_externallib_testcase extends externallib_advanced_testcase {
37 /**
38 * Test create_groups
40 * @expectedException required_capability_exception
42 public function test_create_groups() {
43 global $DB;
45 $this->resetAfterTest(true);
47 $course = self::getDataGenerator()->create_course();
49 $group1 = array();
50 $group1['courseid'] = $course->id;
51 $group1['name'] = 'Group Test 1';
52 $group1['description'] = 'Group Test 1 description';
53 $group1['descriptionformat'] = FORMAT_MOODLE;
54 $group1['enrolmentkey'] = 'Test group enrol secret phrase';
55 $group1['idnumber'] = 'TEST1';
56 $group2 = array();
57 $group2['courseid'] = $course->id;
58 $group2['name'] = 'Group Test 2';
59 $group2['description'] = 'Group Test 2 description';
60 $group3 = array();
61 $group3['courseid'] = $course->id;
62 $group3['name'] = 'Group Test 3';
63 $group3['description'] = 'Group Test 3 description';
64 $group3['idnumber'] = 'TEST1';
65 $group4 = array();
66 $group4['courseid'] = $course->id;
67 $group4['name'] = 'Group Test 4';
68 $group4['description'] = 'Group Test 4 description';
70 // Set the required capabilities by the external function
71 $context = context_course::instance($course->id);
72 $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
73 $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
75 // Call the external function.
76 $groups = core_group_external::create_groups(array($group1, $group2));
78 // We need to execute the return values cleaning process to simulate the web service server.
79 $groups = external_api::clean_returnvalue(core_group_external::create_groups_returns(), $groups);
81 // Checks against DB values
82 $this->assertEquals(2, count($groups));
83 foreach ($groups as $group) {
84 $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
85 switch ($dbgroup->name) {
86 case $group1['name']:
87 $groupdescription = $group1['description'];
88 $groupcourseid = $group1['courseid'];
89 $this->assertEquals($dbgroup->descriptionformat, $group1['descriptionformat']);
90 $this->assertEquals($dbgroup->enrolmentkey, $group1['enrolmentkey']);
91 $this->assertEquals($dbgroup->idnumber, $group1['idnumber']);
92 break;
93 case $group2['name']:
94 $groupdescription = $group2['description'];
95 $groupcourseid = $group2['courseid'];
96 break;
97 default:
98 throw new moodle_exception('unknowgroupname');
99 break;
101 $this->assertEquals($dbgroup->description, $groupdescription);
102 $this->assertEquals($dbgroup->courseid, $groupcourseid);
105 try {
106 $froups = core_group_external::create_groups(array($group3));
107 $this->fail('Exception expected due to already existing idnumber.');
108 } catch (moodle_exception $e) {
109 $this->assertInstanceOf('moodle_exception', $e);
110 $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
113 // Call without required capability
114 $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
115 $froups = core_group_external::create_groups(array($group4));
119 * Test get_groups
121 * @expectedException required_capability_exception
123 public function test_get_groups() {
124 global $DB;
126 $this->resetAfterTest(true);
128 $course = self::getDataGenerator()->create_course();
129 $group1data = array();
130 $group1data['courseid'] = $course->id;
131 $group1data['name'] = 'Group Test 1';
132 $group1data['description'] = 'Group Test 1 description';
133 $group1data['descriptionformat'] = FORMAT_MOODLE;
134 $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
135 $group1data['idnumber'] = 'TEST1';
136 $group2data = array();
137 $group2data['courseid'] = $course->id;
138 $group2data['name'] = 'Group Test 2';
139 $group2data['description'] = 'Group Test 2 description';
140 $group1 = self::getDataGenerator()->create_group($group1data);
141 $group2 = self::getDataGenerator()->create_group($group2data);
143 // Set the required capabilities by the external function
144 $context = context_course::instance($course->id);
145 $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
146 $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
148 // Call the external function.
149 $groups = core_group_external::get_groups(array($group1->id, $group2->id));
151 // We need to execute the return values cleaning process to simulate the web service server.
152 $groups = external_api::clean_returnvalue(core_group_external::get_groups_returns(), $groups);
154 // Checks against DB values
155 $this->assertEquals(2, count($groups));
156 foreach ($groups as $group) {
157 $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
158 switch ($dbgroup->name) {
159 case $group1->name:
160 $groupdescription = $group1->description;
161 $groupcourseid = $group1->courseid;
162 $this->assertEquals($dbgroup->descriptionformat, $group1->descriptionformat);
163 $this->assertEquals($dbgroup->enrolmentkey, $group1->enrolmentkey);
164 $this->assertEquals($dbgroup->idnumber, $group1->idnumber);
165 break;
166 case $group2->name:
167 $groupdescription = $group2->description;
168 $groupcourseid = $group2->courseid;
169 break;
170 default:
171 throw new moodle_exception('unknowgroupname');
172 break;
174 $this->assertEquals($dbgroup->description, $groupdescription);
175 $this->assertEquals($dbgroup->courseid, $groupcourseid);
178 // Call without required capability
179 $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
180 $groups = core_group_external::get_groups(array($group1->id, $group2->id));
184 * Test delete_groups
186 * @expectedException required_capability_exception
188 public function test_delete_groups() {
189 global $DB;
191 $this->resetAfterTest(true);
193 $course = self::getDataGenerator()->create_course();
194 $group1data = array();
195 $group1data['courseid'] = $course->id;
196 $group1data['name'] = 'Group Test 1';
197 $group1data['description'] = 'Group Test 1 description';
198 $group1data['descriptionformat'] = FORMAT_MOODLE;
199 $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
200 $group2data = array();
201 $group2data['courseid'] = $course->id;
202 $group2data['name'] = 'Group Test 2';
203 $group2data['description'] = 'Group Test 2 description';
204 $group3data['courseid'] = $course->id;
205 $group3data['name'] = 'Group Test 3';
206 $group3data['description'] = 'Group Test 3 description';
207 $group1 = self::getDataGenerator()->create_group($group1data);
208 $group2 = self::getDataGenerator()->create_group($group2data);
209 $group3 = self::getDataGenerator()->create_group($group3data);
211 // Set the required capabilities by the external function
212 $context = context_course::instance($course->id);
213 $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
214 $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
216 // Checks against DB values
217 $groupstotal = $DB->count_records('groups', array());
218 $this->assertEquals(3, $groupstotal);
220 // Call the external function.
221 core_group_external::delete_groups(array($group1->id, $group2->id));
223 // Checks against DB values
224 $groupstotal = $DB->count_records('groups', array());
225 $this->assertEquals(1, $groupstotal);
227 // Call without required capability
228 $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
229 $froups = core_group_external::delete_groups(array($group3->id));
233 * Test create and update groupings.
234 * @return void
236 public function test_create_update_groupings() {
237 global $DB;
239 $this->resetAfterTest(true);
241 $this->setAdminUser();
243 $course = self::getDataGenerator()->create_course();
245 $grouping1data = array();
246 $grouping1data['courseid'] = $course->id;
247 $grouping1data['name'] = 'Grouping 1 Test';
248 $grouping1data['description'] = 'Grouping 1 Test description';
249 $grouping1data['descriptionformat'] = FORMAT_MOODLE;
250 $grouping1data['idnumber'] = 'TEST';
252 $grouping1 = self::getDataGenerator()->create_grouping($grouping1data);
254 $grouping1data['name'] = 'Another group';
256 try {
257 $groupings = core_group_external::create_groupings(array($grouping1data));
258 $this->fail('Exception expected due to already existing idnumber.');
259 } catch (moodle_exception $e) {
260 $this->assertInstanceOf('moodle_exception', $e);
261 $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
264 // No exception should be triggered.
265 $grouping1data['id'] = $grouping1->id;
266 $grouping1data['idnumber'] = 'CHANGED';
267 unset($grouping1data['courseid']);
268 core_group_external::update_groupings(array($grouping1data));
270 $grouping2data = array();
271 $grouping2data['courseid'] = $course->id;
272 $grouping2data['name'] = 'Grouping 2 Test';
273 $grouping2data['description'] = 'Grouping 2 Test description';
274 $grouping2data['descriptionformat'] = FORMAT_MOODLE;
275 $grouping2data['idnumber'] = 'TEST';
277 $grouping2 = self::getDataGenerator()->create_grouping($grouping2data);
279 $grouping2data['id'] = $grouping2->id;
280 $grouping2data['idnumber'] = 'CHANGED';
281 unset($grouping2data['courseid']);
282 try {
283 $groupings = core_group_external::update_groupings(array($grouping2data));
284 $this->fail('Exception expected due to already existing idnumber.');
285 } catch (moodle_exception $e) {
286 $this->assertInstanceOf('moodle_exception', $e);
287 $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
292 * Test get_groupings
294 public function test_get_groupings() {
295 global $DB;
297 $this->resetAfterTest(true);
299 $course = self::getDataGenerator()->create_course();
301 $groupingdata = array();
302 $groupingdata['courseid'] = $course->id;
303 $groupingdata['name'] = 'Grouping Test';
304 $groupingdata['description'] = 'Grouping Test description';
305 $groupingdata['descriptionformat'] = FORMAT_MOODLE;
307 $grouping = self::getDataGenerator()->create_grouping($groupingdata);
309 // Set the required capabilities by the external function.
310 $context = context_course::instance($course->id);
311 $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
312 $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
314 // Call the external function without specifying the optional parameter.
315 $groupings = core_group_external::get_groupings(array($grouping->id));
316 // We need to execute the return values cleaning process to simulate the web service server.
317 $groupings = external_api::clean_returnvalue(core_group_external::get_groupings_returns(), $groupings);
319 $this->assertEquals(1, count($groupings));
321 $group1data = array();
322 $group1data['courseid'] = $course->id;
323 $group1data['name'] = 'Group Test 1';
324 $group1data['description'] = 'Group Test 1 description';
325 $group1data['descriptionformat'] = FORMAT_MOODLE;
326 $group2data = array();
327 $group2data['courseid'] = $course->id;
328 $group2data['name'] = 'Group Test 2';
329 $group2data['description'] = 'Group Test 2 description';
330 $group2data['descriptionformat'] = FORMAT_MOODLE;
332 $group1 = self::getDataGenerator()->create_group($group1data);
333 $group2 = self::getDataGenerator()->create_group($group2data);
335 groups_assign_grouping($grouping->id, $group1->id);
336 groups_assign_grouping($grouping->id, $group2->id);
338 // Call the external function specifying that groups are returned.
339 $groupings = core_group_external::get_groupings(array($grouping->id), true);
340 // We need to execute the return values cleaning process to simulate the web service server.
341 $groupings = external_api::clean_returnvalue(core_group_external::get_groupings_returns(), $groupings);
342 $this->assertEquals(1, count($groupings));
343 $this->assertEquals(2, count($groupings[0]['groups']));
344 foreach ($groupings[0]['groups'] as $group) {
345 $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
346 $dbgroupinggroups = $DB->get_record('groupings_groups',
347 array('groupingid' => $groupings[0]['id'],
348 'groupid' => $group['id']),
349 '*', MUST_EXIST);
350 switch ($dbgroup->name) {
351 case $group1->name:
352 $groupdescription = $group1->description;
353 $groupcourseid = $group1->courseid;
354 break;
355 case $group2->name:
356 $groupdescription = $group2->description;
357 $groupcourseid = $group2->courseid;
358 break;
359 default:
360 throw new moodle_exception('unknowgroupname');
361 break;
363 $this->assertEquals($dbgroup->description, $groupdescription);
364 $this->assertEquals($dbgroup->courseid, $groupcourseid);
369 * Test get_groups
371 public function test_get_course_user_groups() {
372 global $DB;
374 $this->resetAfterTest(true);
376 $student1 = self::getDataGenerator()->create_user();
377 $student2 = self::getDataGenerator()->create_user();
378 $teacher = self::getDataGenerator()->create_user();
380 $course = self::getDataGenerator()->create_course();
381 $emptycourse = self::getDataGenerator()->create_course();
383 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
384 $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
385 $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
387 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
388 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id);
389 $this->getDataGenerator()->enrol_user($teacher->id, $emptycourse->id, $teacherrole->id);
391 $group1data = array();
392 $group1data['courseid'] = $course->id;
393 $group1data['name'] = 'Group Test 1';
394 $group1data['description'] = 'Group Test 1 description';
395 $group1data['idnumber'] = 'TEST1';
396 $group2data = array();
397 $group2data['courseid'] = $course->id;
398 $group2data['name'] = 'Group Test 2';
399 $group2data['description'] = 'Group Test 2 description';
400 $group1 = self::getDataGenerator()->create_group($group1data);
401 $group2 = self::getDataGenerator()->create_group($group2data);
403 groups_add_member($group1->id, $student1->id);
404 groups_add_member($group1->id, $student2->id);
405 groups_add_member($group2->id, $student1->id);
407 $this->setUser($student1);
409 $groups = core_group_external::get_course_user_groups($course->id, $student1->id);
410 $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
411 // Check that I see my groups.
412 $this->assertCount(2, $groups['groups']);
414 $this->setUser($student2);
415 $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
416 $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
417 // Check that I see my groups.
418 $this->assertCount(1, $groups['groups']);
420 $this->assertEquals($group1data['name'], $groups['groups'][0]['name']);
421 $this->assertEquals($group1data['description'], $groups['groups'][0]['description']);
422 $this->assertEquals($group1data['idnumber'], $groups['groups'][0]['idnumber']);
424 $this->setUser($teacher);
425 $groups = core_group_external::get_course_user_groups($course->id, $student1->id);
426 $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
427 // Check that a teacher can see student groups.
428 $this->assertCount(2, $groups['groups']);
430 $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
431 $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
432 // Check that a teacher can see student groups.
433 $this->assertCount(1, $groups['groups']);
435 // Check permissions.
436 $this->setUser($student1);
437 try {
438 $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
439 } catch (moodle_exception $e) {
440 $this->assertEquals('accessdenied', $e->errorcode);
443 try {
444 $groups = core_group_external::get_course_user_groups($emptycourse->id, $student2->id);
445 } catch (moodle_exception $e) {
446 $this->assertEquals('requireloginerror', $e->errorcode);
449 $this->setUser($teacher);
450 // Check warnings.
451 $groups = core_group_external::get_course_user_groups($emptycourse->id, $student1->id);
452 $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
453 $this->assertCount(1, $groups['warnings']);
458 * Test get_activity_allowed_groups
460 public function test_get_activity_allowed_groups() {
461 global $DB;
463 $this->resetAfterTest(true);
465 $generator = self::getDataGenerator();
467 $student = $generator->create_user();
468 $otherstudent = $generator->create_user();
469 $teacher = $generator->create_user();
470 $course = $generator->create_course();
471 $othercourse = $generator->create_course();
473 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
474 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
475 $generator->enrol_user($student->id, $course->id, $studentrole->id);
476 $generator->enrol_user($otherstudent->id, $othercourse->id, $studentrole->id);
477 $generator->enrol_user($teacher->id, $course->id, $teacherrole->id);
479 $forum1 = $generator->create_module("forum", array('course' => $course->id), array('groupmode' => VISIBLEGROUPS));
480 $forum2 = $generator->create_module("forum", array('course' => $othercourse->id));
481 $forum3 = $generator->create_module("forum", array('course' => $course->id), array('visible' => 0));
483 // Request data for tests.
484 $cm1 = get_coursemodule_from_instance("forum", $forum1->id);
485 $cm2 = get_coursemodule_from_instance("forum", $forum2->id);
486 $cm3 = get_coursemodule_from_instance("forum", $forum3->id);
488 $group1data = array();
489 $group1data['courseid'] = $course->id;
490 $group1data['name'] = 'Group Test 1';
491 $group1data['description'] = 'Group Test 1 description';
492 $group1data['idnumber'] = 'TEST1';
493 $group2data = array();
494 $group2data['courseid'] = $course->id;
495 $group2data['name'] = 'Group Test 2';
496 $group2data['description'] = 'Group Test 2 description';
497 $group2data['idnumber'] = 'TEST2';
498 $group1 = $generator->create_group($group1data);
499 $group2 = $generator->create_group($group2data);
501 groups_add_member($group1->id, $student->id);
502 groups_add_member($group2->id, $student->id);
504 $this->setUser($student);
506 // First try possible errors.
507 try {
508 $data = core_group_external::get_activity_allowed_groups($cm2->id);
509 } catch (moodle_exception $e) {
510 $this->assertEquals('requireloginerror', $e->errorcode);
513 try {
514 $data = core_group_external::get_activity_allowed_groups($cm3->id);
515 } catch (moodle_exception $e) {
516 $this->assertEquals('requireloginerror', $e->errorcode);
519 // Retrieve my groups.
520 $groups = core_group_external::get_activity_allowed_groups($cm1->id);
521 $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
522 $this->assertCount(2, $groups['groups']);
523 $this->assertFalse($groups['canaccessallgroups']);
525 foreach ($groups['groups'] as $group) {
526 if ($group['name'] == $group1data['name']) {
527 $this->assertEquals($group1data['description'], $group['description']);
528 $this->assertEquals($group1data['idnumber'], $group['idnumber']);
529 } else {
530 $this->assertEquals($group2data['description'], $group['description']);
531 $this->assertEquals($group2data['idnumber'], $group['idnumber']);
535 $this->setUser($teacher);
536 // Retrieve other users groups.
537 $groups = core_group_external::get_activity_allowed_groups($cm1->id, $student->id);
538 $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
539 $this->assertCount(2, $groups['groups']);
540 // We are checking the $student passed as parameter so this will return false.
541 $this->assertFalse($groups['canaccessallgroups']);
543 // Check warnings. Trying to get groups for a user not enrolled in course.
544 $groups = core_group_external::get_activity_allowed_groups($cm1->id, $otherstudent->id);
545 $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
546 $this->assertCount(1, $groups['warnings']);
547 $this->assertFalse($groups['canaccessallgroups']);
549 // Checking teacher groups.
550 $groups = core_group_external::get_activity_allowed_groups($cm1->id);
551 $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
552 $this->assertCount(2, $groups['groups']);
553 // Teachers by default can access all groups.
554 $this->assertTrue($groups['canaccessallgroups']);
558 * Test get_activity_groupmode
560 public function test_get_activity_groupmode() {
561 global $DB;
563 $this->resetAfterTest(true);
565 $generator = self::getDataGenerator();
567 $student = $generator->create_user();
568 $course = $generator->create_course();
569 $othercourse = $generator->create_course();
571 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
572 $generator->enrol_user($student->id, $course->id, $studentrole->id);
574 $forum1 = $generator->create_module("forum", array('course' => $course->id), array('groupmode' => VISIBLEGROUPS));
575 $forum2 = $generator->create_module("forum", array('course' => $othercourse->id));
576 $forum3 = $generator->create_module("forum", array('course' => $course->id), array('visible' => 0));
578 // Request data for tests.
579 $cm1 = get_coursemodule_from_instance("forum", $forum1->id);
580 $cm2 = get_coursemodule_from_instance("forum", $forum2->id);
581 $cm3 = get_coursemodule_from_instance("forum", $forum3->id);
583 $this->setUser($student);
585 $data = core_group_external::get_activity_groupmode($cm1->id);
586 $data = external_api::clean_returnvalue(core_group_external::get_activity_groupmode_returns(), $data);
587 $this->assertEquals(VISIBLEGROUPS, $data['groupmode']);
589 try {
590 $data = core_group_external::get_activity_groupmode($cm2->id);
591 } catch (moodle_exception $e) {
592 $this->assertEquals('requireloginerror', $e->errorcode);
595 try {
596 $data = core_group_external::get_activity_groupmode($cm3->id);
597 } catch (moodle_exception $e) {
598 $this->assertEquals('requireloginerror', $e->errorcode);