Merge branch 'MDL-64656-master' of git://github.com/jleyva/moodle
[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             array('tags' => array('Cats', 'Dogs')));
74     }
76     /**
77      * Create two collaborative wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
78      */
79     private function create_collaborative_wikis_with_groups() {
80         // Create groups and add student to one of them.
81         if (!isset($this->group1)) {
82             $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
83             $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
84             $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
85         }
86         if (!isset($this->group2)) {
87             $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
88         }
90         // Create two collaborative wikis.
91         $this->wikisep = $this->getDataGenerator()->create_module('wiki',
92                                                         array('course' => $this->course->id, 'groupmode' => SEPARATEGROUPS));
93         $this->wikivis = $this->getDataGenerator()->create_module('wiki',
94                                                         array('course' => $this->course->id, 'groupmode' => VISIBLEGROUPS));
96         // Create pages.
97         $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
98         $this->fpsepg1 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group1->id));
99         $this->fpsepg2 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group2->id));
100         $this->fpsepall = $wikigenerator->create_first_page($this->wikisep, array('group' => 0)); // All participants.
101         $this->fpvisg1 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group1->id));
102         $this->fpvisg2 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group2->id));
103         $this->fpvisall = $wikigenerator->create_first_page($this->wikivis, array('group' => 0)); // All participants.
104     }
106     /**
107      * Create two individual wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
108      */
109     private function create_individual_wikis_with_groups() {
110         // Create groups and add student to one of them.
111         if (!isset($this->group1)) {
112             $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
113             $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
114             $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
115         }
116         if (!isset($this->group2)) {
117             $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
118         }
120         // Create two individual wikis.
121         $this->wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
122                                                         'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual'));
123         $this->wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
124                                                         'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual'));
126         // Create pages. Student can only create pages in his groups.
127         $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
128         $this->setUser($this->teacher);
129         $this->fpsepg1indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
130         $this->fpsepg2indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group2->id));
131         $this->fpsepallindt = $wikigenerator->create_first_page($this->wikisepind, array('group' => 0)); // All participants.
132         $this->fpvisg1indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
133         $this->fpvisg2indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group2->id));
134         $this->fpvisallindt = $wikigenerator->create_first_page($this->wikivisind, array('group' => 0)); // All participants.
136         $this->setUser($this->student);
137         $this->fpsepg1indstu = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
138         $this->fpvisg1indstu = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
140         $this->setUser($this->student2);
141         $this->fpsepg1indstu2 = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
142         $this->fpvisg1indstu2 = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
144     }
146     /*
147      * Test get wikis by courses
148      */
149     public function test_mod_wiki_get_wikis_by_courses() {
151         // Create additional course.
152         $course2 = self::getDataGenerator()->create_course();
154         // Second wiki.
155         $record = new stdClass();
156         $record->course = $course2->id;
157         $wiki2 = self::getDataGenerator()->create_module('wiki', $record);
159         // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
160         $enrol = enrol_get_plugin('manual');
161         $enrolinstances = enrol_get_instances($course2->id, true);
162         foreach ($enrolinstances as $courseenrolinstance) {
163             if ($courseenrolinstance->enrol == "manual") {
164                 $instance2 = $courseenrolinstance;
165                 break;
166             }
167         }
168         $enrol->enrol_user($instance2, $this->student->id, $this->studentrole->id);
170         self::setUser($this->student);
172         $returndescription = mod_wiki_external::get_wikis_by_courses_returns();
174         // Create what we expect to be returned when querying the two courses.
175         // First for the student user.
176         $expectedfields = array('id', 'coursemodule', 'course', 'name', 'intro', 'introformat', 'introfiles', 'firstpagetitle',
177                                 'wikimode', 'defaultformat', 'forceformat', 'editbegin', 'editend', 'section', 'visible',
178                                 'groupmode', 'groupingid');
180         // Add expected coursemodule and data.
181         $wiki1 = $this->wiki;
182         $wiki1->coursemodule = $wiki1->cmid;
183         $wiki1->introformat = 1;
184         $wiki1->section = 0;
185         $wiki1->visible = true;
186         $wiki1->groupmode = 0;
187         $wiki1->groupingid = 0;
188         $wiki1->introfiles = [];
190         $wiki2->coursemodule = $wiki2->cmid;
191         $wiki2->introformat = 1;
192         $wiki2->section = 0;
193         $wiki2->visible = true;
194         $wiki2->groupmode = 0;
195         $wiki2->groupingid = 0;
196         $wiki2->introfiles = [];
198         foreach ($expectedfields as $field) {
199             $expected1[$field] = $wiki1->{$field};
200             $expected2[$field] = $wiki2->{$field};
201         }
202         // Users can create pages by default.
203         $expected1['cancreatepages'] = true;
204         $expected2['cancreatepages'] = true;
206         $expectedwikis = array($expected2, $expected1);
208         // Call the external function passing course ids.
209         $result = mod_wiki_external::get_wikis_by_courses(array($course2->id, $this->course->id));
210         $result = external_api::clean_returnvalue($returndescription, $result);
212         $this->assertEquals($expectedwikis, $result['wikis']);
213         $this->assertCount(0, $result['warnings']);
215         // Call the external function without passing course id.
216         $result = mod_wiki_external::get_wikis_by_courses();
217         $result = external_api::clean_returnvalue($returndescription, $result);
218         $this->assertEquals($expectedwikis, $result['wikis']);
219         $this->assertCount(0, $result['warnings']);
221         // Unenrol user from second course and alter expected wikis.
222         $enrol->unenrol_user($instance2, $this->student->id);
223         array_shift($expectedwikis);
225         // Call the external function without passing course id.
226         $result = mod_wiki_external::get_wikis_by_courses();
227         $result = external_api::clean_returnvalue($returndescription, $result);
228         $this->assertEquals($expectedwikis, $result['wikis']);
230         // Call for the second course we unenrolled the user from, expected warning.
231         $result = mod_wiki_external::get_wikis_by_courses(array($course2->id));
232         $this->assertCount(1, $result['warnings']);
233         $this->assertEquals('1', $result['warnings'][0]['warningcode']);
234         $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
236         // Now, try as a teacher for getting all the additional fields.
237         self::setUser($this->teacher);
239         $additionalfields = array('timecreated', 'timemodified');
241         foreach ($additionalfields as $field) {
242             $expectedwikis[0][$field] = $wiki1->{$field};
243         }
245         $result = mod_wiki_external::get_wikis_by_courses();
246         $result = external_api::clean_returnvalue($returndescription, $result);
247         $this->assertEquals($expectedwikis, $result['wikis']);
249         // Admin also should get all the information.
250         self::setAdminUser();
252         $result = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
253         $result = external_api::clean_returnvalue($returndescription, $result);
254         $this->assertEquals($expectedwikis, $result['wikis']);
256         // Now, prohibit capabilities.
257         $this->setUser($this->student);
258         $contextcourse1 = context_course::instance($this->course->id);
260         // Default student role allows to view wiki and create pages.
261         $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
262         $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
263         $this->assertEquals('Test wiki 1', $wikis['wikis'][0]['intro']);
264         $this->assertEquals(1, $wikis['wikis'][0]['cancreatepages']);
266         // Prohibit capability = mod:wiki:viewpage on Course1 for students.
267         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id, true);
268         accesslib_clear_all_caches_for_unit_testing();
269         course_modinfo::clear_instance_cache(null);
271         $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
272         $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
273         $this->assertEquals(0, count($wikis['wikis']));
275         // Prohibit capability = mod:wiki:createpage on Course1 for students.
276         assign_capability('mod/wiki:viewpage', CAP_ALLOW, $this->studentrole->id, $contextcourse1->id, true);
277         assign_capability('mod/wiki:createpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id);
278         accesslib_clear_all_caches_for_unit_testing();
279         course_modinfo::clear_instance_cache(null);
281         $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
282         $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
283         $this->assertFalse($wikis['wikis'][0]['cancreatepages']);
285     }
287     /**
288      * Test view_wiki.
289      */
290     public function test_view_wiki() {
292         // Test invalid instance id.
293         try {
294             mod_wiki_external::view_wiki(0);
295             $this->fail('Exception expected due to invalid mod_wiki instance id.');
296         } catch (moodle_exception $e) {
297             $this->assertEquals('incorrectwikiid', $e->errorcode);
298         }
300         // Test not-enrolled user.
301         $usernotenrolled = self::getDataGenerator()->create_user();
302         $this->setUser($usernotenrolled);
303         try {
304             mod_wiki_external::view_wiki($this->wiki->id);
305             $this->fail('Exception expected due to not enrolled user.');
306         } catch (moodle_exception $e) {
307             $this->assertEquals('requireloginerror', $e->errorcode);
308         }
310         // Test user with full capabilities.
311         $this->setUser($this->student);
313         // Trigger and capture the event.
314         $sink = $this->redirectEvents();
316         $result = mod_wiki_external::view_wiki($this->wiki->id);
317         $result = external_api::clean_returnvalue(mod_wiki_external::view_wiki_returns(), $result);
319         $events = $sink->get_events();
320         $this->assertCount(1, $events);
321         $event = array_shift($events);
323         // Checking that the event contains the expected values.
324         $this->assertInstanceOf('\mod_wiki\event\course_module_viewed', $event);
325         $this->assertEquals($this->context, $event->get_context());
326         $moodlewiki = new \moodle_url('/mod/wiki/view.php', array('id' => $this->cm->id));
327         $this->assertEquals($moodlewiki, $event->get_url());
328         $this->assertEventContextNotUsed($event);
329         $this->assertNotEmpty($event->get_name());
331         // Test user with no capabilities.
332         // We need a explicit prohibit since this capability is allowed for students by default.
333         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
334         accesslib_clear_all_caches_for_unit_testing();
336         try {
337             mod_wiki_external::view_wiki($this->wiki->id);
338             $this->fail('Exception expected due to missing capability.');
339         } catch (moodle_exception $e) {
340             $this->assertEquals('cannotviewpage', $e->errorcode);
341         }
343     }
345     /**
346      * Test view_page.
347      */
348     public function test_view_page() {
350         // Test invalid page id.
351         try {
352             mod_wiki_external::view_page(0);
353             $this->fail('Exception expected due to invalid view_page page id.');
354         } catch (moodle_exception $e) {
355             $this->assertEquals('incorrectpageid', $e->errorcode);
356         }
358         // Test not-enrolled user.
359         $usernotenrolled = self::getDataGenerator()->create_user();
360         $this->setUser($usernotenrolled);
361         try {
362             mod_wiki_external::view_page($this->firstpage->id);
363             $this->fail('Exception expected due to not enrolled user.');
364         } catch (moodle_exception $e) {
365             $this->assertEquals('requireloginerror', $e->errorcode);
366         }
368         // Test user with full capabilities.
369         $this->setUser($this->student);
371         // Trigger and capture the event.
372         $sink = $this->redirectEvents();
374         $result = mod_wiki_external::view_page($this->firstpage->id);
375         $result = external_api::clean_returnvalue(mod_wiki_external::view_page_returns(), $result);
377         $events = $sink->get_events();
378         $this->assertCount(1, $events);
379         $event = array_shift($events);
381         // Checking that the event contains the expected values.
382         $this->assertInstanceOf('\mod_wiki\event\page_viewed', $event);
383         $this->assertEquals($this->context, $event->get_context());
384         $pageurl = new \moodle_url('/mod/wiki/view.php', array('pageid' => $this->firstpage->id));
385         $this->assertEquals($pageurl, $event->get_url());
386         $this->assertEventContextNotUsed($event);
387         $this->assertNotEmpty($event->get_name());
389         // Test user with no capabilities.
390         // We need a explicit prohibit since this capability is allowed for students by default.
391         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
392         accesslib_clear_all_caches_for_unit_testing();
394         try {
395             mod_wiki_external::view_page($this->firstpage->id);
396             $this->fail('Exception expected due to missing capability.');
397         } catch (moodle_exception $e) {
398             $this->assertEquals('cannotviewpage', $e->errorcode);
399         }
401     }
403     /**
404      * Test get_subwikis.
405      */
406     public function test_get_subwikis() {
408         // Test invalid wiki id.
409         try {
410             mod_wiki_external::get_subwikis(0);
411             $this->fail('Exception expected due to invalid get_subwikis wiki id.');
412         } catch (moodle_exception $e) {
413             $this->assertEquals('incorrectwikiid', $e->errorcode);
414         }
416         // Test not-enrolled user.
417         $usernotenrolled = self::getDataGenerator()->create_user();
418         $this->setUser($usernotenrolled);
419         try {
420             mod_wiki_external::get_subwikis($this->wiki->id);
421             $this->fail('Exception expected due to not enrolled user.');
422         } catch (moodle_exception $e) {
423             $this->assertEquals('requireloginerror', $e->errorcode);
424         }
426         // Test user with full capabilities.
427         $this->setUser($this->student);
429         // Create what we expect to be returned. We only test a basic case because deep testing is already done
430         // in the tests for wiki_get_visible_subwikis.
431         $expectedsubwikis = array();
432         $expectedsubwiki = array(
433                 'id' => $this->firstpage->subwikiid,
434                 'wikiid' => $this->wiki->id,
435                 'groupid' => 0,
436                 'userid' => 0,
437                 'canedit' => true
438             );
439         $expectedsubwikis[] = $expectedsubwiki;
441         $result = mod_wiki_external::get_subwikis($this->wiki->id);
442         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwikis_returns(), $result);
443         $this->assertEquals($expectedsubwikis, $result['subwikis']);
444         $this->assertCount(0, $result['warnings']);
446         // Test user with no capabilities.
447         // We need a explicit prohibit since this capability is allowed for students by default.
448         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
449         accesslib_clear_all_caches_for_unit_testing();
451         try {
452             mod_wiki_external::get_subwikis($this->wiki->id);
453             $this->fail('Exception expected due to missing capability.');
454         } catch (moodle_exception $e) {
455             $this->assertEquals('nopermissions', $e->errorcode);
456         }
458     }
460     /**
461      * Test get_subwiki_pages using an invalid wiki instance.
462      *
463      * @expectedException moodle_exception
464      */
465     public function test_get_subwiki_pages_invalid_instance() {
466         mod_wiki_external::get_subwiki_pages(0);
467     }
469     /**
470      * Test get_subwiki_pages using a user not enrolled in the course.
471      *
472      * @expectedException require_login_exception
473      */
474     public function test_get_subwiki_pages_unenrolled_user() {
475         // Create and use the user.
476         $usernotenrolled = self::getDataGenerator()->create_user();
477         $this->setUser($usernotenrolled);
479         mod_wiki_external::get_subwiki_pages($this->wiki->id);
480     }
482     /**
483      * Test get_subwiki_pages using a hidden wiki as student.
484      *
485      * @expectedException require_login_exception
486      */
487     public function test_get_subwiki_pages_hidden_wiki_as_student() {
488         // Create a hidden wiki and try to get the list of pages.
489         $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
490                             array('course' => $this->course->id, 'visible' => false));
492         $this->setUser($this->student);
493         mod_wiki_external::get_subwiki_pages($hiddenwiki->id);
494     }
496     /**
497      * Test get_subwiki_pages without the viewpage capability.
498      *
499      * @expectedException moodle_exception
500      */
501     public function test_get_subwiki_pages_without_viewpage_capability() {
502         // Prohibit capability = mod/wiki:viewpage on the course for students.
503         $contextcourse = context_course::instance($this->course->id);
504         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
505         accesslib_clear_all_caches_for_unit_testing();
507         $this->setUser($this->student);
508         mod_wiki_external::get_subwiki_pages($this->wiki->id);
509     }
511     /**
512      * Test get_subwiki_pages using an invalid userid.
513      *
514      * @expectedException moodle_exception
515      */
516     public function test_get_subwiki_pages_invalid_userid() {
517         // Create an individual wiki.
518         $indwiki = $this->getDataGenerator()->create_module('wiki',
519                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
521         mod_wiki_external::get_subwiki_pages($indwiki->id, 0, -10);
522     }
524     /**
525      * Test get_subwiki_pages using an invalid groupid.
526      *
527      * @expectedException moodle_exception
528      */
529     public function test_get_subwiki_pages_invalid_groupid() {
530         // Create testing data.
531         $this->create_collaborative_wikis_with_groups();
533         mod_wiki_external::get_subwiki_pages($this->wikisep->id, -111);
534     }
536     /**
537      * Test get_subwiki_pages, check that a student can't see another user pages in an individual wiki without groups.
538      *
539      * @expectedException moodle_exception
540      */
541     public function test_get_subwiki_pages_individual_student_see_other_user() {
542         // Create an individual wiki.
543         $indwiki = $this->getDataGenerator()->create_module('wiki',
544                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
546         $this->setUser($this->student);
547         mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
548     }
550     /**
551      * Test get_subwiki_pages, check that a student can't get the pages from another group in
552      * a collaborative wiki using separate groups.
553      *
554      * @expectedException moodle_exception
555      */
556     public function test_get_subwiki_pages_collaborative_separate_groups_student_see_other_group() {
557         // Create testing data.
558         $this->create_collaborative_wikis_with_groups();
560         $this->setUser($this->student);
561         mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group2->id);
562     }
564     /**
565      * Test get_subwiki_pages, check that a student can't get the pages from another group in
566      * an individual wiki using separate groups.
567      *
568      * @expectedException moodle_exception
569      */
570     public function test_get_subwiki_pages_individual_separate_groups_student_see_other_group() {
571         // Create testing data.
572         $this->create_individual_wikis_with_groups();
574         $this->setUser($this->student);
575         mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group2->id, $this->teacher->id);
576     }
578     /**
579      * Test get_subwiki_pages, check that a student can't get the pages from all participants in
580      * a collaborative wiki using separate groups.
581      *
582      * @expectedException moodle_exception
583      */
584     public function test_get_subwiki_pages_collaborative_separate_groups_student_see_all_participants() {
585         // Create testing data.
586         $this->create_collaborative_wikis_with_groups();
588         $this->setUser($this->student);
589         mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
590     }
592     /**
593      * Test get_subwiki_pages, check that a student can't get the pages from all participants in
594      * an individual wiki using separate groups.
595      *
596      * @expectedException moodle_exception
597      */
598     public function test_get_subwiki_pages_individual_separate_groups_student_see_all_participants() {
599         // Create testing data.
600         $this->create_individual_wikis_with_groups();
602         $this->setUser($this->student);
603         mod_wiki_external::get_subwiki_pages($this->wikisepind->id, 0, $this->teacher->id);
604     }
606     /**
607      * Test get_subwiki_pages without groups and collaborative wiki.
608      */
609     public function test_get_subwiki_pages_collaborative() {
611         // Test user with full capabilities.
612         $this->setUser($this->student);
614         // Set expected result: first page.
615         $expectedpages = array();
616         $expectedfirstpage = (array) $this->firstpage;
617         $expectedfirstpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
618         $expectedfirstpage['firstpage'] = true;
619         $expectedfirstpage['contentformat'] = 1;
620         $expectedfirstpage['tags'] = \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $this->firstpage->id);
621         // Cast to expected.
622         $expectedfirstpage['tags'][0]['isstandard'] = (bool) $expectedfirstpage['tags'][0]['isstandard'];
623         $expectedfirstpage['tags'][1]['isstandard'] = (bool) $expectedfirstpage['tags'][1]['isstandard'];
624         $expectedpages[] = $expectedfirstpage;
626         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
627         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
628         $this->assertEquals($expectedpages, $result['pages']);
630         // Check that groupid param is ignored since the wiki isn't using groups.
631         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234);
632         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
633         $this->assertEquals($expectedpages, $result['pages']);
635         // Check that userid param is ignored since the wiki is collaborative.
636         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234, 1234);
637         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
638         $this->assertEquals($expectedpages, $result['pages']);
640         // 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.
641         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
642                                 $this->wiki, array('title' => 'AAA'));
644         $expectednewpage = (array) $newpage;
645         $expectednewpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
646         $expectednewpage['firstpage'] = false;
647         $expectednewpage['contentformat'] = 1;
648         $expectednewpage['tags'] = array();
649         array_unshift($expectedpages, $expectednewpage); // Add page to the beginning since it orders by title by default.
651         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
652         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
653         $this->assertEquals($expectedpages, $result['pages']);
655         // Now we'll order by ID. Since first page was created first it'll have a lower ID.
656         $expectedpages = array($expectedfirstpage, $expectednewpage);
657         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id'));
658         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
659         $this->assertEquals($expectedpages, $result['pages']);
661         // Check that WS doesn't return page content if includecontent is false, it returns the size instead.
662         foreach ($expectedpages as $i => $expectedpage) {
663             if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
664                 $expectedpages[$i]['contentsize'] = mb_strlen($expectedpages[$i]['cachedcontent'], '8bit');
665             } else {
666                 $expectedpages[$i]['contentsize'] = strlen($expectedpages[$i]['cachedcontent']);
667             }
668             unset($expectedpages[$i]['cachedcontent']);
669             unset($expectedpages[$i]['contentformat']);
670         }
671         $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id', 'includecontent' => 0));
672         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
673         $this->assertEquals($expectedpages, $result['pages']);
674     }
676     /**
677      * Test get_subwiki_pages without groups.
678      */
679     public function test_get_subwiki_pages_individual() {
681         // Create an individual wiki to test userid param.
682         $indwiki = $this->getDataGenerator()->create_module('wiki',
683                                 array('course' => $this->course->id, 'wikimode' => 'individual'));
685         // Perform a request before creating any page to check that an empty array is returned if subwiki doesn't exist.
686         $result = mod_wiki_external::get_subwiki_pages($indwiki->id);
687         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
688         $this->assertEquals(array(), $result['pages']);
690         // Create first pages as student and teacher.
691         $this->setUser($this->student);
692         $indfirstpagestudent = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
693         $this->setUser($this->teacher);
694         $indfirstpageteacher = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
696         // Check that teacher can get his pages.
697         $expectedteacherpage = (array) $indfirstpageteacher;
698         $expectedteacherpage['caneditpage'] = true;
699         $expectedteacherpage['firstpage'] = true;
700         $expectedteacherpage['contentformat'] = 1;
701         $expectedteacherpage['tags'] = array();
702         $expectedpages = array($expectedteacherpage);
704         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
705         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
706         $this->assertEquals($expectedpages, $result['pages']);
708         // Check that the teacher can see the student's pages.
709         $expectedstudentpage = (array) $indfirstpagestudent;
710         $expectedstudentpage['caneditpage'] = true;
711         $expectedstudentpage['firstpage'] = true;
712         $expectedstudentpage['contentformat'] = 1;
713         $expectedstudentpage['tags'] = array();
714         $expectedpages = array($expectedstudentpage);
716         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
717         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
718         $this->assertEquals($expectedpages, $result['pages']);
720         // Now check that student can get his pages.
721         $this->setUser($this->student);
723         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
724         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
725         $this->assertEquals($expectedpages, $result['pages']);
727         // Check that not using userid uses current user.
728         $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0);
729         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
730         $this->assertEquals($expectedpages, $result['pages']);
731     }
733     /**
734      * Test get_subwiki_pages with groups and collaborative wikis.
735      */
736     public function test_get_subwiki_pages_separate_groups_collaborative() {
738         // Create testing data.
739         $this->create_collaborative_wikis_with_groups();
741         $this->setUser($this->student);
743         // Try to get pages from a valid group in separate groups wiki.
745         $expectedpage = (array) $this->fpsepg1;
746         $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
747         $expectedpage['firstpage'] = true;
748         $expectedpage['contentformat'] = 1;
749         $expectedpage['tags'] = array();
750         $expectedpages = array($expectedpage);
752         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
753         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
754         $this->assertEquals($expectedpages, $result['pages']);
756         // Let's check that not using groupid returns the same result (current group).
757         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id);
758         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
759         $this->assertEquals($expectedpages, $result['pages']);
761         // Check that teacher can view a group pages without belonging to it.
762         $this->setUser($this->teacher);
763         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
764         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
765         $this->assertEquals($expectedpages, $result['pages']);
767         // Check that teacher can get the pages from all participants.
768         $expectedpage = (array) $this->fpsepall;
769         $expectedpage['caneditpage'] = true;
770         $expectedpage['firstpage'] = true;
771         $expectedpage['contentformat'] = 1;
772         $expectedpage['tags'] = array();
773         $expectedpages = array($expectedpage);
775         $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
776         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
777         $this->assertEquals($expectedpages, $result['pages']);
778     }
780     /**
781      * Test get_subwiki_pages with groups and collaborative wikis.
782      */
783     public function test_get_subwiki_pages_visible_groups_collaborative() {
785         // Create testing data.
786         $this->create_collaborative_wikis_with_groups();
788         $this->setUser($this->student);
790         // Try to get pages from a valid group in visible groups wiki.
792         $expectedpage = (array) $this->fpvisg1;
793         $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
794         $expectedpage['firstpage'] = true;
795         $expectedpage['contentformat'] = 1;
796         $expectedpage['tags'] = array();
797         $expectedpages = array($expectedpage);
799         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group1->id);
800         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
801         $this->assertEquals($expectedpages, $result['pages']);
803         // Check that with visible groups a student can get the pages of groups he doesn't belong to.
804         $expectedpage = (array) $this->fpvisg2;
805         $expectedpage['caneditpage'] = false; // User doesn't belong to group so he can't edit the page.
806         $expectedpage['firstpage'] = true;
807         $expectedpage['contentformat'] = 1;
808         $expectedpage['tags'] = array();
809         $expectedpages = array($expectedpage);
811         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group2->id);
812         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
813         $this->assertEquals($expectedpages, $result['pages']);
815         // Check that with visible groups a student can get the pages of all participants.
816         $expectedpage = (array) $this->fpvisall;
817         $expectedpage['caneditpage'] = false;
818         $expectedpage['firstpage'] = true;
819         $expectedpage['contentformat'] = 1;
820         $expectedpage['tags'] = array();
821         $expectedpages = array($expectedpage);
823         $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, 0);
824         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
825         $this->assertEquals($expectedpages, $result['pages']);
826     }
828     /**
829      * Test get_subwiki_pages with groups and individual wikis.
830      */
831     public function test_get_subwiki_pages_separate_groups_individual() {
833         // Create testing data.
834         $this->create_individual_wikis_with_groups();
836         $this->setUser($this->student);
838         // Check that student can retrieve his pages from separate wiki.
839         $expectedpage = (array) $this->fpsepg1indstu;
840         $expectedpage['caneditpage'] = true;
841         $expectedpage['firstpage'] = true;
842         $expectedpage['contentformat'] = 1;
843         $expectedpage['tags'] = array();
844         $expectedpages = array($expectedpage);
846         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
847         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
848         $this->assertEquals($expectedpages, $result['pages']);
850         // Check that not using userid uses current user.
851         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id);
852         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
853         $this->assertEquals($expectedpages, $result['pages']);
855         // Check that the teacher can see the student pages.
856         $this->setUser($this->teacher);
857         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
858         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
859         $this->assertEquals($expectedpages, $result['pages']);
861         // Check that a student can see pages from another user that belongs to his groups.
862         $this->setUser($this->student);
863         $expectedpage = (array) $this->fpsepg1indstu2;
864         $expectedpage['caneditpage'] = false;
865         $expectedpage['firstpage'] = true;
866         $expectedpage['contentformat'] = 1;
867         $expectedpage['tags'] = array();
868         $expectedpages = array($expectedpage);
870         $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student2->id);
871         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
872         $this->assertEquals($expectedpages, $result['pages']);
873     }
875     /**
876      * Test get_subwiki_pages with groups and individual wikis.
877      */
878     public function test_get_subwiki_pages_visible_groups_individual() {
880         // Create testing data.
881         $this->create_individual_wikis_with_groups();
883         $this->setUser($this->student);
885         // Check that student can retrieve his pages from visible wiki.
886         $expectedpage = (array) $this->fpvisg1indstu;
887         $expectedpage['caneditpage'] = true;
888         $expectedpage['firstpage'] = true;
889         $expectedpage['contentformat'] = 1;
890         $expectedpage['tags'] = array();
891         $expectedpages = array($expectedpage);
893         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group1->id, $this->student->id);
894         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
895         $this->assertEquals($expectedpages, $result['pages']);
897         // Check that student can see teacher pages in visible groups, even if the user doesn't belong to the group.
898         $expectedpage = (array) $this->fpvisg2indt;
899         $expectedpage['caneditpage'] = false;
900         $expectedpage['firstpage'] = true;
901         $expectedpage['contentformat'] = 1;
902         $expectedpage['tags'] = array();
903         $expectedpages = array($expectedpage);
905         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group2->id, $this->teacher->id);
906         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
907         $this->assertEquals($expectedpages, $result['pages']);
909         // Check that with visible groups a student can get the pages of all participants.
910         $expectedpage = (array) $this->fpvisallindt;
911         $expectedpage['caneditpage'] = false;
912         $expectedpage['firstpage'] = true;
913         $expectedpage['contentformat'] = 1;
914         $expectedpage['tags'] = array();
915         $expectedpages = array($expectedpage);
917         $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, 0, $this->teacher->id);
918         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
919         $this->assertEquals($expectedpages, $result['pages']);
920     }
922     /**
923      * Test get_page_contents using an invalid pageid.
924      *
925      * @expectedException moodle_exception
926      */
927     public function test_get_page_contents_invalid_pageid() {
928         mod_wiki_external::get_page_contents(0);
929     }
931     /**
932      * Test get_page_contents using a user not enrolled in the course.
933      *
934      * @expectedException require_login_exception
935      */
936     public function test_get_page_contents_unenrolled_user() {
937         // Create and use the user.
938         $usernotenrolled = self::getDataGenerator()->create_user();
939         $this->setUser($usernotenrolled);
941         mod_wiki_external::get_page_contents($this->firstpage->id);
942     }
944     /**
945      * Test get_page_contents using a hidden wiki as student.
946      *
947      * @expectedException require_login_exception
948      */
949     public function test_get_page_contents_hidden_wiki_as_student() {
950         // Create a hidden wiki and try to get a page contents.
951         $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
952                             array('course' => $this->course->id, 'visible' => false));
953         $hiddenpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($hiddenwiki);
955         $this->setUser($this->student);
956         mod_wiki_external::get_page_contents($hiddenpage->id);
957     }
959     /**
960      * Test get_page_contents without the viewpage capability.
961      *
962      * @expectedException moodle_exception
963      */
964     public function test_get_page_contents_without_viewpage_capability() {
965         // Prohibit capability = mod/wiki:viewpage on the course for students.
966         $contextcourse = context_course::instance($this->course->id);
967         assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
968         accesslib_clear_all_caches_for_unit_testing();
970         $this->setUser($this->student);
971         mod_wiki_external::get_page_contents($this->firstpage->id);
972     }
974     /**
975      * Test get_page_contents, check that a student can't get a page from another group when
976      * using separate groups.
977      *
978      * @expectedException moodle_exception
979      */
980     public function test_get_page_contents_separate_groups_student_see_other_group() {
981         // Create testing data.
982         $this->create_individual_wikis_with_groups();
984         $this->setUser($this->student);
985         mod_wiki_external::get_page_contents($this->fpsepg2indt->id);
986     }
988     /**
989      * Test get_page_contents without groups. We won't test all the possible cases because that's already
990      * done in the tests for get_subwiki_pages.
991      */
992     public function test_get_page_contents() {
994         // Test user with full capabilities.
995         $this->setUser($this->student);
997         // Set expected result: first page.
998         $expectedpage = array(
999             'id' => $this->firstpage->id,
1000             'wikiid' => $this->wiki->id,
1001             'subwikiid' => $this->firstpage->subwikiid,
1002             'groupid' => 0, // No groups.
1003             'userid' => 0, // Collaborative.
1004             'title' => $this->firstpage->title,
1005             'cachedcontent' => $this->firstpage->cachedcontent,
1006             'contentformat' => 1,
1007             'caneditpage' => true,
1008             'version' => 1,
1009             'tags' => \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $this->firstpage->id),
1010         );
1011         // Cast to expected.
1012         $expectedpage['tags'][0]['isstandard'] = (bool) $expectedpage['tags'][0]['isstandard'];
1013         $expectedpage['tags'][1]['isstandard'] = (bool) $expectedpage['tags'][1]['isstandard'];
1015         $result = mod_wiki_external::get_page_contents($this->firstpage->id);
1016         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1017         $this->assertEquals($expectedpage, $result['page']);
1019         // Add a new page to the wiki and test with it.
1020         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wiki);
1022         $expectedpage['id'] = $newpage->id;
1023         $expectedpage['title'] = $newpage->title;
1024         $expectedpage['cachedcontent'] = $newpage->cachedcontent;
1025         $expectedpage['tags'] = array();
1027         $result = mod_wiki_external::get_page_contents($newpage->id);
1028         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1029         $this->assertEquals($expectedpage, $result['page']);
1030     }
1032     /**
1033      * Test get_page_contents with groups. We won't test all the possible cases because that's already
1034      * done in the tests for get_subwiki_pages.
1035      */
1036     public function test_get_page_contents_with_groups() {
1038         // Create testing data.
1039         $this->create_individual_wikis_with_groups();
1041         // Try to get page from a valid group in separate groups wiki.
1042         $this->setUser($this->student);
1044         $expectedfpsepg1indstu = array(
1045             'id' => $this->fpsepg1indstu->id,
1046             'wikiid' => $this->wikisepind->id,
1047             'subwikiid' => $this->fpsepg1indstu->subwikiid,
1048             'groupid' => $this->group1->id,
1049             'userid' => $this->student->id,
1050             'title' => $this->fpsepg1indstu->title,
1051             'cachedcontent' => $this->fpsepg1indstu->cachedcontent,
1052             'contentformat' => 1,
1053             'caneditpage' => true,
1054             'version' => 1,
1055             'tags' => array(),
1056         );
1058         $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1059         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1060         $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1062         // Check that teacher can view a group pages without belonging to it.
1063         $this->setUser($this->teacher);
1064         $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1065         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1066         $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1067     }
1069     /**
1070      * Test get_subwiki_files using a wiki without files.
1071      */
1072     public function test_get_subwiki_files_no_files() {
1073         $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1074         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1075         $this->assertCount(0, $result['files']);
1076         $this->assertCount(0, $result['warnings']);
1077     }
1079     /**
1080      * Test get_subwiki_files, check that a student can't get files from another group's subwiki when
1081      * using separate groups.
1082      *
1083      * @expectedException moodle_exception
1084      */
1085     public function test_get_subwiki_files_separate_groups_student_see_other_group() {
1086         // Create testing data.
1087         $this->create_collaborative_wikis_with_groups();
1089         $this->setUser($this->student);
1090         mod_wiki_external::get_subwiki_files($this->wikisep->id, $this->group2->id);
1091     }
1093     /**
1094      * Test get_subwiki_files using a collaborative wiki without groups.
1095      */
1096     public function test_get_subwiki_files_collaborative_no_groups() {
1097         $this->setUser($this->student);
1099         // Add a file as subwiki attachment.
1100         $fs = get_file_storage();
1101         $file = array('component' => 'mod_wiki', 'filearea' => 'attachments',
1102                 'contextid' => $this->context->id, 'itemid' => $this->firstpage->subwikiid,
1103                 'filename' => 'image.jpg', 'filepath' => '/', 'timemodified' => time());
1104         $content = 'IMAGE';
1105         $fs->create_file_from_string($file, $content);
1107         $expectedfile = array(
1108             'filename' => $file['filename'],
1109             'filepath' => $file['filepath'],
1110             'mimetype' => 'image/jpeg',
1111             'isexternalfile' => false,
1112             'filesize' => strlen($content),
1113             'timemodified' => $file['timemodified'],
1114             'fileurl' => moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1115                             $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']),
1116         );
1118         // Call the WS and check that it returns this file.
1119         $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1120         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1121         $this->assertCount(1, $result['files']);
1122         $this->assertEquals($expectedfile, $result['files'][0]);
1124         // Now add another file to the same subwiki.
1125         $file['filename'] = 'Another image.jpg';
1126         $file['timemodified'] = time();
1127         $content = 'ANOTHER IMAGE';
1128         $fs->create_file_from_string($file, $content);
1130         $expectedfile['filename'] = $file['filename'];
1131         $expectedfile['timemodified'] = $file['timemodified'];
1132         $expectedfile['filesize'] = strlen($content);
1133         $expectedfile['fileurl'] = moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1134                             $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']);
1136         // Call the WS and check that it returns both files file.
1137         $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1138         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1139         $this->assertCount(2, $result['files']);
1140         // The new file is returned first because they're returned in alphabetical order.
1141         $this->assertEquals($expectedfile, $result['files'][0]);
1142     }
1144     /**
1145      * Test get_subwiki_files using an individual wiki with visible groups.
1146      */
1147     public function test_get_subwiki_files_visible_groups_individual() {
1148         // Create testing data.
1149         $this->create_individual_wikis_with_groups();
1151         $this->setUser($this->student);
1153         // Add a file as subwiki attachment in the student group 1 subwiki.
1154         $fs = get_file_storage();
1155         $contextwiki = context_module::instance($this->wikivisind->cmid);
1156         $file = array('component' => 'mod_wiki', 'filearea' => 'attachments',
1157                 'contextid' => $contextwiki->id, 'itemid' => $this->fpvisg1indstu->subwikiid,
1158                 'filename' => 'image.jpg', 'filepath' => '/', 'timemodified' => time());
1159         $content = 'IMAGE';
1160         $fs->create_file_from_string($file, $content);
1162         $expectedfile = array(
1163             'filename' => $file['filename'],
1164             'filepath' => $file['filepath'],
1165             'mimetype' => 'image/jpeg',
1166             'isexternalfile' => false,
1167             'filesize' => strlen($content),
1168             'timemodified' => $file['timemodified'],
1169             'fileurl' => moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1170                             $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']),
1171         );
1173         // Call the WS and check that it returns this file.
1174         $result = mod_wiki_external::get_subwiki_files($this->wikivisind->id, $this->group1->id);
1175         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1176         $this->assertCount(1, $result['files']);
1177         $this->assertEquals($expectedfile, $result['files'][0]);
1179         // Now check that a teacher can see it too.
1180         $this->setUser($this->teacher);
1181         $result = mod_wiki_external::get_subwiki_files($this->wikivisind->id, $this->group1->id, $this->student->id);
1182         $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1183         $this->assertCount(1, $result['files']);
1184         $this->assertEquals($expectedfile, $result['files'][0]);
1185     }
1188     /**
1189      * Test get_page_for_editing. We won't test all the possible cases because that's already
1190      * done in the tests for wiki_parser_proxy::get_section.
1191      */
1192     public function test_get_page_for_editing() {
1194         $this->create_individual_wikis_with_groups();
1196         // We add a <span> in the first title to verify the WS works sending HTML in section.
1197         $sectioncontent = '<h1><span>Title1</span></h1>Text inside section';
1198         $pagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
1199         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
1200                                 $this->wiki, array('content' => $pagecontent));
1202         // Test user with full capabilities.
1203         $this->setUser($this->student);
1205         // Set expected result: Full Page content.
1206         $expected = array(
1207             'content' => $pagecontent,
1208             'contentformat' => 'html',
1209             'version' => '1'
1210         );
1212         $result = mod_wiki_external::get_page_for_editing($newpage->id);
1213         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1214         $this->assertEquals($expected, $result['pagesection']);
1216         // Set expected result: Section Page content.
1217         $expected = array(
1218             'content' => $sectioncontent,
1219             'contentformat' => 'html',
1220             'version' => '1'
1221         );
1223         $result = mod_wiki_external::get_page_for_editing($newpage->id, '<span>Title1</span>');
1224         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1225         $this->assertEquals($expected, $result['pagesection']);
1226     }
1228     /**
1229      * Test test_get_page_locking.
1230      */
1231     public function test_get_page_locking() {
1233         $this->create_individual_wikis_with_groups();
1235         $pagecontent = '<h1>Title1</h1>Text inside section<h1>Title2</h1>Text inside section';
1236         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
1237                                 $this->wiki, array('content' => $pagecontent));
1239         // Test user with full capabilities.
1240         $this->setUser($this->student);
1242         // Test Section locking.
1243         $expected = array(
1244             'version' => '1'
1245         );
1247         $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1248         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1249         $this->assertEquals($expected, $result['pagesection']);
1251         // Test the section is locked.
1252         $this->setUser($this->student2);
1253         try {
1254             mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1255             $this->fail('Exception expected due to not page locking.');
1256         } catch (moodle_exception $e) {
1257             $this->assertEquals('pageislocked', $e->errorcode);
1258         }
1260         // Test the page is locked.
1261         try {
1262             mod_wiki_external::get_page_for_editing($newpage->id, null, true);
1263             $this->fail('Exception expected due to not page locking.');
1264         } catch (moodle_exception $e) {
1265             $this->assertEquals('pageislocked', $e->errorcode);
1266         }
1268         // Test the other section is not locked.
1269         $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title2', true);
1270         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1271         $this->assertEquals($expected, $result['pagesection']);
1273         // Back to the original user to test version change when editing.
1274         $this->setUser($this->student);
1275         $newsectioncontent = '<h1>Title2</h1>New test2';
1276         $result = mod_wiki_external::edit_page($newpage->id, $newsectioncontent, 'Title1');
1278         $expected = array(
1279             'version' => '2'
1280         );
1281         $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1282         $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1283         $this->assertEquals($expected, $result['pagesection']);
1284     }
1286     /**
1287      * Test new_page. We won't test all the possible cases because that's already
1288      * done in the tests for wiki_create_page.
1289      */
1290     public function test_new_page() {
1292         $this->create_individual_wikis_with_groups();
1294         $sectioncontent = '<h1>Title1</h1>Text inside section';
1295         $pagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
1296         $pagetitle = 'Page Title';
1298         // Test user with full capabilities.
1299         $this->setUser($this->student);
1301         // Test on existing subwiki.
1302         $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid);
1303         $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result);
1304         $this->assertInternalType('int', $result['pageid']);
1306         $version = wiki_get_current_version($result['pageid']);
1307         $this->assertEquals($pagecontent, $version->content);
1308         $this->assertEquals('html', $version->contentformat);
1310         $page = wiki_get_page($result['pageid']);
1311         $this->assertEquals($pagetitle, $page->title);
1313         // Test existing page creation.
1314         try {
1315             mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid);
1316             $this->fail('Exception expected due to creation of an existing page.');
1317         } catch (moodle_exception $e) {
1318             $this->assertEquals('pageexists', $e->errorcode);
1319         }
1321         // Test on non existing subwiki. Add student to group2 to have a new subwiki to be created.
1322         $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group2->id));
1323         $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id, $this->student->id,
1324             $this->group2->id);
1325         $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result);
1326         $this->assertInternalType('int', $result['pageid']);
1328         $version = wiki_get_current_version($result['pageid']);
1329         $this->assertEquals($pagecontent, $version->content);
1330         $this->assertEquals('html', $version->contentformat);
1332         $page = wiki_get_page($result['pageid']);
1333         $this->assertEquals($pagetitle, $page->title);
1335         $subwiki = wiki_get_subwiki($page->subwikiid);
1336         $expected = new StdClass();
1337         $expected->id = $subwiki->id;
1338         $expected->wikiid = $this->wikisepind->id;
1339         $expected->groupid = $this->group2->id;
1340         $expected->userid = $this->student->id;
1341         $this->assertEquals($expected, $subwiki);
1343         // Check page creation for a user not in course.
1344         $this->studentnotincourse = self::getDataGenerator()->create_user();
1345         $this->anothercourse = $this->getDataGenerator()->create_course();
1346         $this->groupnotincourse = $this->getDataGenerator()->create_group(array('courseid' => $this->anothercourse->id));
1348         try {
1349             mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id,
1350                 $this->studentnotincourse->id, $this->groupnotincourse->id);
1351             $this->fail('Exception expected due to creation of an invalid subwiki creation.');
1352         } catch (moodle_exception $e) {
1353             $this->assertEquals('cannoteditpage', $e->errorcode);
1354         }
1356     }
1358     /**
1359      * Test edit_page. We won't test all the possible cases because that's already
1360      * done in the tests for wiki_save_section / wiki_save_page.
1361      */
1362     public function test_edit_page() {
1364         $this->create_individual_wikis_with_groups();
1366         // Test user with full capabilities.
1367         $this->setUser($this->student);
1369         $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wikisepind,
1370             array('group' => $this->group1->id, 'content' => 'Test'));
1372         // Test edit whole page.
1373         // We add <span> in the titles to verify the WS works sending HTML in section.
1374         $sectioncontent = '<h1><span>Title1</span></h1>Text inside section';
1375         $newpagecontent = $sectioncontent.'<h1><span>Title2</span></h1>Text inside section';
1377         $result = mod_wiki_external::edit_page($newpage->id, $newpagecontent);
1378         $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
1379         $this->assertInternalType('int', $result['pageid']);
1381         $version = wiki_get_current_version($result['pageid']);
1382         $this->assertEquals($newpagecontent, $version->content);
1384         // Test edit section.
1385         $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1386         $section = '<span>Title2</span>';
1388         $result = mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1389         $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
1390         $this->assertInternalType('int', $result['pageid']);
1392         $expected = $sectioncontent . $newsectioncontent;
1394         $version = wiki_get_current_version($result['pageid']);
1395         $this->assertEquals($expected, $version->content);
1397         // Test locked section.
1398         $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1399         $section = '<span>Title2</span>';
1401         try {
1402             // Using user 1 to avoid other users to edit.
1403             wiki_set_lock($newpage->id, 1, $section, true);
1404             mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1405             $this->fail('Exception expected due to locked section');
1406         } catch (moodle_exception $e) {
1407             $this->assertEquals('pageislocked', $e->errorcode);
1408         }
1410         // Test edit non existing section.
1411         $newsectioncontent = '<h1>Title3</h1>New test3';
1412         $section = 'Title3';
1414         try {
1415             mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1416             $this->fail('Exception expected due to non existing section in the page.');
1417         } catch (moodle_exception $e) {
1418             $this->assertEquals('invalidsection', $e->errorcode);
1419         }
1421     }