Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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/>.
16
 
17
namespace mod_wiki;
18
 
19
use core_external\external_api;
20
use externallib_advanced_testcase;
21
use mod_wiki_external;
22
 
23
defined('MOODLE_INTERNAL') || die();
24
 
25
global $CFG;
26
 
27
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
28
require_once($CFG->dirroot . '/mod/wiki/lib.php');
29
 
30
/**
31
 * Wiki module external functions tests
32
 *
33
 * @package    mod_wiki
34
 * @category   external
35
 * @copyright  2015 Dani Palou <dani@moodle.com>
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 * @since      Moodle 3.1
38
 */
39
class externallib_test extends externallib_advanced_testcase {
40
 
41
    /** @var \stdClass course record. */
42
    protected $course;
43
 
44
    /** @var \stdClass activity record. */
45
    protected $wiki;
46
 
47
    /** @var \stdClass activity record. */
48
    protected $wikisep;
49
 
50
    /** @var \stdClass activity record. */
51
    protected $wikivis;
52
 
53
    /** @var \stdClass activity record. */
54
    protected $wikisepind;
55
 
56
    /** @var \stdClass activity record. */
57
    protected $wikivisind;
58
 
59
    /** @var \context_module context instance. */
60
    protected $context;
61
 
62
    /** @var \StdClass */
63
    protected $cm;
64
 
65
    /** @var \stdClass user record. */
66
    protected $student;
67
 
68
    /** @var \stdClass user record. */
69
    protected $student2;
70
 
71
    /** @var \stdClass user record. */
72
    protected $teacher;
73
 
74
    /** @var mixed a fieldset object, false or exception if error not found. */
75
    protected $studentrole;
76
 
77
    /** @var mixed a fieldset object, false or exception if error not found. */
78
    protected $teacherrole;
79
 
80
    /** @var \stdClass first page. */
81
    protected $firstpage;
82
 
83
    /** @var \stdClass group record */
84
    protected $group1;
85
 
86
    /** @var \stdClass group record */
87
    protected $group2;
88
 
89
    /** @var \stdClass first page. */
90
    protected $fpsepg1;
91
 
92
    /** @var \stdClass first page. */
93
    protected $fpsepg2;
94
 
95
    /** @var \stdClass first page. */
96
    protected $fpsepall;
97
 
98
    /** @var \stdClass first page. */
99
    protected $fpvisg1;
100
 
101
    /** @var \stdClass first page. */
102
    protected $fpvisg2;
103
 
104
    /** @var \stdClass first page. */
105
    protected $fpvisall;
106
 
107
    /** @var \stdClass first page. */
108
    protected $fpsepg1indt;
109
 
110
    /** @var \stdClass first page. */
111
    protected $fpsepg2indt;
112
 
113
    /** @var \stdClass first page. */
114
    protected $fpsepallindt;
115
 
116
    /** @var \stdClass first page. */
117
    protected $fpvisg1indt;
118
 
119
    /** @var \stdClass first page. */
120
    protected $fpvisg2indt;
121
 
122
    /** @var \stdClass first page. */
123
    protected $fpvisallindt;
124
 
125
    /** @var \stdClass first page. */
126
    protected $fpsepg1indstu;
127
 
128
    /** @var \stdClass first page. */
129
    protected $fpvisg1indstu;
130
 
131
    /** @var \stdClass first page. */
132
    protected $fpsepg1indstu2;
133
 
134
    /** @var \stdClass first page. */
135
    protected $fpvisg1indstu2;
136
 
137
    /** @var \stdClass user record. */
138
    protected $studentnotincourse;
139
 
140
    /** @var \stdClass course record. */
141
    protected $anothercourse;
142
 
143
    /** @var \stdClass group record. */
144
    protected $groupnotincourse;
145
 
146
    /**
147
     * Set up for every test
148
     */
149
    public function setUp(): void {
150
        global $DB;
151
        $this->resetAfterTest();
152
        $this->setAdminUser();
153
 
154
        // Setup test data.
155
        $this->course = $this->getDataGenerator()->create_course();
156
        $this->wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id));
157
        $this->context = \context_module::instance($this->wiki->cmid);
158
        $this->cm = get_coursemodule_from_instance('wiki', $this->wiki->id);
159
 
160
        // Create users.
161
        $this->student = self::getDataGenerator()->create_user();
162
        $this->student2 = self::getDataGenerator()->create_user();
163
        $this->teacher = self::getDataGenerator()->create_user();
164
 
165
        // Users enrolments.
166
        $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
167
        $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
168
        $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->studentrole->id, 'manual');
169
        $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id, 'manual');
170
        $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual');
171
 
172
        // Create first pages.
173
        $this->firstpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($this->wiki,
174
            array('tags' => array('Cats', 'Dogs')));
175
    }
176
 
177
    /**
178
     * Create two collaborative wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
179
     */
180
    private function create_collaborative_wikis_with_groups() {
181
        // Create groups and add student to one of them.
182
        if (!isset($this->group1)) {
183
            $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
184
            $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
185
            $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
186
        }
187
        if (!isset($this->group2)) {
188
            $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
189
        }
190
 
191
        // Create two collaborative wikis.
192
        $this->wikisep = $this->getDataGenerator()->create_module('wiki',
193
                                                        array('course' => $this->course->id, 'groupmode' => SEPARATEGROUPS));
194
        $this->wikivis = $this->getDataGenerator()->create_module('wiki',
195
                                                        array('course' => $this->course->id, 'groupmode' => VISIBLEGROUPS));
196
 
197
        // Create pages.
198
        $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
199
        $this->fpsepg1 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group1->id));
200
        $this->fpsepg2 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group2->id));
201
        $this->fpsepall = $wikigenerator->create_first_page($this->wikisep, array('group' => 0)); // All participants.
202
        $this->fpvisg1 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group1->id));
203
        $this->fpvisg2 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group2->id));
204
        $this->fpvisall = $wikigenerator->create_first_page($this->wikivis, array('group' => 0)); // All participants.
205
    }
206
 
207
    /**
208
     * Create two individual wikis (separate/visible groups), 2 groups and a first page for each wiki and group.
209
     */
210
    private function create_individual_wikis_with_groups() {
211
        // Create groups and add student to one of them.
212
        if (!isset($this->group1)) {
213
            $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
214
            $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id));
215
            $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id));
216
        }
217
        if (!isset($this->group2)) {
218
            $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
219
        }
220
 
221
        // Create two individual wikis.
222
        $this->wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
223
                                                        'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual'));
224
        $this->wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id,
225
                                                        'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual'));
226
 
227
        // Create pages. Student can only create pages in his groups.
228
        $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
229
        $this->setUser($this->teacher);
230
        $this->fpsepg1indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
231
        $this->fpsepg2indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group2->id));
232
        $this->fpsepallindt = $wikigenerator->create_first_page($this->wikisepind, array('group' => 0)); // All participants.
233
        $this->fpvisg1indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
234
        $this->fpvisg2indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group2->id));
235
        $this->fpvisallindt = $wikigenerator->create_first_page($this->wikivisind, array('group' => 0)); // All participants.
236
 
237
        $this->setUser($this->student);
238
        $this->fpsepg1indstu = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
239
        $this->fpvisg1indstu = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
240
 
241
        $this->setUser($this->student2);
242
        $this->fpsepg1indstu2 = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id));
243
        $this->fpvisg1indstu2 = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id));
244
 
245
    }
