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.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

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