API: Fixes for AuthManager
[mediawiki.git] / tests / phpunit / includes / PrefixSearchTest.php
blob0ec200c163f8680294056dd89329303cf0cf143f
1 <?php
2 /**
3 * @group Search
4 * @group Database
5 */
6 class PrefixSearchTest extends MediaWikiLangTestCase {
7 private $originalHandlers;
9 public function addDBDataOnce() {
10 if ( !$this->isWikitextNS( NS_MAIN ) ) {
11 // tests are skipped if NS_MAIN is not wikitext
12 return;
15 $this->insertPage( 'Sandbox' );
16 $this->insertPage( 'Bar' );
17 $this->insertPage( 'Example' );
18 $this->insertPage( 'Example Bar' );
19 $this->insertPage( 'Example Foo' );
20 $this->insertPage( 'Example Foo/Bar' );
21 $this->insertPage( 'Example/Baz' );
22 $this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
23 $this->insertPage( 'Redirect Test' );
24 $this->insertPage( 'Redirect Test Worse Result' );
25 $this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
26 $this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
27 $this->insertPage( 'Redirect Test2' );
28 $this->insertPage( 'Redirect Test2 Worse Result' );
30 $this->insertPage( 'Talk:Sandbox' );
31 $this->insertPage( 'Talk:Example' );
33 $this->insertPage( 'User:Example' );
36 protected function setUp() {
37 parent::setUp();
39 if ( !$this->isWikitextNS( NS_MAIN ) ) {
40 $this->markTestSkipped( 'Main namespace does not support wikitext.' );
43 // Avoid special pages from extensions interferring with the tests
44 $this->setMwGlobals( [
45 'wgSpecialPages' => [],
46 'wgHooks' => [],
47 ] );
49 $this->originalHandlers = TestingAccessWrapper::newFromClass( 'Hooks' )->handlers;
50 TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = [];
52 SpecialPageFactory::resetList();
55 public function tearDown() {
56 parent::tearDown();
58 TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = $this->originalHandlers;
60 SpecialPageFactory::resetList();
63 protected function searchProvision( array $results = null ) {
64 if ( $results === null ) {
65 $this->setMwGlobals( 'wgHooks', [] );
66 } else {
67 $this->setMwGlobals( 'wgHooks', [
68 'PrefixSearchBackend' => [
69 function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
70 $srchres = $results;
71 return false;
74 ] );
78 public static function provideSearch() {
79 return [
80 [ [
81 'Empty string',
82 'query' => '',
83 'results' => [],
84 ] ],
85 [ [
86 'Main namespace with title prefix',
87 'query' => 'Ex',
88 'results' => [
89 'Example',
90 'Example/Baz',
91 'Example Bar',
93 // Third result when testing offset
94 'offsetresult' => [
95 'Example Foo',
97 ] ],
98 [ [
99 'Talk namespace prefix',
100 'query' => 'Talk:',
101 'results' => [
102 'Talk:Example',
103 'Talk:Sandbox',
105 ] ],
107 'User namespace prefix',
108 'query' => 'User:',
109 'results' => [
110 'User:Example',
112 ] ],
114 'Special namespace prefix',
115 'query' => 'Special:',
116 'results' => [
117 'Special:ActiveUsers',
118 'Special:AllMessages',
119 'Special:AllMyFiles',
121 // Third result when testing offset
122 'offsetresult' => [
123 'Special:AllMyUploads',
125 ] ],
127 'Special namespace with prefix',
128 'query' => 'Special:Un',
129 'results' => [
130 'Special:Unblock',
131 'Special:UncategorizedCategories',
132 'Special:UncategorizedFiles',
134 // Third result when testing offset
135 'offsetresult' => [
136 'Special:UncategorizedImages',
138 ] ],
140 'Special page name',
141 'query' => 'Special:EditWatchlist',
142 'results' => [
143 'Special:EditWatchlist',
145 ] ],
147 'Special page subpages',
148 'query' => 'Special:EditWatchlist/',
149 'results' => [
150 'Special:EditWatchlist/clear',
151 'Special:EditWatchlist/raw',
153 ] ],
155 'Special page subpages with prefix',
156 'query' => 'Special:EditWatchlist/cl',
157 'results' => [
158 'Special:EditWatchlist/clear',
160 ] ],
165 * @dataProvider provideSearch
166 * @covers PrefixSearch::search
167 * @covers PrefixSearch::searchBackend
169 public function testSearch( array $case ) {
170 $this->searchProvision( null );
171 $searcher = new StringPrefixSearch;
172 $results = $searcher->search( $case['query'], 3 );
173 $this->assertEquals(
174 $case['results'],
175 $results,
176 $case[0]
181 * @dataProvider provideSearch
182 * @covers PrefixSearch::search
183 * @covers PrefixSearch::searchBackend
185 public function testSearchWithOffset( array $case ) {
186 $this->searchProvision( null );
187 $searcher = new StringPrefixSearch;
188 $results = $searcher->search( $case['query'], 3, [], 1 );
190 // We don't expect the first result when offsetting
191 array_shift( $case['results'] );
192 // And sometimes we expect a different last result
193 $expected = isset( $case['offsetresult'] ) ?
194 array_merge( $case['results'], $case['offsetresult'] ) :
195 $case['results'];
197 $this->assertEquals(
198 $expected,
199 $results,
200 $case[0]
204 public static function provideSearchBackend() {
205 return [
207 'Simple case',
208 'provision' => [
209 'Bar',
210 'Barcelona',
211 'Barbara',
213 'query' => 'Bar',
214 'results' => [
215 'Bar',
216 'Barcelona',
217 'Barbara',
219 ] ],
221 'Exact match not on top (bug 70958)',
222 'provision' => [
223 'Barcelona',
224 'Bar',
225 'Barbara',
227 'query' => 'Bar',
228 'results' => [
229 'Bar',
230 'Barcelona',
231 'Barbara',
233 ] ],
235 'Exact match missing (bug 70958)',
236 'provision' => [
237 'Barcelona',
238 'Barbara',
239 'Bart',
241 'query' => 'Bar',
242 'results' => [
243 'Bar',
244 'Barcelona',
245 'Barbara',
247 ] ],
249 'Exact match missing and not existing',
250 'provision' => [
251 'Exile',
252 'Exist',
253 'External',
255 'query' => 'Ex',
256 'results' => [
257 'Exile',
258 'Exist',
259 'External',
261 ] ],
263 "Exact match shouldn't override already found match if " .
264 "exact is redirect and found isn't",
265 'provision' => [
266 // Target of the exact match is low in the list
267 'Redirect Test Worse Result',
268 'Redirect Test',
270 'query' => 'redirect test',
271 'results' => [
272 // Redirect target is pulled up and exact match isn't added
273 'Redirect Test',
274 'Redirect Test Worse Result',
276 ] ],
278 "Exact match shouldn't override already found match if " .
279 "both exact match and found match are redirect",
280 'provision' => [
281 // Another redirect to the same target as the exact match
282 // is low in the list
283 'Redirect Test2 Worse Result',
284 'Redirect test2',
286 'query' => 'redirect TEST2',
287 'results' => [
288 // Found redirect is pulled to the top and exact match isn't
289 // added
290 'Redirect test2',
291 'Redirect Test2 Worse Result',
293 ] ],
295 "Exact match should override any already found matches that " .
296 "are redirects to it",
297 'provision' => [
298 // Another redirect to the same target as the exact match
299 // is low in the list
300 'Redirect Test Worse Result',
301 'Redirect test',
303 'query' => 'Redirect Test',
304 'results' => [
305 // Found redirect is pulled to the top and exact match isn't
306 // added
307 'Redirect Test',
308 'Redirect Test Worse Result',
310 ] ],
315 * @dataProvider provideSearchBackend
316 * @covers PrefixSearch::searchBackend
318 public function testSearchBackend( array $case ) {
319 $this->searchProvision( $case['provision'] );
320 $searcher = new StringPrefixSearch;
321 $results = $searcher->search( $case['query'], 3 );
322 $this->assertEquals(
323 $case['results'],
324 $results,
325 $case[0]