2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Group external PHPunit tests
22 * @copyright 2012 Jerome Mouneyrac
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') ||
die();
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
{
40 * @expectedException required_capability_exception
42 public function test_create_groups() {
45 $this->resetAfterTest(true);
47 $course = self
::getDataGenerator()->create_course();
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';
57 $group2['courseid'] = $course->id
;
58 $group2['name'] = 'Group Test 2';
59 $group2['description'] = 'Group Test 2 description';
61 $group3['courseid'] = $course->id
;
62 $group3['name'] = 'Group Test 3';
63 $group3['description'] = 'Group Test 3 description';
64 $group3['idnumber'] = 'TEST1';
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
) {
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']);
94 $groupdescription = $group2['description'];
95 $groupcourseid = $group2['courseid'];
98 throw new moodle_exception('unknowgroupname');
101 $this->assertEquals($dbgroup->description
, $groupdescription);
102 $this->assertEquals($dbgroup->courseid
, $groupcourseid);
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));
121 * @expectedException required_capability_exception
123 public function test_get_groups() {
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
) {
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
);
167 $groupdescription = $group2->description
;
168 $groupcourseid = $group2->courseid
;
171 throw new moodle_exception('unknowgroupname');
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
));
186 * @expectedException required_capability_exception
188 public function test_delete_groups() {
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.
236 public function test_create_update_groupings() {
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';
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']);
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());
294 public function test_get_groupings() {
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']),
350 switch ($dbgroup->name
) {
352 $groupdescription = $group1->description
;
353 $groupcourseid = $group1->courseid
;
356 $groupdescription = $group2->description
;
357 $groupcourseid = $group2->courseid
;
360 throw new moodle_exception('unknowgroupname');
363 $this->assertEquals($dbgroup->description
, $groupdescription);
364 $this->assertEquals($dbgroup->courseid
, $groupcourseid);
371 public function test_get_course_user_groups() {
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);
438 $groups = core_group_external
::get_course_user_groups($course->id
, $student2->id
);
439 } catch (moodle_exception
$e) {
440 $this->assertEquals('accessdenied', $e->errorcode
);
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);
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() {
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.
508 $data = core_group_external
::get_activity_allowed_groups($cm2->id
);
509 } catch (moodle_exception
$e) {
510 $this->assertEquals('requireloginerror', $e->errorcode
);
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']);
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() {
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']);
590 $data = core_group_external
::get_activity_groupmode($cm2->id
);
591 } catch (moodle_exception
$e) {
592 $this->assertEquals('requireloginerror', $e->errorcode
);
596 $data = core_group_external
::get_activity_groupmode($cm3->id
);
597 } catch (moodle_exception
$e) {
598 $this->assertEquals('requireloginerror', $e->errorcode
);