Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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   * Course global search unit tests.
  19   *
  20   * @package     core_user
  21   * @copyright   2016 Devang Gaur {@link http://www.devanggaur.com}
  22   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace core_user\search;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
  31  
  32  /**
  33   * Provides the unit tests for course global search.
  34   *
  35   * @package     core
  36   * @copyright   2016 Devang Gaur {@link http://www.davidmonllao.com}
  37   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class search_test extends \advanced_testcase {
  40  
  41      /**
  42       * @var string Area id
  43       */
  44      protected $userareaid = null;
  45  
  46      public function setUp(): void {
  47          $this->resetAfterTest(true);
  48          set_config('enableglobalsearch', true);
  49  
  50          $this->userareaid = \core_search\manager::generate_areaid('core_user', 'user');
  51  
  52          // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
  53          $search = \testable_core_search::instance();
  54      }
  55  
  56      /**
  57       * Indexing users contents.
  58       *
  59       * @return void
  60       */
  61      public function test_users_indexing() {
  62          global $SITE;
  63  
  64          // Returns the instance as long as the area is supported.
  65          $searcharea = \core_search\manager::get_search_area($this->userareaid);
  66          $this->assertInstanceOf('\core_user\search\user', $searcharea);
  67  
  68          $user1 = self::getDataGenerator()->create_user();
  69          $user2 = self::getDataGenerator()->create_user();
  70  
  71          // All records.
  72          // Recordset will produce 4 user records:
  73          // Guest User, Admin User and two above generated users.
  74          $recordset = $searcharea->get_recordset_by_timestamp(0);
  75          $this->assertTrue($recordset->valid());
  76          $nrecords = 0;
  77          foreach ($recordset as $record) {
  78              $this->assertInstanceOf('stdClass', $record);
  79              $doc = $searcharea->get_document($record);
  80              $this->assertInstanceOf('\core_search\document', $doc);
  81              $nrecords++;
  82          }
  83          // If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
  84          $recordset->close();
  85          $this->assertEquals(4, $nrecords);
  86  
  87          // The +2 is to prevent race conditions.
  88          $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
  89  
  90          // No new records.
  91          $this->assertFalse($recordset->valid());
  92          $recordset->close();
  93  
  94          // Context support; first, try an unsupported context type.
  95          $coursecontext = \context_course::instance($SITE->id);
  96          $this->assertNull($searcharea->get_document_recordset(0, $coursecontext));
  97  
  98          // Try a specific user, will only return 1 record (that user).
  99          $rs = $searcharea->get_document_recordset(0, \context_user::instance($user1->id));
 100          $this->assertEquals(1, iterator_count($rs));
 101          $rs->close();
 102      }
 103  
 104      /**
 105       * Document contents.
 106       *
 107       * @return void
 108       */
 109      public function test_users_document() {
 110  
 111          // Returns the instance as long as the area is supported.
 112          $searcharea = \core_search\manager::get_search_area($this->userareaid);
 113          $this->assertInstanceOf('\core_user\search\user', $searcharea);
 114  
 115          $user = self::getDataGenerator()->create_user();
 116  
 117          $doc = $searcharea->get_document($user);
 118          $this->assertInstanceOf('\core_search\document', $doc);
 119          $this->assertEquals($user->id, $doc->get('itemid'));
 120          $this->assertEquals($this->userareaid . '-' . $user->id, $doc->get('id'));
 121          $this->assertEquals(SITEID, $doc->get('courseid'));
 122          $this->assertFalse($doc->is_set('userid'));
 123          $this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
 124          $this->assertEquals(content_to_text(fullname($user), false), $searcharea->get_document_display_title($doc));
 125          $this->assertEquals(content_to_text($user->description, $user->descriptionformat), $doc->get('content'));
 126      }
 127  
 128      /**
 129       * Document accesses.
 130       *
 131       * @return void
 132       */
 133      public function test_users_access() {
 134          global $CFG;
 135  
 136          // Returns the instance as long as the area is supported.
 137          $searcharea = \core_search\manager::get_search_area($this->userareaid);
 138  
 139          $user1 = self::getDataGenerator()->create_user();
 140          $user2 = self::getDataGenerator()->create_user();
 141          $user3 = self::getDataGenerator()->create_user();
 142          $user4 = self::getDataGenerator()->create_user();
 143          $user5 = self::getDataGenerator()->create_user();
 144          $user5->id = 0; // Visitor (not guest).
 145  
 146          $deleteduser = self::getDataGenerator()->create_user(array('deleted' => 1));
 147          $unconfirmeduser = self::getDataGenerator()->create_user(array('confirmed' => 0));
 148          $suspendeduser = self::getDataGenerator()->create_user(array('suspended' => 1));
 149  
 150          $course1 = self::getDataGenerator()->create_course();
 151          $course2 = self::getDataGenerator()->create_course();
 152  
 153          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
 154          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
 155  
 156          $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
 157          $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
 158          $this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
 159          $this->getDataGenerator()->enrol_user($user3->id, $course2->id, 'student');
 160          $this->getDataGenerator()->enrol_user($user4->id, $course2->id, 'student');
 161          $this->getDataGenerator()->enrol_user($suspendeduser->id, $course1->id, 'student');
 162  
 163          $this->getDataGenerator()->create_group_member(array('userid' => $user2->id, 'groupid' => $group1->id));
 164          $this->getDataGenerator()->create_group_member(array('userid' => $user3->id, 'groupid' => $group1->id));
 165          $this->getDataGenerator()->create_group_member(array('userid' => $user4->id, 'groupid' => $group2->id));
 166  
 167          $this->setAdminUser();
 168          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user1->id));
 169          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 170          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user3->id));
 171          $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access($deleteduser->id));
 172          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($unconfirmeduser->id));
 173          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($suspendeduser->id));
 174          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access(2));
 175  
 176          $this->setUser($user1);
 177          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user1->id));
 178          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 179          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user3->id));
 180          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user4->id));
 181          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access(1));// Guest user can't be accessed.
 182          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access(2));// Admin user can't be accessed.
 183          $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
 184          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($unconfirmeduser->id));
 185          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($suspendeduser->id));
 186  
 187          $this->setUser($user2);
 188          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user1->id));
 189          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 190          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user3->id));
 191          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user4->id));
 192  
 193          $this->setUser($user3);
 194          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user1->id));
 195          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 196          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user3->id));
 197          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($suspendeduser->id));
 198  
 199          $this->setGuestUser();
 200          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user1->id));
 201          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user2->id));
 202          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user3->id));
 203  
 204          $CFG->forceloginforprofiles = 0;
 205          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user1->id));
 206          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 207          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user3->id));
 208  
 209          $this->setUser($user5);
 210          $CFG->forceloginforprofiles = 1;
 211          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user1->id));
 212          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user2->id));
 213          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($user3->id));
 214  
 215          $CFG->forceloginforprofiles = 0;
 216          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user1->id));
 217          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user2->id));
 218          $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($user3->id));
 219      }
 220  
 221      /**
 222       * Test document icon.
 223       */
 224      public function test_get_doc_icon() {
 225          $searcharea = \core_search\manager::get_search_area($this->userareaid);
 226          $user = self::getDataGenerator()->create_user();
 227          $doc = $searcharea->get_document($user);
 228  
 229          $result = $searcharea->get_doc_icon($doc);
 230  
 231          $this->assertEquals('i/user', $result->get_name());
 232          $this->assertEquals('moodle', $result->get_component());
 233      }
 234  
 235      /**
 236       * Test assigned search categories.
 237       */
 238      public function test_get_category_names() {
 239          $searcharea = \core_search\manager::get_search_area($this->userareaid);
 240  
 241          $expected = ['core-users'];
 242          $this->assertEquals($expected, $searcharea->get_category_names());
 243      }
 244  }