246
 
247
    /*
248
     * Test get wikis by courses
249
     */
11 efrain 250
    public function test_mod_wiki_get_wikis_by_courses(): void {
1 efrain 251
 
252
        // Create additional course.
253
        $course2 = self::getDataGenerator()->create_course();
254
 
255
        // Second wiki.
256
        $record = new \stdClass();
257
        $record->course = $course2->id;
258
        $wiki2 = self::getDataGenerator()->create_module('wiki', $record);
259
 
260
        // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
261
        $enrol = enrol_get_plugin('manual');
262
        $enrolinstances = enrol_get_instances($course2->id, true);
263
        foreach ($enrolinstances as $courseenrolinstance) {
264
            if ($courseenrolinstance->enrol == "manual") {
265
                $instance2 = $courseenrolinstance;
266
                break;
267
            }
268
        }
269
        $enrol->enrol_user($instance2, $this->student->id, $this->studentrole->id);
270
 
271
        self::setUser($this->student);
272
 
273
        $returndescription = mod_wiki_external::get_wikis_by_courses_returns();
274
 
275
        // Create what we expect to be returned when querying the two courses.
276
        // First for the student user.
277
        $expectedfields = array('id', 'coursemodule', 'course', 'name', 'intro', 'introformat', 'introfiles', 'lang',
278
                'firstpagetitle', 'wikimode', 'defaultformat', 'forceformat', 'editbegin', 'editend', 'section', 'visible',
279
                'groupmode', 'groupingid');
280
 
281
        // Add expected coursemodule and data.
282
        $wiki1 = $this->wiki;
283
        $wiki1->coursemodule = $wiki1->cmid;
284
        $wiki1->introformat = 1;
285
        $wiki1->section = 0;
286
        $wiki1->visible = true;
287
        $wiki1->groupmode = 0;
288
        $wiki1->groupingid = 0;
289
        $wiki1->introfiles = [];
290
        $wiki1->lang = '';
291
 
292
        $wiki2->coursemodule = $wiki2->cmid;
293
        $wiki2->introformat = 1;
294
        $wiki2->section = 0;
295
        $wiki2->visible = true;
296
        $wiki2->groupmode = 0;
297
        $wiki2->groupingid = 0;
298
        $wiki2->introfiles = [];
299
        $wiki2->lang = '';
300
 
301
        foreach ($expectedfields as $field) {
302
            $expected1[$field] = $wiki1->{$field};
303
            $expected2[$field] = $wiki2->{$field};
304
        }
305
        // Users can create pages by default.
306
        $expected1['cancreatepages'] = true;
307
        $expected2['cancreatepages'] = true;
308
 
309
        $expectedwikis = array($expected2, $expected1);
310
 
311
        // Call the external function passing course ids.
312
        $result = mod_wiki_external::get_wikis_by_courses(array($course2->id, $this->course->id));
313
        $result = external_api::clean_returnvalue($returndescription, $result);
314
 
315
        $this->assertEquals($expectedwikis, $result['wikis']);
316
        $this->assertCount(0, $result['warnings']);
317
 
318
        // Call the external function without passing course id.
319
        $result = mod_wiki_external::get_wikis_by_courses();
320
        $result = external_api::clean_returnvalue($returndescription, $result);
321
        $this->assertEquals($expectedwikis, $result['wikis']);
322
        $this->assertCount(0, $result['warnings']);
323
 
324
        // Unenrol user from second course and alter expected wikis.
325
        $enrol->unenrol_user($instance2, $this->student->id);
326
        array_shift($expectedwikis);
327
 
328
        // Call the external function without passing course id.
329
        $result = mod_wiki_external::get_wikis_by_courses();
330
        $result = external_api::clean_returnvalue($returndescription, $result);
331
        $this->assertEquals($expectedwikis, $result['wikis']);
332
 
333
        // Call for the second course we unenrolled the user from, expected warning.
334
        $result = mod_wiki_external::get_wikis_by_courses(array($course2->id));
335
        $this->assertCount(1, $result['warnings']);
336
        $this->assertEquals('1', $result['warnings'][0]['warningcode']);
337
        $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
338
 
339
        // Now, try as a teacher for getting all the additional fields.
340
        self::setUser($this->teacher);
341
 
342
        $additionalfields = array('timecreated', 'timemodified');
343
 
344
        foreach ($additionalfields as $field) {
345
            $expectedwikis[0][$field] = $wiki1->{$field};
346
        }
347
 
348
        $result = mod_wiki_external::get_wikis_by_courses();
349
        $result = external_api::clean_returnvalue($returndescription, $result);
350
        $this->assertEquals($expectedwikis, $result['wikis']);
351
 
352
        // Admin also should get all the information.
353
        self::setAdminUser();
354
 
355
        $result = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
356
        $result = external_api::clean_returnvalue($returndescription, $result);
357
        $this->assertEquals($expectedwikis, $result['wikis']);
358
 
359
        // Now, prohibit capabilities.
360
        $this->setUser($this->student);
361
        $contextcourse1 = \context_course::instance($this->course->id);
362
 
363
        // Default student role allows to view wiki and create pages.
364
        $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
365
        $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
366
        $this->assertEquals('Test wiki 1', $wikis['wikis'][0]['intro']);
367
        $this->assertEquals(1, $wikis['wikis'][0]['cancreatepages']);
368
 
369
        // Prohibit capability = mod:wiki:viewpage on Course1 for students.
370
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id, true);
371
        accesslib_clear_all_caches_for_unit_testing();
372
        \course_modinfo::clear_instance_cache(null);
373
 
374
        $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
375
        $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
376
        $this->assertEquals(0, count($wikis['wikis']));
377
 
378
        // Prohibit capability = mod:wiki:createpage on Course1 for students.
379
        assign_capability('mod/wiki:viewpage', CAP_ALLOW, $this->studentrole->id, $contextcourse1->id, true);
380
        assign_capability('mod/wiki:createpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse1->id);
381
        accesslib_clear_all_caches_for_unit_testing();
382
        \course_modinfo::clear_instance_cache(null);
383
 
384
        $wikis = mod_wiki_external::get_wikis_by_courses(array($this->course->id));
385
        $wikis = external_api::clean_returnvalue(mod_wiki_external::get_wikis_by_courses_returns(), $wikis);
386
        $this->assertFalse($wikis['wikis'][0]['cancreatepages']);
387
 
388
    }
389
 
390
    /**
391
     * Test view_wiki.
392
     */
