Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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 test for search indexing.
  19   *
  20   * @package block_html
  21   * @copyright 2017 The Open University
  22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace block_html;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Unit test for search indexing.
  31   *
  32   * @package block_html
  33   * @copyright 2017 The Open University
  34   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class search_content_testcase extends \advanced_testcase {
  37  
  38      /**
  39       * Creates an HTML block on a course.
  40       *
  41       * @param \stdClass $course Course object
  42       * @return \block_html Block instance object
  43       */
  44      protected function create_block($course) {
  45          $page = self::construct_page($course);
  46          $page->blocks->add_block_at_end_of_default_region('html');
  47  
  48          // Load the block.
  49          $page = self::construct_page($course);
  50          $page->blocks->load_blocks();
  51          $blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region());
  52          $block = end($blocks);
  53          return $block;
  54      }
  55  
  56      /**
  57       * Constructs a page object for the test course.
  58       *
  59       * @param \stdClass $course Moodle course object
  60       * @return \moodle_page Page object representing course view
  61       */
  62      protected static function construct_page($course) {
  63          $context = \context_course::instance($course->id);
  64          $page = new \moodle_page();
  65          $page->set_context($context);
  66          $page->set_course($course);
  67          $page->set_pagelayout('standard');
  68          $page->set_pagetype('course-view');
  69          $page->blocks->load_blocks();
  70          return $page;
  71      }
  72  
  73      /**
  74       * Tests all functionality in the search area.
  75       */
  76      public function test_search_area() {
  77          global $CFG, $USER, $DB;
  78          require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
  79  
  80          $this->resetAfterTest();
  81          $this->setAdminUser();
  82  
  83          // Create course and add HTML block.
  84          $generator = $this->getDataGenerator();
  85          $course = $generator->create_course();
  86          $before = time();
  87          $block = $this->create_block($course);
  88  
  89          // Change block settings to add some text and a file.
  90          $itemid = file_get_unused_draft_itemid();
  91          $fs = get_file_storage();
  92          $usercontext = \context_user::instance($USER->id);
  93          $fs->create_file_from_string(['component' => 'user', 'filearea' => 'draft',
  94                  'contextid' => $usercontext->id, 'itemid' => $itemid, 'filepath' => '/',
  95                  'filename' => 'file.txt'], 'File content');
  96          $data = (object)['title' => 'Block title', 'text' => ['text' => 'Block text',
  97                  'itemid' => $itemid, 'format' => FORMAT_HTML]];
  98          $block->instance_config_save($data);
  99          $after = time();
 100  
 101          // Set up fake search engine so we can create documents.
 102          \testable_core_search::instance();
 103  
 104          // Do indexing query.
 105          $area = new \block_html\search\content();
 106          $this->assertEquals('html', $area->get_block_name());
 107          $rs = $area->get_recordset_by_timestamp();
 108          $count = 0;
 109          foreach ($rs as $record) {
 110              $count++;
 111  
 112              $this->assertEquals($course->id, $record->courseid);
 113  
 114              // Check context is correct.
 115              $blockcontext = \context::instance_by_id($record->contextid);
 116              $this->assertInstanceOf('\context_block', $blockcontext);
 117              $coursecontext = $blockcontext->get_parent_context();
 118              $this->assertEquals($course->id, $coursecontext->instanceid);
 119  
 120              // Check created and modified times are correct.
 121              $this->assertTrue($record->timecreated >= $before && $record->timecreated <= $after);
 122              $this->assertTrue($record->timemodified >= $before && $record->timemodified <= $after);
 123  
 124              // Get config data.
 125              $data = unserialize(base64_decode($record->configdata));
 126              $this->assertEquals('Block title', $data->title);
 127              $this->assertEquals('Block text', $data->text);
 128              $this->assertEquals(FORMAT_HTML, $data->format);
 129  
 130              // Check the get_document function 'new' flag.
 131              $doc = $area->get_document($record, ['lastindexedtime' => 1]);
 132              $this->assertTrue($doc->get_is_new());
 133              $doc = $area->get_document($record, ['lastindexedtime' => time() + 1]);
 134              $this->assertFalse($doc->get_is_new());
 135  
 136              // Check the attach_files function results in correct list of associated files.
 137              $this->assertCount(0, $doc->get_files());
 138              $area->attach_files($doc);
 139              $files = $doc->get_files();
 140              $this->assertCount(2, $files);
 141              foreach ($files as $file) {
 142                  if ($file->is_directory()) {
 143                      continue;
 144                  }
 145                  $this->assertEquals('file.txt', $file->get_filename());
 146                  $this->assertEquals('File content', $file->get_content());
 147              }
 148  
 149              // Check the document fields are all as expected.
 150              $this->assertEquals('Block title', $doc->get('title'));
 151              $this->assertEquals('Block text', $doc->get('content'));
 152              $this->assertEquals($blockcontext->id, $doc->get('contextid'));
 153              $this->assertEquals(\core_search\manager::TYPE_TEXT, $doc->get('type'));
 154              $this->assertEquals($course->id, $doc->get('courseid'));
 155              $this->assertEquals($record->timemodified, $doc->get('modified'));
 156              $this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
 157  
 158              // Also check getting the doc url and context url.
 159              $url = new \moodle_url('/course/view.php', ['id' => $course->id], 'inst' . $record->id);
 160              $this->assertTrue($url->compare($area->get_doc_url($doc)));
 161              $this->assertTrue($url->compare($area->get_context_url($doc)));
 162          }
 163          $rs->close();
 164  
 165          // Should only be one HTML block systemwide.
 166          $this->assertEquals(1, $count);
 167  
 168          // If we run the query starting from 1 second after now, there should be no results.
 169          $rs = $area->get_recordset_by_timestamp($after + 1);
 170          $count = 0;
 171          foreach ($rs as $record) {
 172              $count++;
 173          }
 174          $rs->close();
 175          $this->assertEquals(0, $count);
 176  
 177          // Create another block, but this time leave it empty (no data set). Hack the time though.
 178          $block = $this->create_block($course);
 179          $DB->set_field('block_instances', 'timemodified',
 180                  $after + 10, ['id' => $block->instance->id]);
 181          $rs = $area->get_recordset_by_timestamp($after + 10);
 182          $count = 0;
 183          foreach ($rs as $record) {
 184              // Because there is no configdata we don't index it.
 185              $count++;
 186          }
 187          $rs->close();
 188          $this->assertEquals(0, $count);
 189      }
 190  }
 191