31e24be61e80cf16e87954189ebf863e13d0140e
[moodle.git] / mod / wiki / tests / externallib_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  * Wiki module external functions tests.
19  *
20  * @package    mod_wiki
21  * @category   external
22  * @copyright  2015 Dani Palou <dani@moodle.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @since      Moodle 3.1
25  */
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32 require_once($CFG->dirroot . '/mod/wiki/lib.php');
34 /**
35  * Wiki module external functions tests
36  *
37  * @package    mod_wiki
38  * @category   external
39  * @copyright  2015 Dani Palou <dani@moodle.com>
40  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  * @since      Moodle 3.1
42  */
43 class mod_wiki_external_testcase extends externallib_advanced_testcase {
45     /**
46      * Set up for every test
47      */
48     public function setUp() {
49         global $DB;
50         $this->resetAfterTest();
51         $this->setAdminUser();
53         // Setup test data.
54         $this->course = $this->getDataGenerator()->create_course();
55         $this->wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id));
56         $this->context = context_module::instance($this->wiki->cmid);
57         $this->cm = get_coursemodule_from_instance('wiki', $this->wiki->id);
59         // Create users.
60         $this->student = self::getDataGenerator()->create_user();
61         $this->student2 = self::getDataGenerator()->create_user();
62         $this->teacher = self::getDataGenerator()->create_user();
64         // Users enrolments.
65         $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
66         $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
67         $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->studentrole->id, 'manual');
68         $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id, 'manual');
69         $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual');
71         // Create first pages.
72         $this->firstpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($this->wiki);
73     }
75     /**
76      * Create two collaborative wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
77      */
78     private function create_collaborative_wikis_with_groups() {
79         // Create groups and add student to one of them.
80         if (!isset($this->group1)) {
81             $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
82             $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
83             $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
84         }
85         if (!isset($this->group2)) {
86             $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
87         }
89         // Create two collaborative wikis.
90         $this->wikisep = $this->getDataGenerator()->create_module('wiki',
91                                                         array('course' => $this->course->id, 'groupmode' => SEPARATEGROUPS));
92         $this->wikivis = $this->getDataGenerator()->create_module('wiki',
93                                                         array('course' => $this->course->id, 'groupmode' => VISIBLEGROUPS));
95         // Create pages.
96         $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
97         $this->fpsepg1 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group1->id));
98         $this->fpsepg2 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group2->id));
99         $this->fpsepall = $wikigenerator->create_first_page($this->wikisep, array('group' => 0)); // All participants.
100         $this->fpvisg1 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group1->id));
101         $this->fpvisg2 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group2->id));
102         $this->fpvisall = $wikigenerator->create_first_page($this->wikivis, array('group' => 0)); // All participants.
103     }
105     /**
106      * Create two individual wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
107      */
108     private function create_individual_wikis_with_groups() {
109         // Create groups and add student to one of them.
110         if (!isset($this->group1)) {
111             $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
112             $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
113             $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
114         }
115         if (!isset($this->group2)) {
116             $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
117         }
119         // Create two individual wikis.
120         $this->wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
121                                                         'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual'));
122         $this->wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
123                                                         'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual'));
125         // Create pages. Student can only create pages in his groups.
126         $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
127         $this->setUser($this->teacher);
128         $this->fpsepg1indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
129         $this->fpsepg2indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group2->id));
130         $this->fpsepallindt = $wikigenerator->create_first_page($this->wikisepind, array('group' => 0)); // All participants.
131         $this->fpvisg1indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
132         $this->fpvisg2indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group2->id));
133         $this->fpvisallindt = $wikigenerator->create_first_page($this->wikivisind, array('group' => 0)); // All participants.
135         $this->setUser($this->student);
136         $this->fpsepg1indstu = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
137         $this->fpvisg1indstu = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
139         $this->setUser($this->student2);
140         $this->fpsepg1indstu2 = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
141         $this->fpvisg1indstu2 = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
143     }
145     /*
146      * Test get wikis by courses
147      */
148     public function test_mod_wiki_get_wikis_by_courses() {
150         // Create additional course.
151         $course2 = self::getDataGenerator()->create_course();
153         // Second wiki.
154         $record = new stdClass();
155         $record->course = $course2->id;
156         $wiki2 = self::getDataGenerator()->create_module('wiki', $record);
158         // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
159         $enrol = enrol_get_plugin('manual');
160         $enrolinstances = enrol_get_instances($course2->id, true);
161         foreach ($enrolinstances as $courseenrolinstance) {
162             if ($courseenrolinstance->enrol == "manual") {
163                 $instance2 = $courseenrolinstance;
164                 break;
165             }
166         }
167         $enrol->enrol_user($instance2, $this->student->id, $this->studentrole->id);
169         self::setUser($this->student);
171         $returndescription = mod_wiki_external::get_wikis_by_courses_returns();
173         // Create what we expect to be returned when querying the two courses.
174         // First for the student user.
175         $expectedfields = array('id', 'coursemodule', 'course', 'name', 'intro', 'introformat', 'firstpagetitle', 'wikimode',
176                                 'defaultformat', 'forceformat', 'editbegin', 'editend', 'section', 'visible', 'groupmode',
177                                 'groupingid');
179         // Add expected coursemodule and data.
180         $wiki1 = $this->wiki;
181         $wiki1->coursemodule = $wiki1->cmid;
182         $wiki1->introformat = 1;
183         $wiki1->section = 0;
184         $wiki1->visible = true;
185         $wiki1->groupmode = 0;
186         $wiki1->groupingid = 0;
188         $wiki2->coursemodule = $wiki2->cmid;
189         $wiki2->introformat = 1;
190         $wiki2->section = 0;
191         $wiki2->visible = true;
192         $wiki2->groupmode = 0;
193         $wiki2->groupingid = 0;
195         foreach ($expectedfields as $field) {
196             $expected1[$field] = $wiki1->{$field};
197             $expected2[$field] = $wiki2->{$field};
198         }
199         // Users can create pages by default.
200         $expected1['cancreatepages'] = true;
201         $expected2['cancreatepages'] = true;
203         $expectedwikis = array($expected2, $expected1);
205         // Call the external function passing course ids.
206         $result = mod_wiki_external::get_wikis_by_courses(array($course2->id, $this->course->id));
207         $result = external_api::clean_returnvalue($returndescription, $result);
209         $this->assertEquals($expectedwikis, $result['wikis']);
210         $this->assertCount(0, $result['warnings']);
212         // Call the external function without passing course id.
213         $result = mod_wiki_external::get_wikis_by_courses();
214         $result = external_api::clean_returnvalue($returndescription, $result);
215         $this->assertEquals($expectedwikis, $result['wikis']);
216         $this->assertCount(0, $result['warnings']);
218         // Unenrol user from second course and alter expected wikis.
219         $enrol->unenrol_user($instance2, $this->student->id);
220         array_shift($expectedwikis);
222         // Call the external function without passing course id.
223         $result = mod_wiki_external::get_wikis_by_courses();
224         $result = external_api::clean_returnvalue($returndescription, $result);
225         $this->assertEquals($expectedwikis, $result['wikis']);
227         // Call for the second course we unenrolled the user from, expected warning.
228         $result = mod_wiki_external::get_wikis_by_courses(array($course2->id));
229         $this->assertCount(1, $result['warnings']);
230         $this->assertEquals('1', $result['warnings'][0]['warningcode']);
231         $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
233         // Now, try as a teacher for getting all the additional fields.
234         self::setUser($this->teacher);
236         $additionalfields = array('timecreated', 'timemodified');
238         foreach ($additionalfields as $field) {
239             $expectedwikis[0][$field] = $wiki1->{$field};
240         }
242         $result = mod_wiki_external::get_wikis_by_courses();
243         $result = external_api::clean_returnvalue($returndescription, $result);
244         $this->assertEquals($expectedwikis, $result['wikis']);
246         // Admin also should get all the information.
247         self::setAdminUser();
249         $result = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
250         $result = external_api::clean_returnvalue($returndescription, $result);
251         $this->assertEquals($expectedwikis, $result['wikis']);
253         // Now, prohibit capabilities.
254         $this->setUser($this->student);
255         $contextcourse1 = context_course::instance($this->course->id);
256         // Prohibit capability = mod:wiki:viewpage on Course1 for students.
257         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id);
258         accesslib_clear_all_caches_for_unit_testing();
260         $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
261         $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
262         $this->assertFalse(isset($wikis['wikis'][0]['intro']));
264         // Prohibit capability = mod:wiki:createpage on Course1 for students.
265         assign_capability('mod/wiki:createpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id);
266         accesslib_clear_all_caches_for_unit_testing();
268         $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
269         $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
270         $this->assertFalse($wikis['wikis'][0]['cancreatepages']);
272     }
274     /**
275      * Test view_wiki.
276      */
277     public function test_view_wiki() {
279         // Test invalid instance id.
280         try {
281             mod_wiki_external::view_wiki(0);
282             $this->fail('Exception expected due to invalid mod_wiki instance id.');
283         } catch (moodle_exception $e) {
284             $this->assertEquals('incorrectwikiid', $e->errorcode);
285         }
287         // Test not-enrolled user.
288         $usernotenrolled = self::getDataGenerator()->create_user();
289         $this->setUser($usernotenrolled);
290         try {
291             mod_wiki_external::view_wiki($this->wiki->id);
292             $this->fail('Exception expected due to not enrolled user.');
293         } catch (moodle_exception $e) {
294             $this->assertEquals('requireloginerror', $e->errorcode);
295         }
297         // Test user with full capabilities.
298         $this->setUser($this->student);
300         // Trigger and capture the event.
301         $sink = $this->redirectEvents();
303         $result = mod_wiki_external::view_wiki($this->wiki->id);
304         $result = external_api::clean_returnvalue(mod_wiki_external::view_wiki_returns(), $result);
306         $events = $sink->get_events();
307         $this->assertCount(1, $events);
308         $event = array_shift($events);
310         // Checking that the event contains the expected values.
311         $this->assertInstanceOf('\mod_wiki\event\course_module_viewed', $event);
312         $this->assertEquals($this->context, $event->get_context());
313         $moodlewiki = new \moodle_url('/mod/wiki/view.php', array('id' => $this->cm->id));
314         $this->assertEquals($moodlewiki, $event->get_url());
315         $this->assertEventContextNotUsed($event);
316         $this->assertNotEmpty($event->get_name());
318         // Test user with no capabilities.
319         // We need a explicit prohibit since this capability is allowed for students by default.
320         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
321         accesslib_clear_all_caches_for_unit_testing();
323         try {
324             mod_wiki_external::view_wiki($this->wiki->id);
325             $this->fail('Exception expected due to missing capability.');
326         } catch (moodle_exception $e) {
327             $this->assertEquals('cannotviewpage', $e->errorcode);
328         }
330     }
332     /**
333      * Test view_page.
334      */
335     public function test_view_page() {
337         // Test invalid page id.
338         try {
339             mod_wiki_external::view_page(0);
340             $this->fail('Exception expected due to invalid view_page page id.');
341         } catch (moodle_exception $e) {
342             $this->assertEquals('incorrectpageid', $e->errorcode);
343         }
345         // Test not-enrolled user.
346         $usernotenrolled = self::getDataGenerator()->create_user();
347         $this->setUser($usernotenrolled);
348         try {
349             mod_wiki_external::view_page($this->firstpage->id);
350             $this->fail('Exception expected due to not enrolled user.');
351         } catch (moodle_exception $e) {
352             $this->assertEquals('requireloginerror', $e->errorcode);
353         }
355         // Test user with full capabilities.
356         $this->setUser($this->student);
358         // Trigger and capture the event.
359         $sink = $this->redirectEvents();
361         $result = mod_wiki_external::view_page($this->firstpage->id);
362         $result = external_api::clean_returnvalue(mod_wiki_external::view_page_returns(), $result);
364         $events = $sink->get_events();
365         $this->assertCount(1, $events);
366         $event = array_shift($events);
368         // Checking that the event contains the expected values.
369         $this->assertInstanceOf('\mod_wiki\event\page_viewed', $event);
370         $this->assertEquals($this->context, $event->get_context());
371         $pageurl = new \moodle_url('/mod/wiki/view.php', array('pageid' => $this->firstpage->id));
372         $this->assertEquals($pageurl, $event->get_url());
373         $this->assertEventContextNotUsed($event);
374         $this->assertNotEmpty($event->get_name());
376         // Test user with no capabilities.
377         // We need a explicit prohibit since this capability is allowed for students by default.
378         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
379         accesslib_clear_all_caches_for_unit_testing();
381         try {
382             mod_wiki_external::view_page($this->firstpage->id);
383             $this->fail('Exception expected due to missing capability.');
384         } catch (moodle_exception $e) {
385             $this->assertEquals('cannotviewpage', $e->errorcode);
386         }
388     }
390     /**
391      * Test get_subwikis.
392      */
393     public function test_get_subwikis() {
395         // Test invalid wiki id.
396         try {
397             mod_wiki_external::get_subwikis(0);
398             $this->fail('Exception expected due to invalid get_subwikis wiki id.');
399         } catch (moodle_exception $e) {
400             $this->assertEquals('incorrectwikiid', $e->errorcode);
401         }
403         // Test not-enrolled user.
404         $usernotenrolled = self::getDataGenerator()->create_user();
405         $this->setUser($usernotenrolled);
406         try {
407             mod_wiki_external::get_subwikis($this->wiki->id);
408             $this->fail('Exception expected due to not enrolled user.');
409         } catch (moodle_exception $e) {
410             $this->assertEquals('requireloginerror', $e->errorcode);
411         }
413         // Test user with full capabilities.
414         $this->setUser($this->student);
416         // Create what we expect to be returned. We only test a basic case because deep testing is already done
417         // in the tests for wiki_get_visible_subwikis.
418         $expectedsubwikis = array();
419         $expectedsubwiki = array(
420                 'id' => $this->firstpage->subwikiid,
421                 'wikiid' => $this->wiki->id,
422                 'groupid' => 0,
423                 'userid' => 0,
424                 'canedit' => true
425             );
426         $expectedsubwikis[] = $expectedsubwiki;
428         $result = mod_wiki_external::get_subwikis($this->wiki->id);
429         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwikis_returns(), $result);
430         $this->assertEquals($expectedsubwikis, $result['subwikis']);
431         $this->assertCount(0, $result['warnings']);
433         // Test user with no capabilities.
434         // We need a explicit prohibit since this capability is allowed for students by default.
435         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
436         accesslib_clear_all_caches_for_unit_testing();
438         try {
439             mod_wiki_external::get_subwikis($this->wiki->id);
440             $this->fail('Exception expected due to missing capability.');
441         } catch (moodle_exception $e) {
442             $this->assertEquals('nopermissions', $e->errorcode);
443         }
445     }
447     /**
448      * Test get_subwiki_pages using an invalid wiki instance.
449      */
450     public function test_get_subwiki_pages_invalid_instance() {
451         $this->setExpectedException('moodle_exception');
452         mod_wiki_external::get_subwiki_pages(0);
453     }
455     /**
456      * Test get_subwiki_pages using a user not enrolled in the course.
457      */
458     public function test_get_subwiki_pages_unenrolled_user() {
459         // Create and use the user.
460         $usernotenrolled = self::getDataGenerator()->create_user();
461         $this->setUser($usernotenrolled);
463         $this->setExpectedException('require_login_exception');
464         mod_wiki_external::get_subwiki_pages($this->wiki->id);
465     }
467     /**
468      * Test get_subwiki_pages using a hidden wiki as student.
469      */
470     public function test_get_subwiki_pages_hidden_wiki_as_student() {
471         // Create a hidden wiki and try to get the list of pages.
472         $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
473                             array('course' => $this->course->id, 'visible' => false));
475         $this->setUser($this->student);
476         $this->setExpectedException('require_login_exception');
477         mod_wiki_external::get_subwiki_pages($hiddenwiki->id);
478     }
480     /**
481      * Test get_subwiki_pages without the viewpage capability.
482      */
483     public function test_get_subwiki_pages_without_viewpage_capability() {
484         // Prohibit capability = mod/wiki:viewpage on the course for students.
485         $contextcourse = context_course::instance($this->course->id);
486         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
487         accesslib_clear_all_caches_for_unit_testing();
489         $this->setUser($this->student);
490         $this->setExpectedException('moodle_exception');
491         mod_wiki_external::get_subwiki_pages($this->wiki->id);
492     }
494     /**
495      * Test get_subwiki_pages using an invalid userid.
496      */
497     public function test_get_subwiki_pages_invalid_userid() {
498         // Create an individual wiki.
499         $indwiki = $this->getDataGenerator()->create_module('wiki',
500                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
502         $this->setExpectedException('moodle_exception');
503         mod_wiki_external::get_subwiki_pages($indwiki->id, 0, -10);
504     }
506     /**
507      * Test get_subwiki_pages using an invalid groupid.
508      */
509     public function test_get_subwiki_pages_invalid_groupid() {
510         // Create testing data.
511         $this->create_collaborative_wikis_with_groups();
513         $this->setExpectedException('moodle_exception');
514         mod_wiki_external::get_subwiki_pages($this->wikisep->id, -111);
515     }
517     /**
518      * Test get_subwiki_pages, check that a student can't see another user pages in an individual wiki without groups.
519      */
520     public function test_get_subwiki_pages_individual_student_see_other_user() {
521         // Create an individual wiki.
522         $indwiki = $this->getDataGenerator()->create_module('wiki',
523                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
525         $this->setUser($this->student);
526         $this->setExpectedException('moodle_exception');
527         mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
528     }
530     /**
531      * Test get_subwiki_pages, check that a student can't get the pages from another group in
532      * a collaborative wiki using separate groups.
533      */
534     public function test_get_subwiki_pages_collaborative_separate_groups_student_see_other_group() {
535         // Create testing data.
536         $this->create_collaborative_wikis_with_groups();
538         $this->setUser($this->student);
539         $this->setExpectedException('moodle_exception');
540         mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group2->id);
541     }
543     /**
544      * Test get_subwiki_pages, check that a student can't get the pages from another group in
545      * an individual wiki using separate groups.
546      */
547     public function test_get_subwiki_pages_individual_separate_groups_student_see_other_group() {
548         // Create testing data.
549         $this->create_individual_wikis_with_groups();
551         $this->setUser($this->student);
552         $this->setExpectedException('moodle_exception');
553         mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group2->id, $this->teacher->id);
554     }
556     /**
557      * Test get_subwiki_pages, check that a student can't get the pages from all participants in
558      * a collaborative wiki using separate groups.
559      */
560     public function test_get_subwiki_pages_collaborative_separate_groups_student_see_all_participants() {
561         // Create testing data.
562         $this->create_collaborative_wikis_with_groups();
564         $this->setUser($this->student);
565         $this->setExpectedException('moodle_exception');
566         mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
567     }
569     /**
570      * Test get_subwiki_pages, check that a student can't get the pages from all participants in
571      * an individual wiki using separate groups.
572      */
573     public function test_get_subwiki_pages_individual_separate_groups_student_see_all_participants() {
574         // Create testing data.
575         $this->create_individual_wikis_with_groups();
577         $this->setUser($this->student);
578         $this->setExpectedException('moodle_exception');
579         mod_wiki_external::get_subwiki_pages($this->wikisepind->id, 0, $this->teacher->id);
580     }
582     /**
583      * Test get_subwiki_pages without groups and collaborative wiki.
584      */
585     public function test_get_subwiki_pages_collaborative() {
587         // Test user with full capabilities.
588         $this->setUser($this->student);
590         // Set expected result: first page.
591         $expectedpages = array();
592         $expectedfirstpage = (array) $this->firstpage;
593         $expectedfirstpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
594         $expectedfirstpage['firstpage'] = true;
595         $expectedfirstpage['contentformat'] = 1;
596         $expectedpages[] = $expectedfirstpage;
598         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
599         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
600         $this->assertEquals($expectedpages, $result['pages']);
602         // Check that groupid param is ignored since the wiki isn't using groups.
603         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234);
604         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
605         $this->assertEquals($expectedpages, $result['pages']);
607         // Check that userid param is ignored since the wiki is collaborative.
608         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234, 1234);
609         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
610         $this->assertEquals($expectedpages, $result['pages']);
612         // Add a new page to the wiki and test again. We'll use a custom title so it's returned first if sorted by title.
613         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
614                                 $this->wiki, array('title' => 'AAA'));
616         $expectednewpage = (array) $newpage;
617         $expectednewpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
618         $expectednewpage['firstpage'] = false;
619         $expectednewpage['contentformat'] = 1;
620         array_unshift($expectedpages, $expectednewpage); // Add page to the beginning since it orders by title by default.
622         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
623         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
624         $this->assertEquals($expectedpages, $result['pages']);
626         // Now we'll order by ID. Since first page was created first it'll have a lower ID.
627         $expectedpages = array($expectedfirstpage, $expectednewpage);
628         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id'));
629         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
630         $this->assertEquals($expectedpages, $result['pages']);
632         // Check that WS doesn't return page content if includecontent is false.
633         unset($expectedpages[0]['cachedcontent']);
634         unset($expectedpages[0]['contentformat']);
635         unset($expectedpages[1]['cachedcontent']);
636         unset($expectedpages[1]['contentformat']);
637         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id', 'includecontent' => 0));
638         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
639         $this->assertEquals($expectedpages, $result['pages']);
640     }
642     /**
643      * Test get_subwiki_pages without groups.
644      */
645     public function test_get_subwiki_pages_individual() {
647         // Create an individual wiki to test userid param.
648         $indwiki = $this->getDataGenerator()->create_module('wiki',
649                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
651         // Perform a request before creating any page to check that an empty array is returned if subwiki doesn't exist.
652         $result = mod_wiki_external::get_subwiki_pages($indwiki->id);
653         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
654         $this->assertEquals(array(), $result['pages']);
656         // Create first pages as student and teacher.
657         $this->setUser($this->student);
658         $indfirstpagestudent = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
659         $this->setUser($this->teacher);
660         $indfirstpageteacher = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
662         // Check that teacher can get his pages.
663         $expectedteacherpage = (array) $indfirstpageteacher;
664         $expectedteacherpage['caneditpage'] = true;
665         $expectedteacherpage['firstpage'] = true;
666         $expectedteacherpage['contentformat'] = 1;
667         $expectedpages = array($expectedteacherpage);
669         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
670         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
671         $this->assertEquals($expectedpages, $result['pages']);
673         // Check that the teacher can see the student's pages.
674         $expectedstudentpage = (array) $indfirstpagestudent;
675         $expectedstudentpage['caneditpage'] = true;
676         $expectedstudentpage['firstpage'] = true;
677         $expectedstudentpage['contentformat'] = 1;
678         $expectedpages = array($expectedstudentpage);
680         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
681         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
682         $this->assertEquals($expectedpages, $result['pages']);
684         // Now check that student can get his pages.
685         $this->setUser($this->student);
687         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
688         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
689         $this->assertEquals($expectedpages, $result['pages']);
691         // Check that not using userid uses current user.
692         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0);
693         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
694         $this->assertEquals($expectedpages, $result['pages']);
695     }
697     /**
698      * Test get_subwiki_pages with groups and collaborative wikis.
699      */
700     public function test_get_subwiki_pages_separate_groups_collaborative() {
702         // Create testing data.
703         $this->create_collaborative_wikis_with_groups();
705         $this->setUser($this->student);
707         // Try to get pages from a valid group in separate groups wiki.
709         $expectedpage = (array) $this->fpsepg1;
710         $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
711         $expectedpage['firstpage'] = true;
712         $expectedpage['contentformat'] = 1;
713         $expectedpages = array($expectedpage);
715         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
716         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
717         $this->assertEquals($expectedpages, $result['pages']);
719         // Let's check that not using groupid returns the same result (current group).
720         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id);
721         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
722         $this->assertEquals($expectedpages, $result['pages']);
724         // Check that teacher can view a group pages without belonging to it.
725         $this->setUser($this->teacher);
726         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
727         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
728         $this->assertEquals($expectedpages, $result['pages']);
730         // Check that teacher can get the pages from all participants.
731         $expectedpage = (array) $this->fpsepall;
732         $expectedpage['caneditpage'] = true;
733         $expectedpage['firstpage'] = true;
734         $expectedpage['contentformat'] = 1;
735         $expectedpages = array($expectedpage);
737         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
738         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
739         $this->assertEquals($expectedpages, $result['pages']);
740     }
742     /**
743      * Test get_subwiki_pages with groups and collaborative wikis.
744      */
745     public function test_get_subwiki_pages_visible_groups_collaborative() {
747         // Create testing data.
748         $this->create_collaborative_wikis_with_groups();
750         $this->setUser($this->student);
752         // Try to get pages from a valid group in visible groups wiki.
754         $expectedpage = (array) $this->fpvisg1;
755         $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
756         $expectedpage['firstpage'] = true;
757         $expectedpage['contentformat'] = 1;
758         $expectedpages = array($expectedpage);
760         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group1->id);
761         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
762         $this->assertEquals($expectedpages, $result['pages']);
764         // Check that with visible groups a student can get the pages of groups he doesn't belong to.
765         $expectedpage = (array) $this->fpvisg2;
766         $expectedpage['caneditpage'] = false; // User doesn't belong to group so he can't edit the page.
767         $expectedpage['firstpage'] = true;
768         $expectedpage['contentformat'] = 1;
769         $expectedpages = array($expectedpage);
771         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group2->id);
772         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
773         $this->assertEquals($expectedpages, $result['pages']);
775         // Check that with visible groups a student can get the pages of all participants.
776         $expectedpage = (array) $this->fpvisall;
777         $expectedpage['caneditpage'] = false;
778         $expectedpage['firstpage'] = true;
779         $expectedpage['contentformat'] = 1;
780         $expectedpages = array($expectedpage);
782         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, 0);
783         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
784         $this->assertEquals($expectedpages, $result['pages']);
785     }
787     /**
788      * Test get_subwiki_pages with groups and individual wikis.
789      */
790     public function test_get_subwiki_pages_separate_groups_individual() {
792         // Create testing data.
793         $this->create_individual_wikis_with_groups();
795         $this->setUser($this->student);
797         // Check that student can retrieve his pages from separate wiki.
798         $expectedpage = (array) $this->fpsepg1indstu;
799         $expectedpage['caneditpage'] = true;
800         $expectedpage['firstpage'] = true;
801         $expectedpage['contentformat'] = 1;
802         $expectedpages = array($expectedpage);
804         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
805         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
806         $this->assertEquals($expectedpages, $result['pages']);
808         // Check that not using userid uses current user.
809         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id);
810         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
811         $this->assertEquals($expectedpages, $result['pages']);
813         // Check that the teacher can see the student pages.
814         $this->setUser($this->teacher);
815         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
816         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
817         $this->assertEquals($expectedpages, $result['pages']);
819         // Check that a student can see pages from another user that belongs to his groups.
820         $this->setUser($this->student);
821         $expectedpage = (array) $this->fpsepg1indstu2;
822         $expectedpage['caneditpage'] = false;
823         $expectedpage['firstpage'] = true;
824         $expectedpage['contentformat'] = 1;
825         $expectedpages = array($expectedpage);
827         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student2->id);
828         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
829         $this->assertEquals($expectedpages, $result['pages']);
830     }
832     /**
833      * Test get_subwiki_pages with groups and individual wikis.
834      */
835     public function test_get_subwiki_pages_visible_groups_individual() {
837         // Create testing data.
838         $this->create_individual_wikis_with_groups();
840         $this->setUser($this->student);
842         // Check that student can retrieve his pages from visible wiki.
843         $expectedpage = (array) $this->fpvisg1indstu;
844         $expectedpage['caneditpage'] = true;
845         $expectedpage['firstpage'] = true;
846         $expectedpage['contentformat'] = 1;
847         $expectedpages = array($expectedpage);
849         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group1->id, $this->student->id);
850         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
851         $this->assertEquals($expectedpages, $result['pages']);
853         // Check that student can see teacher pages in visible groups, even if the user doesn't belong to the group.
854         $expectedpage = (array) $this->fpvisg2indt;
855         $expectedpage['caneditpage'] = false;
856         $expectedpage['firstpage'] = true;
857         $expectedpage['contentformat'] = 1;
858         $expectedpages = array($expectedpage);
860         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group2->id, $this->teacher->id);
861         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
862         $this->assertEquals($expectedpages, $result['pages']);
864         // Check that with visible groups a student can get the pages of all participants.
865         $expectedpage = (array) $this->fpvisallindt;
866         $expectedpage['caneditpage'] = false;
867         $expectedpage['firstpage'] = true;
868         $expectedpage['contentformat'] = 1;
869         $expectedpages = array($expectedpage);
871         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, 0, $this->teacher->id);
872         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
873         $this->assertEquals($expectedpages, $result['pages']);
874     }
876     /**
877      * Test get_page_contents using an invalid pageid.
878      */
879     public function test_get_page_contents_invalid_pageid() {
880         $this->setExpectedException('moodle_exception');
881         mod_wiki_external::get_page_contents(0);
882     }
884     /**
885      * Test get_page_contents using a user not enrolled in the course.
886      */
887     public function test_get_page_contents_unenrolled_user() {
888         // Create and use the user.
889         $usernotenrolled = self::getDataGenerator()->create_user();
890         $this->setUser($usernotenrolled);
892         $this->setExpectedException('require_login_exception');
893         mod_wiki_external::get_page_contents($this->firstpage->id);
894     }
896     /**
897      * Test get_page_contents using a hidden wiki as student.
898      */
899     public function test_get_page_contents_hidden_wiki_as_student() {
900         // Create a hidden wiki and try to get a page contents.
901         $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
902                             array('course' => $this->course->id, 'visible' => false));
903         $hiddenpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($hiddenwiki);
905         $this->setUser($this->student);
906         $this->setExpectedException('require_login_exception');
907         mod_wiki_external::get_page_contents($hiddenpage->id);
908     }
910     /**
911      * Test get_page_contents without the viewpage capability.
912      */
913     public function test_get_page_contents_without_viewpage_capability() {
914         // Prohibit capability = mod/wiki:viewpage on the course for students.
915         $contextcourse = context_course::instance($this->course->id);
916         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
917         accesslib_clear_all_caches_for_unit_testing();
919         $this->setUser($this->student);
920         $this->setExpectedException('moodle_exception');
921         mod_wiki_external::get_page_contents($this->firstpage->id);
922     }
924     /**
925      * Test get_page_contents, check that a student can't get a page from another group when
926      * using separate groups.
927      */
928     public function test_get_page_contents_separate_groups_student_see_other_group() {
929         // Create testing data.
930         $this->create_individual_wikis_with_groups();
932         $this->setUser($this->student);
933         $this->setExpectedException('moodle_exception');
934         mod_wiki_external::get_page_contents($this->fpsepg2indt->id);
935     }
937     /**
938      * Test get_page_contents without groups. We won't test all the possible cases because that's already
939      * done in the tests for get_subwiki_pages.
940      */
941     public function test_get_page_contents() {
943         // Test user with full capabilities.
944         $this->setUser($this->student);
946         // Set expected result: first page.
947         $expectedpage = array(
948             'id' => $this->firstpage->id,
949             'wikiid' => $this->wiki->id,
950             'subwikiid' => $this->firstpage->subwikiid,
951             'groupid' => 0, // No groups.
952             'userid' => 0, // Collaborative.
953             'title' => $this->firstpage->title,
954             'cachedcontent' => $this->firstpage->cachedcontent,
955             'contentformat' => 1,
956             'caneditpage' => true
957         );
959         $result = mod_wiki_external::get_page_contents($this->firstpage->id);
960         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
961         $this->assertEquals($expectedpage, $result['page']);
963         // Add a new page to the wiki and test with it.
964         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wiki);
966         $expectedpage['id'] = $newpage->id;
967         $expectedpage['title'] = $newpage->title;
968         $expectedpage['cachedcontent'] = $newpage->cachedcontent;
970         $result = mod_wiki_external::get_page_contents($newpage->id);
971         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
972         $this->assertEquals($expectedpage, $result['page']);
973     }
975     /**
976      * Test get_page_contents with groups. We won't test all the possible cases because that's already
977      * done in the tests for get_subwiki_pages.
978      */
979     public function test_get_page_contents_with_groups() {
981         // Create testing data.
982         $this->create_individual_wikis_with_groups();
984         // Try to get page from a valid group in separate groups wiki.
985         $this->setUser($this->student);
987         $expectedfpsepg1indstu = array(
988             'id' => $this->fpsepg1indstu->id,
989             'wikiid' => $this->wikisepind->id,
990             'subwikiid' => $this->fpsepg1indstu->subwikiid,
991             'groupid' => $this->group1->id,
992             'userid' => $this->student->id,
993             'title' => $this->fpsepg1indstu->title,
994             'cachedcontent' => $this->fpsepg1indstu->cachedcontent,
995             'contentformat' => 1,
996             'caneditpage' => true
997         );
999         $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1000         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1001         $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1003         // Check that teacher can view a group pages without belonging to it.
1004         $this->setUser($this->teacher);
1005         $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1006         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1007         $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1008     }