11 efrain 393
    public function test_view_wiki(): void {
1 efrain 394
 
395
        // Test invalid instance id.
396
        try {
397
            mod_wiki_external::view_wiki(0);
398
            $this->fail('Exception expected due to invalid mod_wiki instance id.');
399
        } catch (\moodle_exception $e) {
400
            $this->assertEquals('incorrectwikiid', $e->errorcode);
401
        }
402
 
403
        // Test not-enrolled user.
404
        $usernotenrolled = self::getDataGenerator()->create_user();
405
        $this->setUser($usernotenrolled);
406
        try {
407
            mod_wiki_external::view_wiki($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
        }
412
 
413
        // Test user with full capabilities.
414
        $this->setUser($this->student);
415
 
416
        // Trigger and capture the event.
417
        $sink = $this->redirectEvents();
418
 
419
        $result = mod_wiki_external::view_wiki($this->wiki->id);
420
        $result = external_api::clean_returnvalue(mod_wiki_external::view_wiki_returns(), $result);
421
 
422
        $events = $sink->get_events();
423
        $this->assertCount(1, $events);
424
        $event = array_shift($events);
425
 
426
        // Checking that the event contains the expected values.
427
        $this->assertInstanceOf('\mod_wiki\event\course_module_viewed', $event);
428
        $this->assertEquals($this->context, $event->get_context());
429
        $moodlewiki = new \moodle_url('/mod/wiki/view.php', array('id' => $this->cm->id));
430
        $this->assertEquals($moodlewiki, $event->get_url());
431
        $this->assertEventContextNotUsed($event);
432
        $this->assertNotEmpty($event->get_name());
433
 
434
        // Test user with no capabilities.
435
        // We need a explicit prohibit since this capability is allowed for students by default.
436
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
437
        accesslib_clear_all_caches_for_unit_testing();
438
 
439
        try {
440
            mod_wiki_external::view_wiki($this->wiki->id);
441
            $this->fail('Exception expected due to missing capability.');
442
        } catch (\moodle_exception $e) {
443
            $this->assertEquals('cannotviewpage', $e->errorcode);
444
        }
445
 
446
    }
447
 
448
    /**
449
     * Test view_page.
450
     */
11 efrain 451
    public function test_view_page(): void {
1 efrain 452
 
453
        // Test invalid page id.
454
        try {
455
            mod_wiki_external::view_page(0);
456
            $this->fail('Exception expected due to invalid view_page page id.');
457
        } catch (\moodle_exception $e) {
458
            $this->assertEquals('incorrectpageid', $e->errorcode);
459
        }
460
 
461
        // Test not-enrolled user.
462
        $usernotenrolled = self::getDataGenerator()->create_user();
463
        $this->setUser($usernotenrolled);
464
        try {
465
            mod_wiki_external::view_page($this->firstpage->id);
466
            $this->fail('Exception expected due to not enrolled user.');
467
        } catch (\moodle_exception $e) {
468
            $this->assertEquals('requireloginerror', $e->errorcode);
469
        }
470
 
471
        // Test user with full capabilities.
472
        $this->setUser($this->student);
473
 
474
        // Trigger and capture the event.
475
        $sink = $this->redirectEvents();
476
 
477
        $result = mod_wiki_external::view_page($this->firstpage->id);
478
        $result = external_api::clean_returnvalue(mod_wiki_external::view_page_returns(), $result);
479
 
480
        $events = $sink->get_events();
481
        $this->assertCount(1, $events);
482
        $event = array_shift($events);
483
 
484
        // Checking that the event contains the expected values.
485
        $this->assertInstanceOf('\mod_wiki\event\page_viewed', $event);
486
        $this->assertEquals($this->context, $event->get_context());
487
        $pageurl = new \moodle_url('/mod/wiki/view.php', array('pageid' => $this->firstpage->id));
488
        $this->assertEquals($pageurl, $event->get_url());
489
        $this->assertEventContextNotUsed($event);
490
        $this->assertNotEmpty($event->get_name());
491
 
492
        // Test user with no capabilities.
493
        // We need a explicit prohibit since this capability is allowed for students by default.
494
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
495
        accesslib_clear_all_caches_for_unit_testing();
496
 
497
        try {
498
            mod_wiki_external::view_page($this->firstpage->id);
499
            $this->fail('Exception expected due to missing capability.');
500
        } catch (\moodle_exception $e) {
501
            $this->assertEquals('cannotviewpage', $e->errorcode);
502
        }
503
 
504
    }
505
 
506
    /**
507
     * Test get_subwikis.
508
     */
11 efrain 509
    public function test_get_subwikis(): void {
1 efrain 510
 
511
        // Test invalid wiki id.
512
        try {
513
            mod_wiki_external::get_subwikis(0);
514
            $this->fail('Exception expected due to invalid get_subwikis wiki id.');
515
        } catch (\moodle_exception $e) {
516
            $this->assertEquals('incorrectwikiid', $e->errorcode);
517
        }
518
 
519
        // Test not-enrolled user.
520
        $usernotenrolled = self::getDataGenerator()->create_user();
521
        $this->setUser($usernotenrolled);
522
        try {
523
            mod_wiki_external::get_subwikis($this->wiki->id);
524
            $this->fail('Exception expected due to not enrolled user.');
525
        } catch (\moodle_exception $e) {
526
            $this->assertEquals('requireloginerror', $e->errorcode);
527
        }
528
 
529
        // Test user with full capabilities.
530
        $this->setUser($this->student);
531
 
532
        // Create what we expect to be returned. We only test a basic case because deep testing is already done
533
        // in the tests for wiki_get_visible_subwikis.
534
        $expectedsubwikis = array();
535
        $expectedsubwiki = array(
536
                'id' => $this->firstpage->subwikiid,
537
                'wikiid' => $this->wiki->id,
538
                'groupid' => 0,
539
                'userid' => 0,
540
                'canedit' => true
541
            );
542
        $expectedsubwikis[] = $expectedsubwiki;
543
 
544
        $result = mod_wiki_external::get_subwikis($this->wiki->id);
545
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwikis_returns(), $result);
546
        $this->assertEquals($expectedsubwikis, $result['subwikis']);
547
        $this->assertCount(0, $result['warnings']);
548
 
549
        // Test user with no capabilities.
550
        // We need a explicit prohibit since this capability is allowed for students by default.
551
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
552
        accesslib_clear_all_caches_for_unit_testing();
553
 
554
        try {
555
            mod_wiki_external::get_subwikis($this->wiki->id);
556
            $this->fail('Exception expected due to missing capability.');
557
        } catch (\moodle_exception $e) {
558
            $this->assertEquals('nopermissions', $e->errorcode);
559
        }
560
 
561
    }
562
 
563
    /**
564
     * Test get_subwiki_pages using an invalid wiki instance.
565
     */
11 efrain 566
    public function test_get_subwiki_pages_invalid_instance(): void {
1 efrain 567
        $this->expectException(\moodle_exception::class);
568
        mod_wiki_external::get_subwiki_pages(0);
569
    }
570
 
571
    /**
572
     * Test get_subwiki_pages using a user not enrolled in the course.
573
     */
11 efrain 574
    public function test_get_subwiki_pages_unenrolled_user(): void {
1 efrain 575
        // Create and use the user.
576
        $usernotenrolled = self::getDataGenerator()->create_user();
577
        $this->setUser($usernotenrolled);
578
 
579
        $this->expectException(\require_login_exception::class);
580
        mod_wiki_external::get_subwiki_pages($this->wiki->id);
581
    }
582
 
583
    /**
584
     * Test get_subwiki_pages using a hidden wiki as student.
585
     */
11 efrain 586
    public function test_get_subwiki_pages_hidden_wiki_as_student(): void {
1 efrain 587
        // Create a hidden wiki and try to get the list of pages.
588
        $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
589
                            array('course' => $this->course->id, 'visible' => false));
590
 
591
        $this->setUser($this->student);
592
        $this->expectException(\require_login_exception::class);
593
        mod_wiki_external::get_subwiki_pages($hiddenwiki->id);
594
    }
595
 
596
    /**
597
     * Test get_subwiki_pages without the viewpage capability.
598
     */
