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