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   * Sent message global search unit tests.
  19   *
  20   * @package     core
  21   * @copyright   2016 Devang Gaur
  22   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
  29  
  30  /**
  31   * Provides the unit tests for sent message global search.
  32   *
  33   * @package     core
  34   * @copyright   2016 Devang Gaur
  35   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class message_sent_search_testcase extends advanced_testcase {
  38  
  39      /**
  40       * @var string Area id
  41       */
  42      protected $messagesentareaid = null;
  43  
  44      /**
  45       * Setting up the test environment
  46       * @return void
  47       */
  48      public function setUp(): void {
  49          $this->resetAfterTest(true);
  50          set_config('enableglobalsearch', true);
  51  
  52          $this->messagesentareaid = \core_search\manager::generate_areaid('core_message', 'message_sent');
  53  
  54          // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
  55          $search = testable_core_search::instance();
  56      }
  57  
  58      /**
  59       * Indexing messages contents.
  60       *
  61       * @return void
  62       */
  63      public function test_message_sent_indexing() {
  64  
  65          // Returns the instance as long as the area is supported.
  66          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
  67          $this->assertInstanceOf('\core_message\search\message_sent', $searcharea);
  68  
  69          $user1 = self::getDataGenerator()->create_user();
  70          $user2 = self::getDataGenerator()->create_user();
  71  
  72          $this->preventResetByRollback();
  73          $sink = $this->redirectMessages();
  74  
  75          $message = new \core\message\message();
  76          $message->courseid = SITEID;
  77          $message->userfrom = $user1;
  78          $message->userto = $user2;
  79          $message->subject = "Test Subject";
  80          $message->smallmessage = "Test small messsage";
  81          $message->fullmessage = "Test full messsage";
  82          $message->fullmessageformat = 0;
  83          $message->fullmessagehtml = null;
  84          $message->notification = 0;
  85          $message->component = 'moodle';
  86          $message->name = "instantmessage";
  87  
  88          message_send($message);
  89  
  90          $messages = $sink->get_messages();
  91  
  92          $this->assertEquals(1, count($messages));
  93  
  94          // All records.
  95          $recordset = $searcharea->get_recordset_by_timestamp(0);
  96          $this->assertTrue($recordset->valid());
  97          $nrecords = 0;
  98          foreach ($recordset as $record) {
  99              $this->assertInstanceOf('stdClass', $record);
 100              $doc = $searcharea->get_document($record);
 101              $this->assertInstanceOf('\core_search\document', $doc);
 102              $nrecords++;
 103          }
 104          // If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
 105          $recordset->close();
 106          $this->assertEquals(1, $nrecords);
 107  
 108          // The +2 is to prevent race conditions.
 109          $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
 110  
 111          // No new records.
 112          $this->assertFalse($recordset->valid());
 113          $recordset->close();
 114      }
 115  
 116      /**
 117       * Indexing messages, with restricted contexts.
 118       */
 119      public function test_message_sent_indexing_contexts() {
 120          global $SITE;
 121  
 122          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 123  
 124          $user1 = self::getDataGenerator()->create_user();
 125          $user2 = self::getDataGenerator()->create_user();
 126  
 127          $this->preventResetByRollback();
 128          $sink = $this->redirectMessages();
 129  
 130          // Send first message.
 131          $message = new \core\message\message();
 132          $message->courseid = SITEID;
 133          $message->userfrom = $user1;
 134          $message->userto = $user2;
 135          $message->subject = 'Test1';
 136          $message->smallmessage = 'Test small messsage';
 137          $message->fullmessage = 'Test full messsage';
 138          $message->fullmessageformat = 0;
 139          $message->fullmessagehtml = null;
 140          $message->notification = 0;
 141          $message->component = 'moodle';
 142          $message->name = 'instantmessage';
 143          message_send($message);
 144  
 145          // Ensure that ordering by timestamp will return in consistent order.
 146          $this->waitForSecond();
 147  
 148          // Send second message in opposite direction.
 149          $message = new \core\message\message();
 150          $message->courseid = SITEID;
 151          $message->userfrom = $user2;
 152          $message->userto = $user1;
 153          $message->subject = 'Test2';
 154          $message->smallmessage = 'Test small messsage';
 155          $message->fullmessage = 'Test full messsage';
 156          $message->fullmessageformat = 0;
 157          $message->fullmessagehtml = null;
 158          $message->notification = 0;
 159          $message->component = 'moodle';
 160          $message->name = 'instantmessage';
 161          message_send($message);
 162  
 163          // Test function with null context and system context (same).
 164          $rs = $searcharea->get_document_recordset(0, null);
 165          $this->assertEquals(['Test1', 'Test2'], self::recordset_to_subjects($rs));
 166          $rs = $searcharea->get_document_recordset(0, context_system::instance());
 167          $this->assertEquals(['Test1', 'Test2'], self::recordset_to_subjects($rs));
 168  
 169          // Test with user context for each user.
 170          $rs = $searcharea->get_document_recordset(0, \context_user::instance($user1->id));
 171          $this->assertEquals(['Test1'], self::recordset_to_subjects($rs));
 172          $rs = $searcharea->get_document_recordset(0, \context_user::instance($user2->id));
 173          $this->assertEquals(['Test2'], self::recordset_to_subjects($rs));
 174  
 175          // Test with a course context (should return null).
 176          $this->assertNull($searcharea->get_document_recordset(0,
 177                  context_course::instance($SITE->id)));
 178      }
 179  
 180      /**
 181       * Utility function to convert recordset to array of message subjects for testing.
 182       *
 183       * @param moodle_recordset $rs Recordset to convert (and close)
 184       * @return array Array of IDs from records indexed by number (0, 1, 2, ...)
 185       */
 186      public static function recordset_to_subjects(moodle_recordset $rs) {
 187          $results = [];
 188          foreach ($rs as $rec) {
 189              $results[] = $rec->subject;
 190          }
 191          $rs->close();
 192          return $results;
 193      }
 194  
 195      /**
 196       * Document contents.
 197       *
 198       * @return void
 199       */
 200      public function test_message_sent_document() {
 201  
 202          // Returns the instance as long as the area is supported.
 203          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 204          $this->assertInstanceOf('\core_message\search\message_sent', $searcharea);
 205  
 206          $user1 = self::getDataGenerator()->create_user();
 207          $user2 = self::getDataGenerator()->create_user();
 208  
 209          $this->preventResetByRollback();
 210          $sink = $this->redirectMessages();
 211  
 212          $message = new \core\message\message();
 213          $message->courseid = SITEID;
 214          $message->userfrom = $user1;
 215          $message->userto = $user2;
 216          $message->subject = "Test Subject";
 217          $message->smallmessage = "Test small messsage";
 218          $message->fullmessage = "Test full messsage";
 219          $message->fullmessageformat = 0;
 220          $message->fullmessagehtml = null;
 221          $message->notification = 0;
 222          $message->component = "moodle";
 223          $message->name = "instantmessage";
 224  
 225          message_send($message);
 226  
 227          $messages = $sink->get_messages();
 228          $message = $messages[0];
 229  
 230          $doc = $searcharea->get_document($message);
 231          $this->assertInstanceOf('\core_search\document', $doc);
 232          $this->assertEquals($message->id, $doc->get('itemid'));
 233          $this->assertEquals($this->messagesentareaid . '-' . $message->id, $doc->get('id'));
 234          $this->assertEquals(SITEID, $doc->get('courseid'));
 235          $this->assertEquals($message->useridfrom, $doc->get('owneruserid'));
 236          $this->assertEquals($message->useridto, $doc->get('userid'));
 237          $this->assertEquals(content_to_text($message->subject, false), $doc->get('title'));
 238          $this->assertEquals(content_to_text($message->smallmessage, false), $doc->get('content'));
 239      }
 240  
 241      /**
 242       * Document accesses.
 243       *
 244       * @return void
 245       */
 246      public function test_message_sent_access() {
 247          global $CFG;
 248  
 249          // Returns the instance as long as the area is supported.
 250          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 251  
 252          $user1 = self::getDataGenerator()->create_user();
 253          $user2 = self::getDataGenerator()->create_user();
 254          $user3 = self::getDataGenerator()->create_user();
 255  
 256          $this->preventResetByRollback();
 257          $sink = $this->redirectMessages();
 258  
 259          $message = new \core\message\message();
 260          $message->courseid = SITEID;
 261          $message->userfrom = $user1;
 262          $message->userto = $user2;
 263          $message->subject = "Test Subject";
 264          $message->smallmessage = "Test small messsage";
 265          $message->fullmessage = "Test full messsage";
 266          $message->fullmessageformat = 0;
 267          $message->fullmessagehtml = null;
 268          $message->notification = 0;
 269          $message->component = "moodle";
 270          $message->name = "instantmessage";
 271  
 272          $messageid = message_send($message);
 273  
 274          $messages = $sink->get_messages();
 275          $message = $messages[0];
 276  
 277          $this->setUser($user1);
 278  
 279          if ($CFG->messaging) {
 280              $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($messageid));
 281          } else {
 282              $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($messageid));
 283          }
 284  
 285          $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
 286  
 287          \core_message\api::delete_message($user1->id, $message->id);
 288          $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access($messageid));
 289  
 290          $this->setUser($user2);
 291          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($messageid));
 292  
 293          $this->setUser($user3);
 294          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($messageid));
 295  
 296          $this->setGuestUser();
 297          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($messageid));
 298  
 299          $this->setAdminUser();
 300          $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($messageid));
 301  
 302          delete_user($user2);
 303  
 304          $this->setUser($user1);
 305          $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access($messageid));
 306  
 307      }
 308  
 309      /**
 310       * Test sent deleted user.
 311       * Tests the case where a sent message for a deleted user
 312       * is attempted to be added to the index.
 313       *
 314       * @return void
 315       */
 316      public function test_message_sent_deleted_user() {
 317  
 318          // Returns the instance as long as the area is supported.
 319          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 320          $this->assertInstanceOf('\core_message\search\message_sent', $searcharea);
 321  
 322          $user1 = self::getDataGenerator()->create_user();
 323          $user2 = self::getDataGenerator()->create_user();
 324  
 325          $this->preventResetByRollback();
 326          $sink = $this->redirectMessages();
 327  
 328          $message = new \core\message\message();
 329          $message->courseid = SITEID;
 330          $message->userfrom = $user1;
 331          $message->userto = $user2;
 332          $message->subject = "Test Subject";
 333          $message->smallmessage = "Test small messsage";
 334          $message->fullmessage = "Test full messsage";
 335          $message->fullmessageformat = 0;
 336          $message->fullmessagehtml = null;
 337          $message->notification = 0;
 338          $message->component = "moodle";
 339          $message->name = "instantmessage";
 340  
 341          message_send($message);
 342  
 343          $messages = $sink->get_messages();
 344          $message = $messages[0];
 345  
 346          // Delete user.
 347          delete_user($user1);
 348  
 349          $doc = $searcharea->get_document($message);
 350  
 351          $this->assertFalse($doc);
 352  
 353      }
 354  
 355      /**
 356       * Test document icon.
 357       */
 358      public function test_get_doc_icon() {
 359          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 360  
 361          $document = $this->getMockBuilder('\core_search\document')
 362              ->disableOriginalConstructor()
 363              ->getMock();
 364  
 365          $result = $searcharea->get_doc_icon($document);
 366  
 367          $this->assertEquals('t/message', $result->get_name());
 368          $this->assertEquals('moodle', $result->get_component());
 369      }
 370  
 371      /**
 372       * Test assigned search categories.
 373       */
 374      public function test_get_category_names() {
 375          $searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
 376  
 377          $expected = ['core-users'];
 378          $this->assertEquals($expected, $searcharea->get_category_names());
 379      }
 380  }