11 efrain 599
    public function test_get_subwiki_pages_without_viewpage_capability(): void {
1 efrain 600
        // Prohibit capability = mod/wiki:viewpage on the course for students.
601
        $contextcourse = \context_course::instance($this->course->id);
602
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
603
        accesslib_clear_all_caches_for_unit_testing();
604
 
605
        $this->setUser($this->student);
606
        $this->expectException(\moodle_exception::class);
607
        mod_wiki_external::get_subwiki_pages($this->wiki->id);
608
    }
609
 
610
    /**
611
     * Test get_subwiki_pages using an invalid userid.
612
     */
11 efrain 613
    public function test_get_subwiki_pages_invalid_userid(): void {
1 efrain 614
        // Create an individual wiki.
615
        $indwiki = $this->getDataGenerator()->create_module('wiki',
616
                                array('course' => $this->course->id, 'wikimode' => 'individual'));
617
 
618
        $this->expectException(\moodle_exception::class);
619
        mod_wiki_external::get_subwiki_pages($indwiki->id, 0, -10);
620
    }
621
 
622
    /**
623
     * Test get_subwiki_pages using an invalid groupid.
624
     */
11 efrain 625
    public function test_get_subwiki_pages_invalid_groupid(): void {
1 efrain 626
        // Create testing data.
627
        $this->create_collaborative_wikis_with_groups();
628
 
629
        $this->expectException(\moodle_exception::class);
630
        mod_wiki_external::get_subwiki_pages($this->wikisep->id, -111);
631
    }
632
 
633
    /**
634
     * Test get_subwiki_pages, check that a student can't see another user pages in an individual wiki without groups.
635
     */
11 efrain 636
    public function test_get_subwiki_pages_individual_student_see_other_user(): void {
1 efrain 637
        // Create an individual wiki.
638
        $indwiki = $this->getDataGenerator()->create_module('wiki',
639
                                array('course' => $this->course->id, 'wikimode' => 'individual'));
640
 
641
        $this->setUser($this->student);
642
        $this->expectException(\moodle_exception::class);
643
        mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
644
    }
645
 
646
    /**
647
     * Test get_subwiki_pages, check that a student can't get the pages from another group in
648
     * a collaborative wiki using separate groups.
649
     */
11 efrain 650
    public function test_get_subwiki_pages_collaborative_separate_groups_student_see_other_group(): void {
1 efrain 651
        // Create testing data.
652
        $this->create_collaborative_wikis_with_groups();
653
 
654
        $this->setUser($this->student);
655
        $this->expectException(\moodle_exception::class);
656
        mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group2->id);
657
    }
658
 
659
    /**
660
     * Test get_subwiki_pages, check that a student can't get the pages from another group in
661
     * an individual wiki using separate groups.
662
     */
11 efrain 663
    public function test_get_subwiki_pages_individual_separate_groups_student_see_other_group(): void {
1 efrain 664
        // Create testing data.
665
        $this->create_individual_wikis_with_groups();
666
 
667
        $this->setUser($this->student);
668
        $this->expectException(\moodle_exception::class);
669
        mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group2->id, $this->teacher->id);
670
    }
671
 
672
    /**
673
     * Test get_subwiki_pages, check that a student can't get the pages from all participants in
674
     * a collaborative wiki using separate groups.
675
     */
11 efrain 676
    public function test_get_subwiki_pages_collaborative_separate_groups_student_see_all_participants(): void {
1 efrain 677
        // Create testing data.
678
        $this->create_collaborative_wikis_with_groups();
679
 
680
        $this->setUser($this->student);
681
        $this->expectException(\moodle_exception::class);
682
        mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
683
    }
684
 
685
    /**
686
     * Test get_subwiki_pages, check that a student can't get the pages from all participants in
687
     * an individual wiki using separate groups.
688
     */
11 efrain 689
    public function test_get_subwiki_pages_individual_separate_groups_student_see_all_participants(): void {
1 efrain 690
        // Create testing data.
691
        $this->create_individual_wikis_with_groups();
692
 
693
        $this->setUser($this->student);
694
        $this->expectException(\moodle_exception::class);
695
        mod_wiki_external::get_subwiki_pages($this->wikisepind->id, 0, $this->teacher->id);
696
    }
697
 
698
    /**
699
     * Test get_subwiki_pages without groups and collaborative wiki.
700
     */
11 efrain 701
    public function test_get_subwiki_pages_collaborative(): void {
1 efrain 702
 
703
        // Test user with full capabilities.
704
        $this->setUser($this->student);
705
 
706
        // Set expected result: first page.
707
        $expectedpages = array();
708
        $expectedfirstpage = (array) $this->firstpage;
709
        $expectedfirstpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
710
        $expectedfirstpage['firstpage'] = true;
711
        $expectedfirstpage['contentformat'] = 1;
712
        $expectedfirstpage['tags'] = \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $this->firstpage->id);
713
        // Cast to expected.
714
        $expectedfirstpage['tags'][0]['isstandard'] = (bool) $expectedfirstpage['tags'][0]['isstandard'];
715
        $expectedfirstpage['tags'][1]['isstandard'] = (bool) $expectedfirstpage['tags'][1]['isstandard'];
716
        $expectedpages[] = $expectedfirstpage;
717
 
718
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
719
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
720
        $this->assertEquals($expectedpages, $result['pages']);
721
 
722
        // Check that groupid param is ignored since the wiki isn't using groups.
723
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234);
724
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
725
        $this->assertEquals($expectedpages, $result['pages']);
726
 
727
        // Check that userid param is ignored since the wiki is collaborative.
728
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234, 1234);
729
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
730
        $this->assertEquals($expectedpages, $result['pages']);
731
 
732
        // 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.
733
        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
734
                                $this->wiki, array('title' => 'AAA'));
735
 
736
        $expectednewpage = (array) $newpage;
737
        $expectednewpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability.
738
        $expectednewpage['firstpage'] = false;
739
        $expectednewpage['contentformat'] = 1;
740
        $expectednewpage['tags'] = array();
741
        array_unshift($expectedpages, $expectednewpage); // Add page to the beginning since it orders by title by default.
742
 
743
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id);
744
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
745
        $this->assertEquals($expectedpages, $result['pages']);
746
 
747
        // Now we'll order by ID. Since first page was created first it'll have a lower ID.
748
        $expectedpages = array($expectedfirstpage, $expectednewpage);
749
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id'));
750
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
751
        $this->assertEquals($expectedpages, $result['pages']);
752
 
753
        // Check that WS doesn't return page content if includecontent is false, it returns the size instead.
754
        foreach ($expectedpages as $i => $expectedpage) {
755
            $expectedpages[$i]['contentsize'] = \core_text::strlen($expectedpages[$i]['cachedcontent']);
756
            unset($expectedpages[$i]['cachedcontent']);
757
            unset($expectedpages[$i]['contentformat']);
758
        }
759
        $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id', 'includecontent' => 0));
760
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
761
        $this->assertEquals($expectedpages, $result['pages']);
762
    }
763
 
764
    /**
765
     * Test get_subwiki_pages without groups.
766
     */
11 efrain 767
    public function test_get_subwiki_pages_individual(): void {
1 efrain 768
 
769
        // Create an individual wiki to test userid param.
770
        $indwiki = $this->getDataGenerator()->create_module('wiki',
771
                                array('course' => $this->course->id, 'wikimode' => 'individual'));
772
 
773
        // Perform a request before creating any page to check that an empty array is returned if subwiki doesn't exist.
774
        $result = mod_wiki_external::get_subwiki_pages($indwiki->id);
775
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
776
        $this->assertEquals(array(), $result['pages']);
777
 
778
        // Create first pages as student and teacher.
779
        $this->setUser($this->student);
780
        $indfirstpagestudent = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
781
        $this->setUser($this->teacher);
782
        $indfirstpageteacher = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki);
