Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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   * Unit tests for mod_wiki lib
  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  require_once($CFG->dirroot . '/mod/wiki/lib.php');
  31  require_once($CFG->dirroot . '/mod/wiki/locallib.php');
  32  require_once($CFG->libdir . '/completionlib.php');
  33  
  34  /**
  35   * Unit tests for mod_wiki lib
  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_lib_testcase extends advanced_testcase {
  44  
  45      /**
  46       * Test wiki_view.
  47       *
  48       * @return void
  49       */
  50      public function test_wiki_view() {
  51          global $CFG;
  52  
  53          $CFG->enablecompletion = COMPLETION_ENABLED;
  54          $this->resetAfterTest();
  55  
  56          $this->setAdminUser();
  57          // Setup test data.
  58          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => COMPLETION_ENABLED));
  59          $options = array('completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => COMPLETION_VIEW_REQUIRED);
  60          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id), $options);
  61          $context = context_module::instance($wiki->cmid);
  62          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
  63  
  64          // Trigger and capture the event.
  65          $sink = $this->redirectEvents();
  66  
  67          wiki_view($wiki, $course, $cm, $context);
  68  
  69          $events = $sink->get_events();
  70          // 2 additional events thanks to completion.
  71          $this->assertCount(3, $events);
  72          $event = array_shift($events);
  73  
  74          // Checking that the event contains the expected values.
  75          $this->assertInstanceOf('\mod_wiki\event\course_module_viewed', $event);
  76          $this->assertEquals($context, $event->get_context());
  77          $moodleurl = new \moodle_url('/mod/wiki/view.php', array('id' => $cm->id));
  78          $this->assertEquals($moodleurl, $event->get_url());
  79          $this->assertEventContextNotUsed($event);
  80          $this->assertNotEmpty($event->get_name());
  81  
  82          // Check completion status.
  83          $completion = new completion_info($course);
  84          $completiondata = $completion->get_data($cm);
  85          $this->assertEquals(1, $completiondata->completionstate);
  86  
  87      }
  88  
  89      /**
  90       * Test wiki_page_view.
  91       *
  92       * @return void
  93       */
  94      public function test_wiki_page_view() {
  95          global $CFG;
  96  
  97          $CFG->enablecompletion = COMPLETION_ENABLED;
  98          $this->resetAfterTest();
  99  
 100          $this->setAdminUser();
 101          // Setup test data.
 102          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => COMPLETION_ENABLED));
 103          $options = array('completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => COMPLETION_VIEW_REQUIRED);
 104          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id), $options);
 105          $context = context_module::instance($wiki->cmid);
 106          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
 107          $firstpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($wiki);
 108  
 109          // Trigger and capture the event.
 110          $sink = $this->redirectEvents();
 111  
 112          wiki_page_view($wiki, $firstpage, $course, $cm, $context);
 113  
 114          $events = $sink->get_events();
 115          // 2 additional events thanks to completion.
 116          $this->assertCount(3, $events);
 117          $event = array_shift($events);
 118  
 119          // Checking that the event contains the expected values.
 120          $this->assertInstanceOf('\mod_wiki\event\page_viewed', $event);
 121          $this->assertEquals($context, $event->get_context());
 122          $pageurl = new \moodle_url('/mod/wiki/view.php', array('pageid' => $firstpage->id));
 123          $this->assertEquals($pageurl, $event->get_url());
 124          $this->assertEventContextNotUsed($event);
 125          $this->assertNotEmpty($event->get_name());
 126  
 127          // Check completion status.
 128          $completion = new completion_info($course);
 129          $completiondata = $completion->get_data($cm);
 130          $this->assertEquals(1, $completiondata->completionstate);
 131  
 132      }
 133  
 134      /**
 135       * Test wiki_user_can_edit without groups.
 136       *
 137       * @return void
 138       */
 139      public function test_wiki_user_can_edit() {
 140          global $DB;
 141  
 142          $this->resetAfterTest();
 143          $this->setAdminUser();
 144  
 145          // Setup test data.
 146          $course = $this->getDataGenerator()->create_course();
 147          $indwiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id, 'wikimode' => 'individual'));
 148          $colwiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id, 'wikimode' => 'collaborative'));
 149  
 150          // Create users.
 151          $student = self::getDataGenerator()->create_user();
 152          $teacher = self::getDataGenerator()->create_user();
 153  
 154          // Users enrolments.
 155          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 156          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 157          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 158          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 159  
 160          // Simulate collaborative subwiki.
 161          $swcol = new stdClass();
 162          $swcol->id = -1;
 163          $swcol->wikiid = $colwiki->id;
 164          $swcol->groupid = 0;
 165          $swcol->userid = 0;
 166  
 167          // Simulate individual subwikis (1 per user).
 168          $swindstudent = clone($swcol);
 169          $swindstudent->wikiid = $indwiki->id;
 170          $swindstudent->userid = $student->id;
 171  
 172          $swindteacher = clone($swindstudent);
 173          $swindteacher->userid = $teacher->id;
 174  
 175          $this->setUser($student);
 176  
 177          // Check that the student can edit the collaborative subwiki.
 178          $this->assertTrue(wiki_user_can_edit($swcol));
 179  
 180          // Check that the student can edit his individual subwiki.
 181          $this->assertTrue(wiki_user_can_edit($swindstudent));
 182  
 183          // Check that the student cannot edit teacher's individual subwiki.
 184          $this->assertFalse(wiki_user_can_edit($swindteacher));
 185  
 186          // Now test as a teacher.
 187          $this->setUser($teacher);
 188  
 189          // Check that the teacher can edit the collaborative subwiki.
 190          $this->assertTrue(wiki_user_can_edit($swcol));
 191  
 192          // Check that the teacher can edit his individual subwiki.
 193          $this->assertTrue(wiki_user_can_edit($swindteacher));
 194  
 195          // Check that the teacher can edit student's individual subwiki.
 196          $this->assertTrue(wiki_user_can_edit($swindstudent));
 197  
 198      }
 199  
 200      /**
 201       * Test wiki_user_can_edit using collaborative wikis with groups.
 202       *
 203       * @return void
 204       */
 205      public function test_wiki_user_can_edit_with_groups_collaborative() {
 206          global $DB;
 207  
 208          $this->resetAfterTest();
 209          $this->setAdminUser();
 210  
 211          // Setup test data.
 212          $course = $this->getDataGenerator()->create_course();
 213          $wikisepcol = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 214                                                          'groupmode' => SEPARATEGROUPS, 'wikimode' => 'collaborative'));
 215          $wikiviscol = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 216                                                          'groupmode' => VISIBLEGROUPS, 'wikimode' => 'collaborative'));
 217  
 218          // Create users.
 219          $student = self::getDataGenerator()->create_user();
 220          $student2 = self::getDataGenerator()->create_user();
 221          $teacher = self::getDataGenerator()->create_user();
 222  
 223          // Users enrolments.
 224          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 225          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 226          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 227          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id, 'manual');
 228          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 229  
 230          // Create groups.
 231          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 232          $this->getDataGenerator()->create_group_member(array('userid' => $student->id, 'groupid' => $group1->id));
 233          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group1->id));
 234          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 235          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group2->id));
 236  
 237          // Simulate all the possible subwikis.
 238          // Subwikis in collaborative wikis: 1 subwiki per group + 1 subwiki for all participants.
 239          $swsepcolg1 = new stdClass();
 240          $swsepcolg1->id = -1;
 241          $swsepcolg1->wikiid = $wikisepcol->id;
 242          $swsepcolg1->groupid = $group1->id;
 243          $swsepcolg1->userid = 0;
 244  
 245          $swsepcolg2 = clone($swsepcolg1);
 246          $swsepcolg2->groupid = $group2->id;
 247  
 248          $swsepcolallparts = clone($swsepcolg1); // All participants.
 249          $swsepcolallparts->groupid = 0;
 250  
 251          $swviscolg1 = clone($swsepcolg1);
 252          $swviscolg1->wikiid = $wikiviscol->id;
 253  
 254          $swviscolg2 = clone($swviscolg1);
 255          $swviscolg2->groupid = $group2->id;
 256  
 257          $swviscolallparts = clone($swviscolg1); // All participants.
 258          $swviscolallparts->groupid = 0;
 259  
 260          $this->setUser($student);
 261  
 262          // Check that the student can edit his group's subwiki both in separate and visible groups.
 263          $this->assertTrue(wiki_user_can_edit($swsepcolg1));
 264          $this->assertTrue(wiki_user_can_edit($swviscolg1));
 265  
 266          // Check that the student cannot edit subwiki from group 2 both in separate and visible groups.
 267          $this->assertFalse(wiki_user_can_edit($swsepcolg2));
 268          $this->assertFalse(wiki_user_can_edit($swviscolg2));
 269  
 270          // Now test as student 2.
 271          $this->setUser($student2);
 272  
 273          // Check that the student 2 can edit subwikis from both groups both in separate and visible groups.
 274          $this->assertTrue(wiki_user_can_edit($swsepcolg1));
 275          $this->assertTrue(wiki_user_can_edit($swviscolg1));
 276          $this->assertTrue(wiki_user_can_edit($swsepcolg2));
 277          $this->assertTrue(wiki_user_can_edit($swviscolg2));
 278  
 279          // Check that the student 2 cannot edit subwikis from all participants.
 280          $this->assertFalse(wiki_user_can_edit($swsepcolallparts));
 281          $this->assertFalse(wiki_user_can_edit($swviscolallparts));
 282  
 283          // Now test it as a teacher.
 284          $this->setUser($teacher);
 285  
 286          // Check that teacher can edit all subwikis.
 287          $this->assertTrue(wiki_user_can_edit($swsepcolg1));
 288          $this->assertTrue(wiki_user_can_edit($swviscolg1));
 289          $this->assertTrue(wiki_user_can_edit($swsepcolg2));
 290          $this->assertTrue(wiki_user_can_edit($swviscolg2));
 291          $this->assertTrue(wiki_user_can_edit($swsepcolallparts));
 292          $this->assertTrue(wiki_user_can_edit($swviscolallparts));
 293      }
 294  
 295      /**
 296       * Test wiki_user_can_edit using individual wikis with groups.
 297       *
 298       * @return void
 299       */
 300      public function test_wiki_user_can_edit_with_groups_individual() {
 301          global $DB;
 302  
 303          $this->resetAfterTest();
 304          $this->setAdminUser();
 305  
 306          // Setup test data.
 307          $course = $this->getDataGenerator()->create_course();
 308          $wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 309                                                          'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual'));
 310          $wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 311                                                          'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual'));
 312  
 313          // Create users.
 314          $student = self::getDataGenerator()->create_user();
 315          $student2 = self::getDataGenerator()->create_user();
 316          $teacher = self::getDataGenerator()->create_user();
 317  
 318          // Users enrolments.
 319          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 320          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 321          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 322          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id, 'manual');
 323          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 324  
 325          // Create groups.
 326          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 327          $this->getDataGenerator()->create_group_member(array('userid' => $student->id, 'groupid' => $group1->id));
 328          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group1->id));
 329          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 330          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group2->id));
 331  
 332          // Simulate all the possible subwikis.
 333          // Subwikis in collaborative wikis: 1 subwiki per group + 1 subwiki for all participants.
 334          $swsepindg1s1 = new stdClass();
 335          $swsepindg1s1->id = -1;
 336          $swsepindg1s1->wikiid = $wikisepind->id;
 337          $swsepindg1s1->groupid = $group1->id;
 338          $swsepindg1s1->userid = $student->id;
 339  
 340          $swsepindg1s2 = clone($swsepindg1s1);
 341          $swsepindg1s2->userid = $student2->id;
 342  
 343          $swsepindg2s2 = clone($swsepindg1s2);
 344          $swsepindg2s2->groupid = $group2->id;
 345  
 346          $swsepindteacher = clone($swsepindg1s1);
 347          $swsepindteacher->userid = $teacher->id;
 348          $swsepindteacher->groupid = 0;
 349  
 350          $swvisindg1s1 = clone($swsepindg1s1);
 351          $swvisindg1s1->wikiid = $wikivisind->id;
 352  
 353          $swvisindg1s2 = clone($swvisindg1s1);
 354          $swvisindg1s2->userid = $student2->id;
 355  
 356          $swvisindg2s2 = clone($swvisindg1s2);
 357          $swvisindg2s2->groupid = $group2->id;
 358  
 359          $swvisindteacher = clone($swvisindg1s1);
 360          $swvisindteacher->userid = $teacher->id;
 361          $swvisindteacher->groupid = 0;
 362  
 363          $this->setUser($student);
 364  
 365          // Check that the student can edit his subwiki both in separate and visible groups.
 366          $this->assertTrue(wiki_user_can_edit($swsepindg1s1));
 367          $this->assertTrue(wiki_user_can_edit($swvisindg1s1));
 368  
 369          // Check that the student cannot edit subwikis from another user even if he belongs to his group.
 370          $this->assertFalse(wiki_user_can_edit($swsepindg1s2));
 371          $this->assertFalse(wiki_user_can_edit($swvisindg1s2));
 372  
 373          // Now test as student 2.
 374          $this->setUser($student2);
 375  
 376          // Check that the student 2 can edit his subwikis from both groups both in separate and visible groups.
 377          $this->assertTrue(wiki_user_can_edit($swsepindg1s2));
 378          $this->assertTrue(wiki_user_can_edit($swvisindg1s2));
 379          $this->assertTrue(wiki_user_can_edit($swsepindg2s2));
 380          $this->assertTrue(wiki_user_can_edit($swvisindg2s2));
 381  
 382          // Now test it as a teacher.
 383          $this->setUser($teacher);
 384  
 385          // Check that teacher can edit all subwikis.
 386          $this->assertTrue(wiki_user_can_edit($swsepindg1s1));
 387          $this->assertTrue(wiki_user_can_edit($swsepindg1s2));
 388          $this->assertTrue(wiki_user_can_edit($swsepindg2s2));
 389          $this->assertTrue(wiki_user_can_edit($swsepindteacher));
 390          $this->assertTrue(wiki_user_can_edit($swvisindg1s1));
 391          $this->assertTrue(wiki_user_can_edit($swvisindg1s2));
 392          $this->assertTrue(wiki_user_can_edit($swvisindg2s2));
 393          $this->assertTrue(wiki_user_can_edit($swvisindteacher));
 394      }
 395  
 396      /**
 397       * Test wiki_get_visible_subwikis without groups.
 398       *
 399       * @return void
 400       */
 401      public function test_wiki_get_visible_subwikis_without_groups() {
 402          global $DB;
 403  
 404          $this->resetAfterTest();
 405          $this->setAdminUser();
 406  
 407          // Setup test data.
 408          $course = $this->getDataGenerator()->create_course();
 409          $indwiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id, 'wikimode' => 'individual'));
 410          $colwiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id, 'wikimode' => 'collaborative'));
 411  
 412          // Create users.
 413          $student = self::getDataGenerator()->create_user();
 414          $teacher = self::getDataGenerator()->create_user();
 415  
 416          // Users enrolments.
 417          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 418          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 419          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 420          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 421  
 422          $this->setUser($student);
 423  
 424          // Check that not passing a wiki returns empty array.
 425          $result = wiki_get_visible_subwikis(null);
 426          $this->assertEquals(array(), $result);
 427  
 428          // Check that the student can get the only subwiki from the collaborative wiki.
 429          $expectedsubwikis = array();
 430          $expectedsubwiki = new stdClass();
 431          $expectedsubwiki->id = -1; // We haven't created any page so the subwiki hasn't been created.
 432          $expectedsubwiki->wikiid = $colwiki->id;
 433          $expectedsubwiki->groupid = 0;
 434          $expectedsubwiki->userid = 0;
 435          $expectedsubwikis[] = $expectedsubwiki;
 436  
 437          $result = wiki_get_visible_subwikis($colwiki);
 438          $this->assertEquals($expectedsubwikis, $result);
 439  
 440          // Create a page now so the subwiki is created.
 441          $colfirstpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($colwiki);
 442  
 443          // Call the function again, now we expect to have a subwiki ID.
 444          $expectedsubwikis[0]->id = $colfirstpage->subwikiid;
 445          $result = wiki_get_visible_subwikis($colwiki);
 446          $this->assertEquals($expectedsubwikis, $result);
 447  
 448          // Check that the teacher can see it too.
 449          $this->setUser($teacher);
 450          $result = wiki_get_visible_subwikis($colwiki);
 451          $this->assertEquals($expectedsubwikis, $result);
 452  
 453          // Check that the student can only see his subwiki in the individual wiki.
 454          $this->setUser($student);
 455          $expectedsubwikis[0]->id = -1;
 456          $expectedsubwikis[0]->wikiid = $indwiki->id;
 457          $expectedsubwikis[0]->userid = $student->id;
 458          $result = wiki_get_visible_subwikis($indwiki);
 459          $this->assertEquals($expectedsubwikis, $result);
 460  
 461          // Check that the teacher can see his subwiki and the student subwiki in the individual wiki.
 462          $this->setUser($teacher);
 463          $teachersubwiki = new stdClass();
 464          $teachersubwiki->id = -1;
 465          $teachersubwiki->wikiid = $indwiki->id;
 466          $teachersubwiki->groupid = 0;
 467          $teachersubwiki->userid = $teacher->id;
 468          $expectedsubwikis[] = $teachersubwiki;
 469  
 470          $result = wiki_get_visible_subwikis($indwiki);
 471          $this->assertEqualsCanonicalizing($expectedsubwikis, $result); // Compare without order.
 472      }
 473  
 474      /**
 475       * Test wiki_get_visible_subwikis using collaborative wikis with groups.
 476       *
 477       * @return void
 478       */
 479      public function test_wiki_get_visible_subwikis_with_groups_collaborative() {
 480          global $DB;
 481  
 482          $this->resetAfterTest();
 483          $this->setAdminUser();
 484  
 485          // Setup test data.
 486          $course = $this->getDataGenerator()->create_course();
 487          $wikisepcol = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 488                                                          'groupmode' => SEPARATEGROUPS, 'wikimode' => 'collaborative'));
 489          $wikiviscol = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 490                                                          'groupmode' => VISIBLEGROUPS, 'wikimode' => 'collaborative'));
 491  
 492          // Create users.
 493          $student = self::getDataGenerator()->create_user();
 494          $student2 = self::getDataGenerator()->create_user();
 495          $student3 = self::getDataGenerator()->create_user();
 496          $teacher = self::getDataGenerator()->create_user();
 497  
 498          // Users enrolments.
 499          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 500          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 501          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 502          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id, 'manual');
 503          $this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id, 'manual');
 504          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 505  
 506          // Create groups.
 507          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 508          $this->getDataGenerator()->create_group_member(array('userid' => $student->id, 'groupid' => $group1->id));
 509          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group1->id));
 510          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 511          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group2->id));
 512          $this->getDataGenerator()->create_group_member(array('userid' => $student3->id, 'groupid' => $group2->id));
 513  
 514          $this->setUser($student);
 515  
 516          // Create all the possible subwikis. We haven't created any page so ids will be -1.
 517          // Subwikis in collaborative wikis: 1 subwiki per group + 1 subwiki for all participants.
 518          $swsepcolg1 = new stdClass();
 519          $swsepcolg1->id = -1;
 520          $swsepcolg1->wikiid = $wikisepcol->id;
 521          $swsepcolg1->groupid = $group1->id;
 522          $swsepcolg1->userid = 0;
 523  
 524          $swsepcolg2 = clone($swsepcolg1);
 525          $swsepcolg2->groupid = $group2->id;
 526  
 527          $swsepcolallparts = clone($swsepcolg1); // All participants.
 528          $swsepcolallparts->groupid = 0;
 529  
 530          $swviscolg1 = clone($swsepcolg1);
 531          $swviscolg1->wikiid = $wikiviscol->id;
 532  
 533          $swviscolg2 = clone($swviscolg1);
 534          $swviscolg2->groupid = $group2->id;
 535  
 536          $swviscolallparts = clone($swviscolg1); // All participants.
 537          $swviscolallparts->groupid = 0;
 538  
 539          // Check that the student can get only the subwiki from his group in collaborative wiki with separate groups.
 540          $expectedsubwikis = array($swsepcolg1);
 541          $result = wiki_get_visible_subwikis($wikisepcol);
 542          $this->assertEquals($expectedsubwikis, $result);
 543  
 544          // Check that he can get subwikis from both groups in collaborative wiki with visible groups, and also all participants.
 545          $expectedsubwikis = array($swviscolallparts, $swviscolg1, $swviscolg2);
 546          $result = wiki_get_visible_subwikis($wikiviscol);
 547          $this->assertEqualsCanonicalizing($expectedsubwikis, $result);
 548  
 549          // Now test it as a teacher. No need to check visible groups wikis because the result is the same as student.
 550          $this->setUser($teacher);
 551  
 552          // Check that he can get the subwikis from all the groups in collaborative wiki with separate groups.
 553          $expectedsubwikis = array($swsepcolg1, $swsepcolg2, $swsepcolallparts);
 554          $result = wiki_get_visible_subwikis($wikisepcol);
 555          $this->assertEqualsCanonicalizing($expectedsubwikis, $result);
 556      }
 557  
 558      /**
 559       * Test wiki_get_visible_subwikis using individual wikis with groups.
 560       *
 561       * @return void
 562       */
 563      public function test_wiki_get_visible_subwikis_with_groups_individual() {
 564          global $DB;
 565  
 566          $this->resetAfterTest();
 567          $this->setAdminUser();
 568  
 569          // Setup test data.
 570          $course = $this->getDataGenerator()->create_course();
 571          $wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 572                                                          'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual'));
 573          $wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id,
 574                                                          'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual'));
 575  
 576          // Create users.
 577          $student = self::getDataGenerator()->create_user();
 578          $student2 = self::getDataGenerator()->create_user();
 579          $student3 = self::getDataGenerator()->create_user();
 580          $teacher = self::getDataGenerator()->create_user();
 581  
 582          // Users enrolments.
 583          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 584          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 585          $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
 586          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id, 'manual');
 587          $this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id, 'manual');
 588          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id, 'manual');
 589  
 590          // Create groups.
 591          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 592          $this->getDataGenerator()->create_group_member(array('userid' => $student->id, 'groupid' => $group1->id));
 593          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group1->id));
 594          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
 595          $this->getDataGenerator()->create_group_member(array('userid' => $student2->id, 'groupid' => $group2->id));
 596          $this->getDataGenerator()->create_group_member(array('userid' => $student3->id, 'groupid' => $group2->id));
 597  
 598          $this->setUser($student);
 599  
 600          // Create all the possible subwikis to be returned. We haven't created any page so ids will be -1.
 601          // Subwikis in individual wikis: 1 subwiki per user and group. If user doesn't belong to any group then groupid is 0.
 602          $swsepindg1s1 = new stdClass();
 603          $swsepindg1s1->id = -1;
 604          $swsepindg1s1->wikiid = $wikisepind->id;
 605          $swsepindg1s1->groupid = $group1->id;
 606          $swsepindg1s1->userid = $student->id;
 607  
 608          $swsepindg1s2 = clone($swsepindg1s1);
 609          $swsepindg1s2->userid = $student2->id;
 610  
 611          $swsepindg2s2 = clone($swsepindg1s2);
 612          $swsepindg2s2->groupid = $group2->id;
 613  
 614          $swsepindg2s3 = clone($swsepindg1s1);
 615          $swsepindg2s3->userid = $student3->id;
 616          $swsepindg2s3->groupid = $group2->id;
 617  
 618          $swsepindteacher = clone($swsepindg1s1);
 619          $swsepindteacher->userid = $teacher->id;
 620          $swsepindteacher->groupid = 0;
 621  
 622          $swvisindg1s1 = clone($swsepindg1s1);
 623          $swvisindg1s1->wikiid = $wikivisind->id;
 624  
 625          $swvisindg1s2 = clone($swvisindg1s1);
 626          $swvisindg1s2->userid = $student2->id;
 627  
 628          $swvisindg2s2 = clone($swvisindg1s2);
 629          $swvisindg2s2->groupid = $group2->id;
 630  
 631          $swvisindg2s3 = clone($swvisindg1s1);
 632          $swvisindg2s3->userid = $student3->id;
 633          $swvisindg2s3->groupid = $group2->id;
 634  
 635          $swvisindteacher = clone($swvisindg1s1);
 636          $swvisindteacher->userid = $teacher->id;
 637          $swvisindteacher->groupid = 0;
 638  
 639          // Check that student can get the subwikis from his group in individual wiki with separate groups.
 640          $expectedsubwikis = array($swsepindg1s1, $swsepindg1s2);
 641          $result = wiki_get_visible_subwikis($wikisepind);
 642          $this->assertEqualsCanonicalizing($expectedsubwikis, $result);
 643  
 644          // Check that he can get subwikis from all users and groups in individual wiki with visible groups.
 645          $expectedsubwikis = array($swvisindg1s1, $swvisindg1s2, $swvisindg2s2, $swvisindg2s3, $swvisindteacher);
 646          $result = wiki_get_visible_subwikis($wikivisind);
 647          $this->assertEqualsCanonicalizing($expectedsubwikis, $result);
 648  
 649          // Now test it as a teacher. No need to check visible groups wikis because the result is the same as student.
 650          $this->setUser($teacher);
 651  
 652          // Check that teacher can get the subwikis from all the groups in individual wiki with separate groups.
 653          $expectedsubwikis = array($swsepindg1s1, $swsepindg1s2, $swsepindg2s2, $swsepindg2s3, $swsepindteacher);
 654          $result = wiki_get_visible_subwikis($wikisepind);
 655          $this->assertEqualsCanonicalizing($expectedsubwikis, $result);
 656      }
 657  
 658      public function test_mod_wiki_get_tagged_pages() {
 659          global $DB;
 660  
 661          $this->resetAfterTest();
 662          $this->setAdminUser();
 663  
 664          // Setup test data.
 665          $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
 666          $course3 = $this->getDataGenerator()->create_course();
 667          $course2 = $this->getDataGenerator()->create_course();
 668          $course1 = $this->getDataGenerator()->create_course();
 669          $wiki1 = $this->getDataGenerator()->create_module('wiki', array('course' => $course1->id));
 670          $wiki2 = $this->getDataGenerator()->create_module('wiki', array('course' => $course2->id));
 671          $wiki3 = $this->getDataGenerator()->create_module('wiki', array('course' => $course3->id));
 672          $page11 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats', 'Dogs')));
 673          $page12 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats', 'mice')));
 674          $page13 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats')));
 675          $page14 = $wikigenerator->create_content($wiki1);
 676          $page15 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats')));
 677          $page21 = $wikigenerator->create_content($wiki2, array('tags' => array('Cats')));
 678          $page22 = $wikigenerator->create_content($wiki2, array('tags' => array('Cats', 'Dogs')));
 679          $page23 = $wikigenerator->create_content($wiki2, array('tags' => array('mice', 'Cats')));
 680          $page31 = $wikigenerator->create_content($wiki3, array('tags' => array('mice', 'Cats')));
 681  
 682          $tag = core_tag_tag::get_by_name(0, 'Cats');
 683  
 684          // Admin can see everything.
 685          $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
 686                  /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */0);
 687          $this->assertRegExp('/'.$page11->title.'/', $res->content);
 688          $this->assertRegExp('/'.$page12->title.'/', $res->content);
 689          $this->assertRegExp('/'.$page13->title.'/', $res->content);
 690          $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
 691          $this->assertRegExp('/'.$page15->title.'/', $res->content);
 692          $this->assertRegExp('/'.$page21->title.'/', $res->content);
 693          $this->assertNotRegExp('/'.$page22->title.'/', $res->content);
 694          $this->assertNotRegExp('/'.$page23->title.'/', $res->content);
 695          $this->assertNotRegExp('/'.$page31->title.'/', $res->content);
 696          $this->assertEmpty($res->prevpageurl);
 697          $this->assertNotEmpty($res->nextpageurl);
 698          $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
 699                  /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */1);
 700          $this->assertNotRegExp('/'.$page11->title.'/', $res->content);
 701          $this->assertNotRegExp('/'.$page12->title.'/', $res->content);
 702          $this->assertNotRegExp('/'.$page13->title.'/', $res->content);
 703          $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
 704          $this->assertNotRegExp('/'.$page15->title.'/', $res->content);
 705          $this->assertNotRegExp('/'.$page21->title.'/', $res->content);
 706          $this->assertRegExp('/'.$page22->title.'/', $res->content);
 707          $this->assertRegExp('/'.$page23->title.'/', $res->content);
 708          $this->assertRegExp('/'.$page31->title.'/', $res->content);
 709          $this->assertNotEmpty($res->prevpageurl);
 710          $this->assertEmpty($res->nextpageurl);
 711  
 712          // Create and enrol a user.
 713          $student = self::getDataGenerator()->create_user();
 714          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 715          $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
 716          $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
 717          $this->setUser($student);
 718          core_tag_index_builder::reset_caches();
 719  
 720          // User can not see pages in course 3 because he is not enrolled.
 721          $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
 722                  /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */1);
 723          $this->assertRegExp('/'.$page22->title.'/', $res->content);
 724          $this->assertRegExp('/'.$page23->title.'/', $res->content);
 725          $this->assertNotRegExp('/'.$page31->title.'/', $res->content);
 726  
 727          // User can search wiki pages inside a course.
 728          $coursecontext = context_course::instance($course1->id);
 729          $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
 730                  /*$fromctx = */0, /*$ctx = */$coursecontext->id, /*$rec = */1, /*$page = */0);
 731          $this->assertRegExp('/'.$page11->title.'/', $res->content);
 732          $this->assertRegExp('/'.$page12->title.'/', $res->content);
 733          $this->assertRegExp('/'.$page13->title.'/', $res->content);
 734          $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
 735          $this->assertRegExp('/'.$page15->title.'/', $res->content);
 736          $this->assertNotRegExp('/'.$page21->title.'/', $res->content);
 737          $this->assertNotRegExp('/'.$page22->title.'/', $res->content);
 738          $this->assertNotRegExp('/'.$page23->title.'/', $res->content);
 739          $this->assertEmpty($res->nextpageurl);
 740      }
 741  
 742      public function test_wiki_core_calendar_provide_event_action() {
 743          $this->resetAfterTest();
 744          $this->setAdminUser();
 745  
 746          // Create the activity.
 747          $course = $this->getDataGenerator()->create_course();
 748          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id));
 749  
 750          // Create a calendar event.
 751          $event = $this->create_action_event($course->id, $wiki->id,
 752              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 753  
 754          // Create an action factory.
 755          $factory = new \core_calendar\action_factory();
 756  
 757          // Decorate action event.
 758          $actionevent = mod_wiki_core_calendar_provide_event_action($event, $factory);
 759  
 760          // Confirm the event was decorated.
 761          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
 762          $this->assertEquals(get_string('view'), $actionevent->get_name());
 763          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
 764          $this->assertEquals(1, $actionevent->get_item_count());
 765          $this->assertTrue($actionevent->is_actionable());
 766      }
 767  
 768      public function test_wiki_core_calendar_provide_event_action_for_non_user() {
 769          global $CFG;
 770  
 771          $this->resetAfterTest();
 772          $this->setAdminUser();
 773  
 774          // Create the activity.
 775          $course = $this->getDataGenerator()->create_course();
 776          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id));
 777  
 778          // Create a calendar event.
 779          $event = $this->create_action_event($course->id, $wiki->id,
 780                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 781  
 782          // Now, log out.
 783          $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
 784          $this->setUser();
 785  
 786          // Create an action factory.
 787          $factory = new \core_calendar\action_factory();
 788  
 789          // Decorate action event for the student.
 790          $actionevent = mod_wiki_core_calendar_provide_event_action($event, $factory);
 791  
 792          // Confirm the event is not shown at all.
 793          $this->assertNull($actionevent);
 794      }
 795  
 796      public function test_wiki_core_calendar_provide_event_action_for_user() {
 797          global $CFG;
 798  
 799          $this->resetAfterTest();
 800          $this->setAdminUser();
 801  
 802          // Create the activity.
 803          $course = $this->getDataGenerator()->create_course();
 804          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id));
 805          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 806  
 807          // Create a calendar event.
 808          $event = $this->create_action_event($course->id, $wiki->id,
 809                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 810  
 811          // Now log out.
 812          $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
 813          $this->setUser();
 814  
 815          // Create an action factory.
 816          $factory = new \core_calendar\action_factory();
 817  
 818          // Decorate action event for the student.
 819          $actionevent = mod_wiki_core_calendar_provide_event_action($event, $factory, $student->id);
 820  
 821          // Confirm the event was decorated.
 822          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
 823          $this->assertEquals(get_string('view'), $actionevent->get_name());
 824          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
 825          $this->assertEquals(1, $actionevent->get_item_count());
 826          $this->assertTrue($actionevent->is_actionable());
 827      }
 828  
 829      public function test_wiki_core_calendar_provide_event_action_already_completed() {
 830          global $CFG;
 831  
 832          $this->resetAfterTest();
 833          $this->setAdminUser();
 834  
 835          $CFG->enablecompletion = 1;
 836  
 837          // Create the activity.
 838          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 839          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id),
 840              array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 841  
 842          // Get some additional data.
 843          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
 844  
 845          // Create a calendar event.
 846          $event = $this->create_action_event($course->id, $wiki->id,
 847              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 848  
 849          // Mark the activity as completed.
 850          $completion = new completion_info($course);
 851          $completion->set_module_viewed($cm);
 852  
 853          // Create an action factory.
 854          $factory = new \core_calendar\action_factory();
 855  
 856          // Decorate action event.
 857          $actionevent = mod_wiki_core_calendar_provide_event_action($event, $factory);
 858  
 859          // Ensure result was null.
 860          $this->assertNull($actionevent);
 861      }
 862  
 863      public function test_wiki_core_calendar_provide_event_action_already_completed_for_user() {
 864          global $CFG;
 865  
 866          $this->resetAfterTest();
 867          $this->setAdminUser();
 868  
 869          $CFG->enablecompletion = 1;
 870  
 871          // Create the activity.
 872          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 873          $wiki = $this->getDataGenerator()->create_module('wiki', array('course' => $course->id),
 874                  array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 875  
 876          // Create 2 students and enrol them into the course.
 877          $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
 878          $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
 879  
 880          // Get some additional data.
 881          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
 882  
 883          // Create a calendar event.
 884          $event = $this->create_action_event($course->id, $wiki->id,
 885                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 886  
 887          // Mark the activity as completed for the $student1.
 888          $completion = new completion_info($course);
 889          $completion->set_module_viewed($cm, $student1->id);
 890  
 891          // Now log in as $student2.
 892          $this->setUser($student2);
 893  
 894          // Create an action factory.
 895          $factory = new \core_calendar\action_factory();
 896  
 897          // Decorate action event for $student1.
 898          $actionevent = mod_wiki_core_calendar_provide_event_action($event, $factory, $student1->id);
 899  
 900          // Ensure result was null.
 901          $this->assertNull($actionevent);
 902      }
 903  
 904      /**
 905       * Creates an action event.
 906       *
 907       * @param int $courseid The course id.
 908       * @param int $instanceid The instance id.
 909       * @param string $eventtype The event type.
 910       * @return bool|calendar_event
 911       */
 912      private function create_action_event($courseid, $instanceid, $eventtype) {
 913          $event = new stdClass();
 914          $event->name = 'Calendar event';
 915          $event->modulename  = 'wiki';
 916          $event->courseid = $courseid;
 917          $event->instance = $instanceid;
 918          $event->type = CALENDAR_EVENT_TYPE_ACTION;
 919          $event->eventtype = $eventtype;
 920          $event->timestart = time();
 921  
 922          return calendar_event::create($event);
 923      }
 924  }