Merge branch 'MDL-67813-master-1' of git://github.com/mihailges/moodle
[moodle.git] / repository / contentbank / tests / search_test.php
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/>.
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  */
25 defined('MOODLE_INTERNAL') || die();
27 global $CFG;
29 require_once("$CFG->dirroot/repository/lib.php");
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 {
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();
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);
68         $this->assertEquals($expected, $actual, '', 0.0, 10, true);
69     }
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     }
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);
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);
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);
162         // Log in as admin.
163         $this->setUser($admin);
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->assertEquals($expected, $searchcontentnodes, '', 0.0, 10, true);
176     }
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);
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);
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');
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');
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->assertEquals($expected, $searchcontentnodes, '', 0.0, 10, true);
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->assertEquals($expected, $searchcontentnodes, '', 0.0, 10, true);
240     }