783
 
784
        // Check that teacher can get his pages.
785
        $expectedteacherpage = (array) $indfirstpageteacher;
786
        $expectedteacherpage['caneditpage'] = true;
787
        $expectedteacherpage['firstpage'] = true;
788
        $expectedteacherpage['contentformat'] = 1;
789
        $expectedteacherpage['tags'] = array();
790
        $expectedpages = array($expectedteacherpage);
791
 
792
        $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
793
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
794
        $this->assertEquals($expectedpages, $result['pages']);
795
 
796
        // Check that the teacher can see the student's pages.
797
        $expectedstudentpage = (array) $indfirstpagestudent;
798
        $expectedstudentpage['caneditpage'] = true;
799
        $expectedstudentpage['firstpage'] = true;
800
        $expectedstudentpage['contentformat'] = 1;
801
        $expectedstudentpage['tags'] = array();
802
        $expectedpages = array($expectedstudentpage);
803
 
804
        $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
805
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
806
        $this->assertEquals($expectedpages, $result['pages']);
807
 
808
        // Now check that student can get his pages.
809
        $this->setUser($this->student);
810
 
811
        $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id);
812
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
813
        $this->assertEquals($expectedpages, $result['pages']);
814
 
815
        // Check that not using userid uses current user.
816
        $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0);
817
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
818
        $this->assertEquals($expectedpages, $result['pages']);
819
    }
820
 
821
    /**
822
     * Test get_subwiki_pages with groups and collaborative wikis.
823
     */
11 efrain 824
    public function test_get_subwiki_pages_separate_groups_collaborative(): void {
1 efrain 825
 
826
        // Create testing data.
827
        $this->create_collaborative_wikis_with_groups();
828
 
829
        $this->setUser($this->student);
830
 
831
        // Try to get pages from a valid group in separate groups wiki.
832
 
833
        $expectedpage = (array) $this->fpsepg1;
834
        $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
835
        $expectedpage['firstpage'] = true;
836
        $expectedpage['contentformat'] = 1;
837
        $expectedpage['tags'] = array();
838
        $expectedpages = array($expectedpage);
839
 
840
        $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
841
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
842
        $this->assertEquals($expectedpages, $result['pages']);
843
 
844
        // Let's check that not using groupid returns the same result (current group).
845
        $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id);
846
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
847
        $this->assertEquals($expectedpages, $result['pages']);
848
 
849
        // Check that teacher can view a group pages without belonging to it.
850
        $this->setUser($this->teacher);
851
        $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id);
852
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
853
        $this->assertEquals($expectedpages, $result['pages']);
854
 
855
        // Check that teacher can get the pages from all participants.
856
        $expectedpage = (array) $this->fpsepall;
857
        $expectedpage['caneditpage'] = true;
858
        $expectedpage['firstpage'] = true;
859
        $expectedpage['contentformat'] = 1;
860
        $expectedpage['tags'] = array();
861
        $expectedpages = array($expectedpage);
862
 
863
        $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
864
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
865
        $this->assertEquals($expectedpages, $result['pages']);
866
    }
867
 
868
    /**
869
     * Test get_subwiki_pages with groups and collaborative wikis.
870
     */
11 efrain 871
    public function test_get_subwiki_pages_visible_groups_collaborative(): void {
1 efrain 872
 
873
        // Create testing data.
874
        $this->create_collaborative_wikis_with_groups();
875
 
876
        $this->setUser($this->student);
877
 
878
        // Try to get pages from a valid group in visible groups wiki.
879
 
880
        $expectedpage = (array) $this->fpvisg1;
881
        $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability.
882
        $expectedpage['firstpage'] = true;
883
        $expectedpage['contentformat'] = 1;
884
        $expectedpage['tags'] = array();
885
        $expectedpages = array($expectedpage);
886
 
887
        $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group1->id);
888
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
889
        $this->assertEquals($expectedpages, $result['pages']);
890
 
891
        // Check that with visible groups a student can get the pages of groups he doesn't belong to.
892
        $expectedpage = (array) $this->fpvisg2;
893
        $expectedpage['caneditpage'] = false; // User doesn't belong to group so he can't edit the page.
894
        $expectedpage['firstpage'] = true;
895
        $expectedpage['contentformat'] = 1;
896
        $expectedpage['tags'] = array();
897
        $expectedpages = array($expectedpage);
898
 
899
        $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group2->id);
900
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
901
        $this->assertEquals($expectedpages, $result['pages']);
902
 
903
        // Check that with visible groups a student can get the pages of all participants.
904
        $expectedpage = (array) $this->fpvisall;
905
        $expectedpage['caneditpage'] = false;
906
        $expectedpage['firstpage'] = true;
907
        $expectedpage['contentformat'] = 1;
908
        $expectedpage['tags'] = array();
909
        $expectedpages = array($expectedpage);
910
 
911
        $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, 0);
912
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
913
        $this->assertEquals($expectedpages, $result['pages']);
914
    }
915
 
916
    /**
917
     * Test get_subwiki_pages with groups and individual wikis.
918
     */
11 efrain 919
    public function test_get_subwiki_pages_separate_groups_individual(): void {
1 efrain 920
 
921
        // Create testing data.
922
        $this->create_individual_wikis_with_groups();
923
 
924
        $this->setUser($this->student);
925
 
926
        // Check that student can retrieve his pages from separate wiki.
927
        $expectedpage = (array) $this->fpsepg1indstu;
928
        $expectedpage['caneditpage'] = true;
929
        $expectedpage['firstpage'] = true;
930
        $expectedpage['contentformat'] = 1;
931
        $expectedpage['tags'] = array();
932
        $expectedpages = array($expectedpage);
933
 
934
        $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
935
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
936
        $this->assertEquals($expectedpages, $result['pages']);
937
 
938
        // Check that not using userid uses current user.
939
        $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id);
940
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
941
        $this->assertEquals($expectedpages, $result['pages']);
942
 
943
        // Check that the teacher can see the student pages.
944
        $this->setUser($this->teacher);
945
        $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id);
946
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
947
        $this->assertEquals($expectedpages, $result['pages']);
948
 
949
        // Check that a student can see pages from another user that belongs to his groups.
950
        $this->setUser($this->student);
951
        $expectedpage = (array) $this->fpsepg1indstu2;
952
        $expectedpage['caneditpage'] = false;
953
        $expectedpage['firstpage'] = true;
954
        $expectedpage['contentformat'] = 1;
955
        $expectedpage['tags'] = array();
956
        $expectedpages = array($expectedpage);
957
 
958
        $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student2->id);
959
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
960
        $this->assertEquals($expectedpages, $result['pages']);
961
    }
962
 
963
    /**
964
     * Test get_subwiki_pages with groups and individual wikis.
965
     */
11 efrain 966
    public function test_get_subwiki_pages_visible_groups_individual(): void {
1 efrain 967
 
968
        // Create testing data.
969
        $this->create_individual_wikis_with_groups();
970
 
971
        $this->setUser($this->student);
972
 
973
        // Check that student can retrieve his pages from visible wiki.
974
        $expectedpage = (array) $this->fpvisg1indstu;
975
        $expectedpage['caneditpage'] = true;
976
        $expectedpage['firstpage'] = true;
977
        $expectedpage['contentformat'] = 1;
978
        $expectedpage['tags'] = array();
979
        $expectedpages = array($expectedpage);
980
 
981
        $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group1->id, $this->student->id);
