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 311 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  /**
  18   * Content bank repository search unit tests.
  19   *
  20   * @package    repository_contentbank
  21   * @copyright  2020 Mihail Geshoski <mihail@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace repository_contentbank\search;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  
  31  require_once("$CFG->dirroot/repository/lib.php");
  32  
  33  /**
  34   * Tests for the content bank search class.
  35   *
  36   * @package    repository_contentbank
  37   * @copyright  2020 Mihail Geshoski <mihail@moodle.com>
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class search_test extends \advanced_testcase {
  41  
  42      /**
  43       * Test get_search_contents() by searching through some existing content using different search terms.
  44       *
  45       * @dataProvider get_search_contents_provider
  46       * @param array $contentnames The array containing the names of the content that needs to be generated
  47       * @param string $search The search string
  48       * @param array $expected The array containing the expected content names that should be returned by the search
  49       */
  50      public function test_get_search_contents(array $contentnames, string $search, array $expected) {
  51          $this->resetAfterTest();
  52  
  53          $admin = get_admin();
  54          $systemcontext = \context_system::instance();
  55          // Add some content to the content bank.
  56          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
  57          foreach ($contentnames as $contentname) {
  58              $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
  59                  $systemcontext, true, 'file.h5p', $contentname);
  60          }
  61          // Log in as admin.
  62          $this->setUser($admin);
  63          // Search for content bank content items which have the search pattern within the name.
  64          $searchcontentnodes = \repository_contentbank\contentbank_search::get_search_contents($search);
  65          // Get the content name of the each content returned after performing the search.
  66          $actual = array_map(function($searchcontentnode) {
  67              return $searchcontentnode['shorttitle'];
  68          }, $searchcontentnodes);
  69  
  70          $this->assertEqualsCanonicalizing($expected, $actual);
  71      }
  72  
  73      /**
  74       * Data provider for test_get_search_contents().
  75       *
  76       * @return array
  77       */
  78      public function get_search_contents_provider(): array {
  79          return [
  80              'Search for existing pattern found within the name of content items' => [
  81                  [
  82                      'systemcontentfile1',
  83                      'systemcontentfile2',
  84                      'somesystemfile'
  85                  ],
  86                  'content',
  87                  [
  88                      'systemcontentfile1',
  89                      'systemcontentfile2'
  90                  ]
  91              ],
  92              'Search for existing pattern found at the beginning of the name of content items' => [
  93                  [
  94                      'systemcontentfile1',
  95                      'systemcontentfile2',
  96                      'somesystemfile'
  97                  ],
  98                  'some',
  99                  [
 100                      'somesystemfile',
 101                  ]
 102              ],
 103              'Search for existing pattern found at the end of the name of content items' => [
 104                  [
 105                      'systemcontentfile1',
 106                      'systemcontentfile2',
 107                      'somesystemfile'
 108                  ],
 109                  'file2',
 110                  [
 111                      'systemcontentfile2',
 112                  ]
 113              ],
 114              'Search for a pattern which does not exist within the name of any content item' => [
 115                  [
 116                      'systemcontentfile1',
 117                      'somesystemfile'
 118                  ],
 119                  'somefile',
 120                  []
 121              ],
 122              'Case-insensitive search for a pattern which exists within the name of content items' => [
 123                  [
 124                      'systemcontentfile1',
 125                      'systemcontentfile2',
 126                      'somesystemfile'
 127                  ],
 128                  'CONTENT',
 129                  [
 130                      'systemcontentfile1',
 131                      'systemcontentfile2'
 132                  ]
 133              ]
 134          ];
 135      }
 136  
 137      /**
 138       * Test get_search_contents() by searching for content with users that have capability to access/view
 139       * all existing content bank content. By default, admins, managers should be able to view every existing content
 140       * that matches the search criteria.
 141       */
 142      public function test_get_search_contents_user_can_access_all_content() {
 143          $this->resetAfterTest(true);
 144  
 145          // Create a course in default category by default.
 146          $course = $this->getDataGenerator()->create_course();
 147          $coursecontext = \context_course::instance($course->id);
 148          // Create a course category without a course.
 149          $category = $this->getDataGenerator()->create_category();
 150          $categorycontext = \context_coursecat::instance($category->id);
 151  
 152          $admin = get_admin();
 153          // Add some content to the content bank in different contexts.
 154          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
 155          // Add a content bank file in the category context.
 156          $categorycontents = $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
 157              $categorycontext, true, 'file.h5p', 'categorycontentfile');
 158          $categorycontent = reset($categorycontents);
 159          // Add a content bank file in the course context.
 160          $coursecontents = $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
 161              $coursecontext, true, 'file.h5p', 'coursecontentfile');
 162          $coursecontent = reset($coursecontents);
 163  
 164          // Log in as admin.
 165          $this->setUser($admin);
 166  
 167          // Search for content bank content items which have the pattern 'contentfile' within the name.
 168          $search = 'contentfile';
 169          $searchcontentnodes = \repository_contentbank\contentbank_search::get_search_contents($search);
 170          // All content files which name matches the search criteria should be available to the admin user.
 171          // The search should return 2 file nodes.
 172          $this->assertCount(2, $searchcontentnodes);
 173          $expected = [
 174              \repository_contentbank\helper::create_contentbank_content_node($categorycontent),
 175              \repository_contentbank\helper::create_contentbank_content_node($coursecontent),
 176          ];
 177          $this->assertEqualsCanonicalizing($expected, $searchcontentnodes);
 178      }
 179  
 180      /**
 181       * Test get_search_contents() by searching for content with users that have capability to access/view only
 182       * certain existing content bank content. By default, editing teachers should be able to view content that matches
 183       * the search criteria AND is in the courses they are enrolled, course categories of the enrolled courses
 184       * and system content. Other authenticated users should be able to access only the system content.
 185       */
 186      public function test_get_search_contents_user_can_access_certain_content() {
 187          global $CFG;
 188  
 189          $this->resetAfterTest(true);
 190  
 191          $systemcontext = \context_system::instance();
 192          // Create course1.
 193          $course1 = $this->getDataGenerator()->create_course();
 194          $course1context = \context_course::instance($course1->id);
 195          // Create course2.
 196          $course2 = $this->getDataGenerator()->create_course();
 197          $course2context = \context_course::instance($course2->id);
 198  
 199          $admin = get_admin();
 200          // Create and enrol an editing teacher in course1.
 201          $editingteacher = $this->getDataGenerator()->create_and_enrol($course1, 'editingteacher');
 202          // Create and enrol a teacher in course2.
 203          $teacher = $this->getDataGenerator()->create_and_enrol($course2, 'teacher');
 204  
 205          // Add some content to the content bank in different contexts.
 206          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
 207          // Add a content bank file in the system context.
 208          $filepath = $CFG->dirroot . '/h5p/tests/fixtures/ipsums.h5p';
 209          $systemcontents = $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
 210              $systemcontext, true, $filepath, 'systemcontentfile');
 211          $systemcontent = reset($systemcontents);
 212          // Add a content bank file in the course1 context.
 213          $course1contents = $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
 214              $course1context, true, $filepath, 'coursecontentfile1');
 215          $course1content = reset($course1contents);
 216          // Add a content bank file in the course2 context.
 217          $generator->generate_contentbank_data('contenttype_h5p', 1, $admin->id,
 218              $course2context, true, $filepath, 'coursecontentfile2');
 219  
 220          // Log in as an editing teacher.
 221          $this->setUser($editingteacher);
 222          // Search for content bank content items which have the pattern 'contentfile' within the name.
 223          $search = 'contentfile';
 224          $searchcontentnodes = \repository_contentbank\contentbank_search::get_search_contents($search);
 225          // The search should return 2 file nodes. The editing teacher does not have access to the content of course2
 226          // and therefore, the course2 content should be skipped.
 227          $this->assertCount(2, $searchcontentnodes);
 228          $expected = [
 229              \repository_contentbank\helper::create_contentbank_content_node($systemcontent),
 230              \repository_contentbank\helper::create_contentbank_content_node($course1content),
 231          ];
 232          $this->assertEqualsCanonicalizing($expected, $searchcontentnodes);
 233  
 234          // Log in as a teacher.
 235          $this->setUser($teacher);
 236          // Search for content bank content items which have the pattern 'contentfile' within the name.
 237          $search = 'contentfile';
 238          $searchcontentnodes = \repository_contentbank\contentbank_search::get_search_contents($search);
 239          // The search should return 1 file node. The teacher should only be able to view system content.
 240          $this->assertCount(1, $searchcontentnodes);
 241          $expected = [
 242              \repository_contentbank\helper::create_contentbank_content_node($systemcontent),
 243          ];
 244          $this->assertEqualsCanonicalizing($expected, $searchcontentnodes);
 245      }
 246  }