Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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  /**
  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   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  
  31  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  32  require_once($CFG->dirroot . '/mod/wiki/lib.php');
  33  
  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 {
  44  
  45      /**
  46       * Set up for every test
  47       */
  48      public function setUp() {
  49          global $DB;
  50          $this->resetAfterTest();
  51          $this->setAdminUser();
  52  
  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);
  58  
  59          // Create users.
  60          $this->student = self::getDataGenerator()->create_user();
  61          $this->student2 = self::getDataGenerator()->create_user();
  62          $this->teacher = self::getDataGenerator()->create_user();
  63  
  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');
  70  
  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      }
  75  
  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          }
  89  
  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));
  95  
  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      }
 105  
 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          }
 119  
 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'));
 125  
 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.
 135  
 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));
 139  
 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));
 143  
 144      }
 145  
 146      /*
 147       * Test get wikis by courses
 148       */
 149      public function test_mod_wiki_get_wikis_by_courses() {
 150  
 151          // Create additional course.
 152          $course2 = self::getDataGenerator()->create_course();
 153  
 154          // Second wiki.
 155          $record = new stdClass();
 156          $record->course = $course2->id;
 157          $wiki2 = self::getDataGenerator()->create_module('wiki', $record);
 158  
 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);
 169  
 170          self::setUser($this->student);
 171  
 172          $returndescription = mod_wiki_external::get_wikis_by_courses_returns();
 173  
 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');
 179  
 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 = [];
 189  
 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 = [];
 197  
 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;
 205  
 206          $expectedwikis = array($expected2, $expected1);
 207  
 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);
 211  
 212          $this->assertEquals($expectedwikis, $result['wikis']);
 213          $this->assertCount(0, $result['warnings']);
 214  
 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']);
 220  
 221          // Unenrol user from second course and alter expected wikis.
 222          $enrol->unenrol_user($instance2, $this->student->id);
 223          array_shift($expectedwikis);
 224  
 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']);
 229  
 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']);
 235  
 236          // Now, try as a teacher for getting all the additional fields.
 237          self::setUser($this->teacher);
 238  
 239          $additionalfields = array('timecreated', 'timemodified');
 240  
 241          foreach ($additionalfields as $field) {
 242              $expectedwikis[0][$field] = $wiki1->{$field};
 243          }
 244  
 245          $result = mod_wiki_external::get_wikis_by_courses();
 246          $result = external_api::clean_returnvalue($returndescription, $result);
 247          $this->assertEquals($expectedwikis, $result['wikis']);
 248  
 249          // Admin also should get all the information.
 250          self::setAdminUser();
 251  
 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']);
 255  
 256          // Now, prohibit capabilities.
 257          $this->setUser($this->student);
 258          $contextcourse1 = context_course::instance($this->course->id);
 259  
 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']);
 265  
 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);
 270  
 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']));
 274  
 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);
 280  
 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']);
 284  
 285      }
 286  
 287      /**
 288       * Test view_wiki.
 289       */
 290      public function test_view_wiki() {
 291  
 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          }
 299  
 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          }
 309  
 310          // Test user with full capabilities.
 311          $this->setUser($this->student);
 312  
 313          // Trigger and capture the event.
 314          $sink = $this->redirectEvents();
 315  
 316          $result = mod_wiki_external::view_wiki($this->wiki->id);
 317          $result = external_api::clean_returnvalue(mod_wiki_external::view_wiki_returns(), $result);
 318  
 319          $events = $sink->get_events();
 320          $this->assertCount(1, $events);
 321          $event = array_shift($events);
 322  
 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());
 330  
 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();
 335  
 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          }
 342  
 343      }
 344  
 345      /**
 346       * Test view_page.
 347       */
 348      public function test_view_page() {
 349  
 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          }
 357  
 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          }
 367  
 368          // Test user with full capabilities.
 369          $this->setUser($this->student);
 370  
 371          // Trigger and capture the event.
 372          $sink = $this->redirectEvents();
 373  
 374          $result = mod_wiki_external::view_page($this->firstpage->id);
 375          $result = external_api::clean_returnvalue(mod_wiki_external::view_page_returns(), $result);
 376  
 377          $events = $sink->get_events();
 378          $this->assertCount(1, $events);
 379          $event = array_shift($events);
 380  
 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());
 388  
 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();
 393  
 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          }
 400  
 401      }
 402  
 403      /**
 404       * Test get_subwikis.
 405       */
 406      public function test_get_subwikis() {
 407  
 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          }
 415  
 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          }
 425  
 426          // Test user with full capabilities.
 427          $this->setUser($this->student);
 428  
 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;
 440  
 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']);
 445  
 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();
 450  
 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          }
 457  
 458      }
 459  
 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      }
 468  
 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);
 478  
 479          mod_wiki_external::get_subwiki_pages($this->wiki->id);
 480      }
 481  
 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));
 491  
 492          $this->setUser($this->student);
 493          mod_wiki_external::get_subwiki_pages($hiddenwiki->id);
 494      }
 495  
 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();
 506  
 507          $this->setUser($this->student);
 508          mod_wiki_external::get_subwiki_pages($this->wiki->id);
 509      }
 510  
 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'));
 520  
 521          mod_wiki_external::get_subwiki_pages($indwiki->id, 0, -10);
 522      }
 523  
 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();
 532  
 533          mod_wiki_external::get_subwiki_pages($this->wikisep->id, -111);
 534      }
 535  
 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'));
 545  
 546          $this->setUser($this->student);
 547          mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id);
 548      }
 549  
 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();
 559  
 560          $this->setUser($this->student);
 561          mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group2->id);
 562      }
 563  
 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();
 573  
 574          $this->setUser($this->student);
 575          mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group2->id, $this->teacher->id);
 576      }
 577  
 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();
 587  
 588          $this->setUser($this->student);
 589          mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0);
 590      }
 591  
 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();
 601  
 602          $this->setUser($this->student);
 603          mod_wiki_external::get_subwiki_pages($this->wikisepind->id, 0, $this->teacher->id);
 604      }
 605  
 606      /**
 607       * Test get_subwiki_pages without groups and collaborative wiki.
 608       */
 609      public function test_get_subwiki_pages_collaborative() {
 610  
 611          // Test user with full capabilities.
 612          $this->setUser($this->student);
 613  
 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;
 625  
 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']);
 629  
 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']);
 634  
 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']);
 639  
 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'));
 643  
 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.
 650  
 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']);
 654  
 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']);
 660  
 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      }
 675  
 676      /**
 677       * Test get_subwiki_pages without groups.
 678       */
 679      public function test_get_subwiki_pages_individual() {
 680  
 681          // Create an individual wiki to test userid param.
 682          $indwiki = $this->getDataGenerator()->create_module('wiki',
 683                                  array('course' => $this->course->id, 'wikimode' => 'individual'));
 684  
 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']);
 689  
 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);
 695  
 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);
 703  
 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']);
 707  
 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);
 715  
 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']);
 719  
 720          // Now check that student can get his pages.
 721          $this->setUser($this->student);
 722  
 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']);
 726  
 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      }
 732  
 733      /**
 734       * Test get_subwiki_pages with groups and collaborative wikis.
 735       */
 736      public function test_get_subwiki_pages_separate_groups_collaborative() {
 737  
 738          // Create testing data.
 739          $this->create_collaborative_wikis_with_groups();
 740  
 741          $this->setUser($this->student);
 742  
 743          // Try to get pages from a valid group in separate groups wiki.
 744  
 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);
 751  
 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']);
 755  
 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']);
 760  
 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']);
 766  
 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);
 774  
 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      }
 779  
 780      /**
 781       * Test get_subwiki_pages with groups and collaborative wikis.
 782       */
 783      public function test_get_subwiki_pages_visible_groups_collaborative() {
 784  
 785          // Create testing data.
 786          $this->create_collaborative_wikis_with_groups();
 787  
 788          $this->setUser($this->student);
 789  
 790          // Try to get pages from a valid group in visible groups wiki.
 791  
 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);
 798  
 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']);
 802  
 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);
 810  
 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']);
 814  
 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);
 822  
 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      }
 827  
 828      /**
 829       * Test get_subwiki_pages with groups and individual wikis.
 830       */
 831      public function test_get_subwiki_pages_separate_groups_individual() {
 832  
 833          // Create testing data.
 834          $this->create_individual_wikis_with_groups();
 835  
 836          $this->setUser($this->student);
 837  
 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);
 845  
 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']);
 849  
 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']);
 854  
 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']);
 860  
 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);
 869  
 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      }
 874  
 875      /**
 876       * Test get_subwiki_pages with groups and individual wikis.
 877       */
 878      public function test_get_subwiki_pages_visible_groups_individual() {
 879  
 880          // Create testing data.
 881          $this->create_individual_wikis_with_groups();
 882  
 883          $this->setUser($this->student);
 884  
 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);
 892  
 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']);
 896  
 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);
 904  
 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']);
 908  
 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);
 916  
 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      }
 921  
 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      }
 930  
 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);
 940  
 941          mod_wiki_external::get_page_contents($this->firstpage->id);
 942      }
 943  
 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);
 954  
 955          $this->setUser($this->student);
 956          mod_wiki_external::get_page_contents($hiddenpage->id);
 957      }
 958  
 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();
 969  
 970          $this->setUser($this->student);
 971          mod_wiki_external::get_page_contents($this->firstpage->id);
 972      }
 973  
 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();
 983  
 984          $this->setUser($this->student);
 985          mod_wiki_external::get_page_contents($this->fpsepg2indt->id);
 986      }
 987  
 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() {
 993  
 994          // Test user with full capabilities.
 995          $this->setUser($this->student);
 996  
 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'];
1014  
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']);
1018  
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);
1021  
1022          $expectedpage['id'] = $newpage->id;
1023          $expectedpage['title'] = $newpage->title;
1024          $expectedpage['cachedcontent'] = $newpage->cachedcontent;
1025          $expectedpage['tags'] = array();
1026  
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      }
1031  
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() {
1037  
1038          // Create testing data.
1039          $this->create_individual_wikis_with_groups();
1040  
1041          // Try to get page from a valid group in separate groups wiki.
1042          $this->setUser($this->student);
1043  
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          );
1057  
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']);
1061  
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      }
1068  
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      }
1078  
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();
1088  
1089          $this->setUser($this->student);
1090          mod_wiki_external::get_subwiki_files($this->wikisep->id, $this->group2->id);
1091      }
1092  
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);
1098  
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);
1106  
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          );
1117  
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]);
1123  
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);
1129  
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']);
1135  
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      }
1143  
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();
1150  
1151          $this->setUser($this->student);
1152  
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);
1161  
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          );
1172  
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]);
1178  
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      }
1186  
1187  
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() {
1193  
1194          $this->create_individual_wikis_with_groups();
1195  
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));
1201  
1202          // Test user with full capabilities.
1203          $this->setUser($this->student);
1204  
1205          // Set expected result: Full Page content.
1206          $expected = array(
1207              'content' => $pagecontent,
1208              'contentformat' => 'html',
1209              'version' => '1'
1210          );
1211  
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']);
1215  
1216          // Set expected result: Section Page content.
1217          $expected = array(
1218              'content' => $sectioncontent,
1219              'contentformat' => 'html',
1220              'version' => '1'
1221          );
1222  
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      }
1227  
1228      /**
1229       * Test test_get_page_locking.
1230       */
1231      public function test_get_page_locking() {
1232  
1233          $this->create_individual_wikis_with_groups();
1234  
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));
1238  
1239          // Test user with full capabilities.
1240          $this->setUser($this->student);
1241  
1242          // Test Section locking.
1243          $expected = array(
1244              'version' => '1'
1245          );
1246  
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']);
1250  
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          }
1259  
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          }
1267  
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']);
1272  
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');
1277  
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      }
1285  
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() {
1291  
1292          $this->create_individual_wikis_with_groups();
1293  
1294          $sectioncontent = '<h1>Title1</h1>Text inside section';
1295          $pagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
1296          $pagetitle = 'Page Title';
1297  
1298          // Test user with full capabilities.
1299          $this->setUser($this->student);
1300  
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']);
1305  
1306          $version = wiki_get_current_version($result['pageid']);
1307          $this->assertEquals($pagecontent, $version->content);
1308          $this->assertEquals('html', $version->contentformat);
1309  
1310          $page = wiki_get_page($result['pageid']);
1311          $this->assertEquals($pagetitle, $page->title);
1312  
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          }
1320  
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']);
1327  
1328          $version = wiki_get_current_version($result['pageid']);
1329          $this->assertEquals($pagecontent, $version->content);
1330          $this->assertEquals('html', $version->contentformat);
1331  
1332          $page = wiki_get_page($result['pageid']);
1333          $this->assertEquals($pagetitle, $page->title);
1334  
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);
1342  
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));
1347  
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          }
1355  
1356      }
1357  
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() {
1363  
1364          $this->create_individual_wikis_with_groups();
1365  
1366          // Test user with full capabilities.
1367          $this->setUser($this->student);
1368  
1369          $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wikisepind,
1370              array('group' => $this->group1->id, 'content' => 'Test'));
1371  
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';
1376  
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']);
1380  
1381          $version = wiki_get_current_version($result['pageid']);
1382          $this->assertEquals($newpagecontent, $version->content);
1383  
1384          // Test edit section.
1385          $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1386          $section = '<span>Title2</span>';
1387  
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']);
1391  
1392          $expected = $sectioncontent . $newsectioncontent;
1393  
1394          $version = wiki_get_current_version($result['pageid']);
1395          $this->assertEquals($expected, $version->content);
1396  
1397          // Test locked section.
1398          $newsectioncontent = '<h1><span>Title2</span></h1>New test2';
1399          $section = '<span>Title2</span>';
1400  
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          }
1409  
1410          // Test edit non existing section.
1411          $newsectioncontent = '<h1>Title3</h1>New test3';
1412          $section = 'Title3';
1413  
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          }
1420  
1421      }
1422  
1423  }