982
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
983
        $this->assertEquals($expectedpages, $result['pages']);
984
 
985
        // Check that student can see teacher pages in visible groups, even if the user doesn't belong to the group.
986
        $expectedpage = (array) $this->fpvisg2indt;
987
        $expectedpage['caneditpage'] = false;
988
        $expectedpage['firstpage'] = true;
989
        $expectedpage['contentformat'] = 1;
990
        $expectedpage['tags'] = array();
991
        $expectedpages = array($expectedpage);
992
 
993
        $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group2->id, $this->teacher->id);
994
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
995
        $this->assertEquals($expectedpages, $result['pages']);
996
 
997
        // Check that with visible groups a student can get the pages of all participants.
998
        $expectedpage = (array) $this->fpvisallindt;
999
        $expectedpage['caneditpage'] = false;
1000
        $expectedpage['firstpage'] = true;
1001
        $expectedpage['contentformat'] = 1;
1002
        $expectedpage['tags'] = array();
1003
        $expectedpages = array($expectedpage);
1004
 
1005
        $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, 0, $this->teacher->id);
1006
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result);
1007
        $this->assertEquals($expectedpages, $result['pages']);
1008
    }
1009
 
1010
    /**
1011
     * Test get_page_contents using an invalid pageid.
1012
     */
11 efrain 1013
    public function test_get_page_contents_invalid_pageid(): void {
1 efrain 1014
        $this->expectException(\moodle_exception::class);
1015
        mod_wiki_external::get_page_contents(0);
1016
    }
1017
 
1018
    /**
1019
     * Test get_page_contents using a user not enrolled in the course.
1020
     */
11 efrain 1021
    public function test_get_page_contents_unenrolled_user(): void {
1 efrain 1022
        // Create and use the user.
1023
        $usernotenrolled = self::getDataGenerator()->create_user();
1024
        $this->setUser($usernotenrolled);
1025
 
1026
        $this->expectException(\require_login_exception::class);
1027
        mod_wiki_external::get_page_contents($this->firstpage->id);
1028
    }
1029
 
1030
    /**
1031
     * Test get_page_contents using a hidden wiki as student.
1032
     */
11 efrain 1033
    public function test_get_page_contents_hidden_wiki_as_student(): void {
1 efrain 1034
        // Create a hidden wiki and try to get a page contents.
1035
        $hiddenwiki = $this->getDataGenerator()->create_module('wiki',
1036
                            array('course' => $this->course->id, 'visible' => false));
1037
        $hiddenpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($hiddenwiki);
1038
 
1039
        $this->setUser($this->student);
1040
        $this->expectException(\require_login_exception::class);
1041
        mod_wiki_external::get_page_contents($hiddenpage->id);
1042
    }
1043
 
1044
    /**
1045
     * Test get_page_contents without the viewpage capability.
1046
     */
11 efrain 1047
    public function test_get_page_contents_without_viewpage_capability(): void {
1 efrain 1048
        // Prohibit capability = mod/wiki:viewpage on the course for students.
1049
        $contextcourse = \context_course::instance($this->course->id);
1050
        assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id);
1051
        accesslib_clear_all_caches_for_unit_testing();
1052
 
1053
        $this->setUser($this->student);
1054
        $this->expectException(\moodle_exception::class);
1055
        mod_wiki_external::get_page_contents($this->firstpage->id);
1056
    }
1057
 
1058
    /**
1059
     * Test get_page_contents, check that a student can't get a page from another group when
1060
     * using separate groups.
1061
     */
11 efrain 1062
    public function test_get_page_contents_separate_groups_student_see_other_group(): void {
1 efrain 1063
        // Create testing data.
1064
        $this->create_individual_wikis_with_groups();
1065
 
1066
        $this->setUser($this->student);
1067
        $this->expectException(\moodle_exception::class);
1068
        mod_wiki_external::get_page_contents($this->fpsepg2indt->id);
1069
    }
1070
 
1071
    /**
1072
     * Test get_page_contents without groups. We won't test all the possible cases because that's already
1073
     * done in the tests for get_subwiki_pages.
1074
     */
11 efrain 1075
    public function test_get_page_contents(): void {
1 efrain 1076
 
1077
        // Test user with full capabilities.
1078
        $this->setUser($this->student);
1079
 
1080
        // Set expected result: first page.
1081
        $expectedpage = array(
1082
            'id' => $this->firstpage->id,
1083
            'wikiid' => $this->wiki->id,
1084
            'subwikiid' => $this->firstpage->subwikiid,
1085
            'groupid' => 0, // No groups.
1086
            'userid' => 0, // Collaborative.
1087
            'title' => $this->firstpage->title,
1088
            'cachedcontent' => $this->firstpage->cachedcontent,
1089
            'contentformat' => 1,
1090
            'caneditpage' => true,
1091
            'version' => 1,
1092
            'tags' => \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $this->firstpage->id),
1093
        );
1094
        // Cast to expected.
1095
        $expectedpage['tags'][0]['isstandard'] = (bool) $expectedpage['tags'][0]['isstandard'];
1096
        $expectedpage['tags'][1]['isstandard'] = (bool) $expectedpage['tags'][1]['isstandard'];
1097
 
1098
        $result = mod_wiki_external::get_page_contents($this->firstpage->id);
1099
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1100
        $this->assertEquals($expectedpage, $result['page']);
1101
 
1102
        // Add a new page to the wiki and test with it.
1103
        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wiki);
1104
 
1105
        $expectedpage['id'] = $newpage->id;
1106
        $expectedpage['title'] = $newpage->title;
1107
        $expectedpage['cachedcontent'] = $newpage->cachedcontent;
1108
        $expectedpage['tags'] = array();
1109
 
1110
        $result = mod_wiki_external::get_page_contents($newpage->id);
1111
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1112
        $this->assertEquals($expectedpage, $result['page']);
1113
    }
1114
 
1115
    /**
1116
     * Test get_page_contents with groups. We won't test all the possible cases because that's already
1117
     * done in the tests for get_subwiki_pages.
1118
     */
11 efrain 1119
    public function test_get_page_contents_with_groups(): void {
1 efrain 1120
 
1121
        // Create testing data.
1122
        $this->create_individual_wikis_with_groups();
1123
 
1124
        // Try to get page from a valid group in separate groups wiki.
1125
        $this->setUser($this->student);
1126
 
1127
        $expectedfpsepg1indstu = array(
1128
            'id' => $this->fpsepg1indstu->id,
1129
            'wikiid' => $this->wikisepind->id,
1130
            'subwikiid' => $this->fpsepg1indstu->subwikiid,
1131
            'groupid' => $this->group1->id,
1132
            'userid' => $this->student->id,
1133
            'title' => $this->fpsepg1indstu->title,
1134
            'cachedcontent' => $this->fpsepg1indstu->cachedcontent,
1135
            'contentformat' => 1,
1136
            'caneditpage' => true,
1137
            'version' => 1,
1138
            'tags' => array(),
1139
        );
1140
 
1141
        $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1142
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1143
        $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1144
 
1145
        // Check that teacher can view a group pages without belonging to it.
1146
        $this->setUser($this->teacher);
1147
        $result = mod_wiki_external::get_page_contents($this->fpsepg1indstu->id);
1148
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_contents_returns(), $result);
1149
        $this->assertEquals($expectedfpsepg1indstu, $result['page']);
