MDL-53226 search_simpledb: Use databases full-text search capabilities
[moodle.git] / search / engine / simpledb / tests / engine_test.php
CommitLineData
2ee2f530
DM
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 * Simple db search engine tests.
19 *
20 * @package search_simpledb
21 * @category phpunit
22 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
30require_once($CFG->dirroot . '/search/tests/fixtures/mock_search_area.php');
31
32/**
33 * Simple search engine base unit tests.
34 *
35 * @package search_simpledb
36 * @category phpunit
37 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
40class search_simpledb_engine_testcase extends advanced_testcase {
41
42 /**
43 * @var \core_search::manager
44 */
45 protected $search = null;
46
47 public function setUp() {
48 $this->resetAfterTest();
49 set_config('enableglobalsearch', true);
50
51 // Inject search_simpledb engine into the testable core search as we need to add the mock
52 // search component to it.
53 $searchengine = new \search_simpledb\engine();
54 $this->search = testable_core_search::instance($searchengine);
55 $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
56 $this->search->add_search_area($areaid, new core_mocksearch\search\role_capabilities());
57 }
58
59 public function test_index() {
60 global $DB;
61
62 $noneditingteacherid = $DB->get_field('role', 'id', array('shortname' => 'teacher'));
63
64 // Data gets into the search engine.
65 $this->assertTrue($this->search->index());
66
67 // Not anymore as everything was already added.
68 sleep(1);
69 $this->assertFalse($this->search->index());
70
71 assign_capability('moodle/course:renameroles', CAP_ALLOW, $noneditingteacherid, context_system::instance()->id);
72 accesslib_clear_all_caches_for_unit_testing();
73
74 // Indexing again once there is new data.
75 $this->assertTrue($this->search->index());
76 }
77
78 /**
79 * Test search filters.
80 *
81 * @return void
82 */
83 public function test_search() {
84 global $USER, $DB;
85
86 $this->setAdminUser();
87
88 $noneditingteacherid = $DB->get_field('role', 'id', array('shortname' => 'teacher'));
89
90 $this->search->index();
91
92 // Check that docid - id is respected.
93 $rolecaps = $DB->get_records('role_capabilities', array('capability' => 'moodle/course:renameroles'));
94 $rolecap = reset($rolecaps);
95 $rolecap->timemodified = time();
96 $DB->update_record('role_capabilities', $rolecap);
97
98 $this->search->index();
99
100 $querydata = new stdClass();
101 $querydata->q = 'message';
102 $results = $this->search->search($querydata);
103 $this->assertCount(2, $results);
104
105 // Based on core_mocksearch\search\indexer.
106 $this->assertEquals($USER->id, $results[0]->get('userid'));
107 $this->assertEquals(\context_system::instance()->id, $results[0]->get('contextid'));
108
109 // Do a test to make sure we aren't searching non-query fields, like areaid.
110 $querydata->q = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
111 $this->assertCount(0, $this->search->search($querydata));
112 $querydata->q = 'message';
113
114 sleep(1);
115 $beforeadding = time();
116 sleep(1);
117 assign_capability('moodle/course:renameroles', CAP_ALLOW, $noneditingteacherid, context_system::instance()->id);
118 accesslib_clear_all_caches_for_unit_testing();
119 $this->search->index();
120
121 // Timestart.
122 $querydata->timestart = $beforeadding;
123 $this->assertCount(2, $this->search->search($querydata));
124
125 // Timeend.
126 unset($querydata->timestart);
127 $querydata->timeend = $beforeadding;
128 $this->assertCount(1, $this->search->search($querydata));
129
130 // Title.
131 unset($querydata->timeend);
132 $querydata->title = 'moodle/course:renameroles roleid 1';
133 $this->assertCount(1, $this->search->search($querydata));
134
135 // Course IDs.
136 unset($querydata->title);
137 $querydata->courseids = array(SITEID + 1);
138 $this->assertCount(0, $this->search->search($querydata));
139
140 $querydata->courseids = array(SITEID);
141 $this->assertCount(3, $this->search->search($querydata));
142
143 // Check that index contents get updated.
144 $DB->delete_records('role_capabilities', array('capability' => 'moodle/course:renameroles'));
145 $this->search->index(true);
146 unset($querydata->title);
147 $querydata->q = '*renameroles*';
148 $this->assertCount(0, $this->search->search($querydata));
149 }
150
151 public function test_delete() {
152 $this->search->index();
153
154 $querydata = new stdClass();
155 $querydata->q = 'message';
156
157 $this->assertCount(2, $this->search->search($querydata));
158
159 $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
160 $this->search->delete_index($areaid);
161 $this->assertCount(0, $this->search->search($querydata));
162 }
163
164 public function test_alloweduserid() {
165 $engine = $this->search->get_engine();
166 $area = new core_mocksearch\search\role_capabilities();
167
168 // Get the first record for the recordset.
169 $recordset = $area->get_recordset_by_timestamp();
170 foreach ($recordset as $r) {
171 $record = $r;
172 break;
173 }
174 $recordset->close();
175
176 // Get the doc and insert the default doc.
177 $doc = $area->get_document($record);
178 $engine->add_document($doc);
179
180 $users = array();
181 $users[] = $this->getDataGenerator()->create_user();
182 $users[] = $this->getDataGenerator()->create_user();
183 $users[] = $this->getDataGenerator()->create_user();
184
185 // Add a record that only user 100 can see.
186 $originalid = $doc->get('id');
187
188 // Now add a custom doc for each user.
189 foreach ($users as $user) {
190 $doc = $area->get_document($record);
191 $doc->set('id', $originalid.'-'.$user->id);
192 $doc->set('owneruserid', $user->id);
193 $engine->add_document($doc);
194 }
195
196 $engine->area_index_complete($area->get_area_id());
197
198 $querydata = new stdClass();
199 $querydata->q = 'message';
200 $querydata->title = $doc->get('title');
201
202 // We are going to go through each user and see if they get the original and the owned doc.
203 foreach ($users as $user) {
204 $this->setUser($user);
205
206 $results = $this->search->search($querydata);
207 $this->assertCount(2, $results);
208
209 $owned = 0;
210 $notowned = 0;
211
212 // We don't know what order we will get the results in, so we are doing this.
213 foreach ($results as $result) {
214 $owneruserid = $result->get('owneruserid');
215 if (empty($owneruserid)) {
216 $notowned++;
217 $this->assertEquals(0, $owneruserid);
218 $this->assertEquals($originalid, $result->get('id'));
219 } else {
220 $owned++;
221 $this->assertEquals($user->id, $owneruserid);
222 $this->assertEquals($originalid.'-'.$user->id, $result->get('id'));
223 }
224 }
225
226 $this->assertEquals(1, $owned);
227 $this->assertEquals(1, $notowned);
228 }
229
230 // Now test a user with no owned results.
231 $otheruser = $this->getDataGenerator()->create_user();
232 $this->setUser($otheruser);
233
234 $results = $this->search->search($querydata);
235 $this->assertCount(1, $results);
236
237 $this->assertEquals(0, $results[0]->get('owneruserid'));
238 $this->assertEquals($originalid, $results[0]->get('id'));
239 }
240
241 public function test_delete_by_id() {
242 // First get files in the index.
243 $this->search->index();
244 $engine = $this->search->get_engine();
245
246 $querydata = new stdClass();
247
248 // Then search to make sure they are there.
249 $querydata->q = 'moodle/course:renameroles';
250 $results = $this->search->search($querydata);
251 $this->assertCount(2, $results);
252
253 $first = reset($results);
254 $deleteid = $first->get('id');
255
256 $engine->delete_by_id($deleteid);
257
258 // Check that we don't get a result for it anymore.
259 $results = $this->search->search($querydata);
260 $this->assertCount(1, $results);
261 $result = reset($results);
262 $this->assertNotEquals($deleteid, $result->get('id'));
263 }
264}