Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
  • Differences Between: [Versions 310 and 311] [Versions 37 and 311] [Versions 38 and 311] [Versions 39 and 311]

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