1150
    }
1151
 
1152
    /**
1153
     * Test get_subwiki_files using a wiki without files.
1154
     */
11 efrain 1155
    public function test_get_subwiki_files_no_files(): void {
1 efrain 1156
        $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1157
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1158
        $this->assertCount(0, $result['files']);
1159
        $this->assertCount(0, $result['warnings']);
1160
    }
1161
 
1162
    /**
1163
     * Test get_subwiki_files, check that a student can't get files from another group's subwiki when
1164
     * using separate groups.
1165
     */
11 efrain 1166
    public function test_get_subwiki_files_separate_groups_student_see_other_group(): void {
1 efrain 1167
        // Create testing data.
1168
        $this->create_collaborative_wikis_with_groups();
1169
 
1170
        $this->setUser($this->student);
1171
        $this->expectException(\moodle_exception::class);
1172
        mod_wiki_external::get_subwiki_files($this->wikisep->id, $this->group2->id);
1173
    }
1174
 
1175
    /**
1176
     * Test get_subwiki_files using a collaborative wiki without groups.
1177
     */
11 efrain 1178
    public function test_get_subwiki_files_collaborative_no_groups(): void {
1 efrain 1179
        $this->setUser($this->student);
1180
 
1181
        // Add a file as subwiki attachment.
1182
        $fs = get_file_storage();
1183
        $file = array('component' => 'mod_wiki', 'filearea' => 'attachments',
1184
                'contextid' => $this->context->id, 'itemid' => $this->firstpage->subwikiid,
1185
                'filename' => 'image.jpg', 'filepath' => '/', 'timemodified' => time());
1186
        $content = 'IMAGE';
1187
        $fs->create_file_from_string($file, $content);
1188
 
1189
        $expectedfile = array(
1190
            'filename' => $file['filename'],
1191
            'filepath' => $file['filepath'],
1192
            'mimetype' => 'image/jpeg',
1193
            'isexternalfile' => false,
1194
            'filesize' => strlen($content),
1195
            'timemodified' => $file['timemodified'],
1196
            'fileurl' => \moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1197
                            $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']),
1198
            'icon' => 'f/image',
1199
        );
1200
 
1201
        // Call the WS and check that it returns this file.
1202
        $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1203
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1204
        $this->assertCount(1, $result['files']);
1205
        $this->assertEquals($expectedfile, $result['files'][0]);
1206
 
1207
        // Now add another file to the same subwiki.
1208
        $file['filename'] = 'Another image.jpg';
1209
        $file['timemodified'] = time();
1210
        $content = 'ANOTHER IMAGE';
1211
        $fs->create_file_from_string($file, $content);
1212
 
1213
        $expectedfile['filename'] = $file['filename'];
1214
        $expectedfile['timemodified'] = $file['timemodified'];
1215
        $expectedfile['filesize'] = strlen($content);
1216
        $expectedfile['fileurl'] = \moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1217
                            $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']);
1218
 
1219
        // Call the WS and check that it returns both files file.
1220
        $result = mod_wiki_external::get_subwiki_files($this->wiki->id);
1221
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1222
        $this->assertCount(2, $result['files']);
1223
        // The new file is returned first because they're returned in alphabetical order.
1224
        $this->assertEquals($expectedfile, $result['files'][0]);
1225
    }
1226
 
1227
    /**
1228
     * Test get_subwiki_files using an individual wiki with visible groups.
1229
     */
11 efrain 1230
    public function test_get_subwiki_files_visible_groups_individual(): void {
1 efrain 1231
        // Create testing data.
1232
        $this->create_individual_wikis_with_groups();
1233
 
1234
        $this->setUser($this->student);
1235
 
1236
        // Add a file as subwiki attachment in the student group 1 subwiki.
1237
        $fs = get_file_storage();
1238
        $contextwiki = \context_module::instance($this->wikivisind->cmid);
1239
        $file = array('component' => 'mod_wiki', 'filearea' => 'attachments',
1240
                'contextid' => $contextwiki->id, 'itemid' => $this->fpvisg1indstu->subwikiid,
1241
                'filename' => 'image.jpg', 'filepath' => '/', 'timemodified' => time());
1242
        $content = 'IMAGE';
1243
        $fs->create_file_from_string($file, $content);
1244
 
1245
        $expectedfile = array(
1246
            'filename' => $file['filename'],
1247
            'filepath' => $file['filepath'],
1248
            'mimetype' => 'image/jpeg',
1249
            'isexternalfile' => false,
1250
            'filesize' => strlen($content),
1251
            'timemodified' => $file['timemodified'],
1252
            'fileurl' => \moodle_url::make_webservice_pluginfile_url($file['contextid'], $file['component'],
1253
                            $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']),
1254
            'icon' => 'f/image',
1255
        );
1256
 
1257
        // Call the WS and check that it returns this file.
1258
        $result = mod_wiki_external::get_subwiki_files($this->wikivisind->id, $this->group1->id);
1259
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1260
        $this->assertCount(1, $result['files']);
1261
        $this->assertEquals($expectedfile, $result['files'][0]);
1262
 
1263
        // Now check that a teacher can see it too.
1264
        $this->setUser($this->teacher);
1265
        $result = mod_wiki_external::get_subwiki_files($this->wikivisind->id, $this->group1->id, $this->student->id);
1266
        $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_files_returns(), $result);
1267
        $this->assertCount(1, $result['files']);
1268
        $this->assertEquals($expectedfile, $result['files'][0]);
1269
    }
1270
 
1271
 
1272
    /**
1273
     * Test get_page_for_editing. We won't test all the possible cases because that's already
1274
     * done in the tests for wiki_parser_proxy::get_section.
1275
     */
11 efrain 1276
    public function test_get_page_for_editing(): void {
1 efrain 1277
 
1278
        $this->create_individual_wikis_with_groups();
1279
 
1280
        // We add a <span> in the first title to verify the WS works sending HTML in section.
1281
        $sectioncontent = '<h1><span>Title1</span></h1>Text inside section';
1282
        $pagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
1283
        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
1284
                                $this->wiki, array('content' => $pagecontent));
1285
 
1286
        // Test user with full capabilities.
1287
        $this->setUser($this->student);
1288
 
1289
        // Set expected result: Full Page content.
1290
        $expected = array(
1291
            'content' => $pagecontent,
1292
            'contentformat' => 'html',
1293
            'version' => '1'
1294
        );
1295
 
1296
        $result = mod_wiki_external::get_page_for_editing($newpage->id);
1297
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1298
        $this->assertEquals($expected, $result['pagesection']);
1299
 
1300
        // Set expected result: Section Page content.
1301
        $expected = array(
1302
            'content' => $sectioncontent,
1303
            'contentformat' => 'html',
1304
            'version' => '1'
1305
        );
1306
 
1307
        $result = mod_wiki_external::get_page_for_editing($newpage->id, '<span>Title1</span>');
1308
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1309
        $this->assertEquals($expected, $result['pagesection']);
1310
    }
1311
 
1312
    /**
1313
     * Test test_get_page_locking.
1314
     */
11 efrain 1315
    public function test_get_page_locking(): void {
1 efrain 1316
 
1317
        $this->create_individual_wikis_with_groups();
1318
 
1319
        $pagecontent = '<h1>Title1</h1>Text inside section<h1>Title2</h1>Text inside section';
1320
        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page(
1321
                                $this->wiki, array('content' => $pagecontent));
1322
 
1323
        // Test user with full capabilities.
1324
        $this->setUser($this->student);
1325
 
1326
        // Test Section locking.
1327
        $expected = array(
1328
            'version' => '1'
1329
        );
1330
 
1331
        $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1332
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1333
        $this->assertEquals($expected, $result['pagesection']);
1334
 
1335
        // Test the section is locked.
1336
        $this->setUser($this->student2);
1337
        try {
1338
            mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1339
            $this->fail('Exception expected due to not page locking.');
1340
        } catch (\moodle_exception $e) {
1341
            $this->assertEquals('pageislocked', $e->errorcode);
1342
        }
1343
 
1344
        // Test the page is locked.
1345
        try {
1346
            mod_wiki_external::get_page_for_editing($newpage->id, null, true);
1347
            $this->fail('Exception expected due to not page locking.');
1348
        } catch (\moodle_exception $e) {
1349
            $this->assertEquals('pageislocked', $e->errorcode);
1350
        }
1351
 
1352
        // Test the other section is not locked.
1353
        $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title2', true);
1354
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1355
        $this->assertEquals($expected, $result['pagesection']);
1356
 
1357
        // Back to the original user to test version change when editing.
1358
        $this->setUser($this->student);
1359
        $newsectioncontent = '<h1>Title2</h1>New test2';
1360
        $result = mod_wiki_external::edit_page($newpage->id, $newsectioncontent, 'Title1');
1361
 
1362
        $expected = array(
1363
            'version' => '2'
1364
        );
1365
        $result = mod_wiki_external::get_page_for_editing($newpage->id, 'Title1', true);
1366
        $result = external_api::clean_returnvalue(mod_wiki_external::get_page_for_editing_returns(), $result);
1367
        $this->assertEquals($expected, $result['pagesection']);
1368
    }
1369
 
1370
    /**
1371
     * Test new_page. We won't test all the possible cases because that's already
1372
     * done in the tests for wiki_create_page.
1373
     */
11 efrain 1374
    public function test_new_page(): void {
1 efrain 1375
 
1376
        $this->create_individual_wikis_with_groups();
1377
 
1378
        $sectioncontent = '<h1>Title1</h1>Text inside section';
1379
        $pagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
1380
        $pagetitle = 'Page Title';
1381
 
1382
        // Test user with full capabilities.
1383
        $this->setUser($this->student);
1384
 
1385
        // Test on existing subwiki.
1386
        $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid);
1387
        $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result);
1388
        $this->assertIsInt($result['pageid']);
1389
 
1390
        $version = wiki_get_current_version($result['pageid']);
1391
        $this->assertEquals($pagecontent, $version->content);
1392
        $this->assertEquals('html', $version->contentformat);
1393
 
1394
        $page = wiki_get_page($result['pageid']);
1395
        $this->assertEquals($pagetitle, $page->title);
1396
 
1397
        // Test existing page creation.
1398
        try {
1399
            mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid);
1400
            $this->fail('Exception expected due to creation of an existing page.');
1401
        } catch (\moodle_exception $e) {
1402
            $this->assertEquals('pageexists', $e->errorcode);
1403
        }
1404
 
1405
        // Test on non existing subwiki. Add student to group2 to have a new subwiki to be created.
1406
        $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group2->id));
1407
        $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id, $this->student->id,
1408
            $this->group2->id);
1409
        $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result);
1410
        $this->assertIsInt($result['pageid']);
1411
 
1412
        $version = wiki_get_current_version($result['pageid']);
1413
        $this->assertEquals($pagecontent, $version->content);
1414
        $this->assertEquals('html', $version->contentformat);
1415
 
1416
        $page = wiki_get_page($result['pageid']);
1417
        $this->assertEquals($pagetitle, $page->title);
1418
 
1419
        $subwiki = wiki_get_subwiki($page->subwikiid);
1420
        $expected = new \stdClass();
1421
        $expected->id = $subwiki->id;
1422
        $expected->wikiid = $this->wikisepind->id;
1423
        $expected->groupid = $this->group2->id;
1424
        $expected->userid = $this->student->id;
1425
        $this->assertEquals($expected, $subwiki);
1426
 
1427
        // Check page creation for a user not in course.
1428
        $this->studentnotincourse = self::getDataGenerator()->create_user();
1429
        $this->anothercourse = $this->getDataGenerator()->create_course();
1430
        $this->groupnotincourse = $this->getDataGenerator()->create_group(array('courseid' => $this->anothercourse->id));
1431
 
1432
        try {
1433
            mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id,
1434
                $this->studentnotincourse->id, $this->groupnotincourse->id);
1435
            $this->fail('Exception expected due to creation of an invalid subwiki creation.');
1436
        } catch (\moodle_exception $e) {
1437
            $this->assertEquals('cannoteditpage', $e->errorcode);
1438
        }
1439
 
1440
    }
1441
 
1442
    /**
1443
     * Test edit_page. We won't test all the possible cases because that's already
1444
     * done in the tests for wiki_save_section / wiki_save_page.
1445
     */
11 efrain 1446
    public function test_edit_page(): void {
1 efrain 1447
 
1448
        $this->create_individual_wikis_with_groups();
1449
 
1450
        // Test user with full capabilities.
1451
        $this->setUser($this->student);
1452
 
1453
        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wikisepind,
1454
            array('group' => $this->group1->id, 'content' => 'Test'));
1455
 
1456
        // Test edit whole page.
1457
        // We add <span> in the titles to verify the WS works sending HTML in section.
1458
        $sectioncontent = '<h1><span>Title1</span></h1>Text inside section';
1459
        $newpagecontent = $sectioncontent.'<h1><span>Title2</span></h1>Text inside section';
1460
 
1461
        $result = mod_wiki_external::edit_page($newpage->id, $newpagecontent);
1462
        $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
1463
        $this->assertIsInt($result['pageid']);
1464
 
1465
        $version = wiki_get_current_version($result['pageid']);
1466
        $this->assertEquals($newpagecontent, $version->content);
1467
 
1468
        // Test edit section.
1469
        $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1470
        $section = '<span>Title2</span>';
1471
 
1472
        $result = mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1473
        $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
1474
        $this->assertIsInt($result['pageid']);
1475
 
1476
        $expected = $sectioncontent . $newsectioncontent;
1477
 
1478
        $version = wiki_get_current_version($result['pageid']);
1479
        $this->assertEquals($expected, $version->content);
1480
 
1481
        // Test locked section.
1482
        $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1483
        $section = '<span>Title2</span>';
1484
 
1485
        try {
1486
            // Using user 1 to avoid other users to edit.
1487
            wiki_set_lock($newpage->id, 1, $section, true);
1488
            mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1489
            $this->fail('Exception expected due to locked section');
1490
        } catch (\moodle_exception $e) {
1491
            $this->assertEquals('pageislocked', $e->errorcode);
1492
        }
1493
 
1494
        // Test edit non existing section.
1495
        $newsectioncontent = '<h1>Title3</h1>New test3';
1496
        $section = 'Title3';
1497
 
1498
        try {
1499
            mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
1500
            $this->fail('Exception expected due to non existing section in the page.');
1501
        } catch (\moodle_exception $e) {
1502
            $this->assertEquals('invalidsection', $e->errorcode);
1503
        }
1504
 
1505
    }
1506
 
1507
}