Merge "OutputPage: Don't get a ParserOptions for $wgUser before the end of Setup...
[lhc/web/wiklou.git] / tests / phpunit / includes / search / SearchEnginePrefixTest.php
1 <?php
2 /**
3 * @group Search
4 * @group Database
5 */
6 class SearchEnginePrefixTest extends MediaWikiLangTestCase {
7
8 /**
9 * @var SearchEngine
10 */
11 private $search;
12
13 public function addDBData() {
14 if ( !$this->isWikitextNS( NS_MAIN ) ) {
15 // tests are skipped if NS_MAIN is not wikitext
16 return;
17 }
18
19 $this->insertPage( 'Sandbox' );
20 $this->insertPage( 'Bar' );
21 $this->insertPage( 'Example' );
22 $this->insertPage( 'Example Bar' );
23 $this->insertPage( 'Example Foo' );
24 $this->insertPage( 'Example Foo/Bar' );
25 $this->insertPage( 'Example/Baz' );
26 $this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
27 $this->insertPage( 'Redirect Test' );
28 $this->insertPage( 'Redirect Test Worse Result' );
29 $this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
30 $this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
31 $this->insertPage( 'Redirect Test2' );
32 $this->insertPage( 'Redirect Test2 Worse Result' );
33
34 $this->insertPage( 'Talk:Sandbox' );
35 $this->insertPage( 'Talk:Example' );
36
37 $this->insertPage( 'User:Example' );
38 }
39
40 protected function setUp() {
41 parent::setUp();
42
43 if ( !$this->isWikitextNS( NS_MAIN ) ) {
44 $this->markTestSkipped( 'Main namespace does not support wikitext.' );
45 }
46
47 // Avoid special pages from extensions interferring with the tests
48 $this->setMwGlobals( 'wgSpecialPages', array() );
49 $this->search = SearchEngine::create();
50 $this->search->setNamespaces( array() );
51 }
52
53 protected function searchProvision( Array $results = null ) {
54 if ( $results === null ) {
55 $this->setMwGlobals( 'wgHooks', array() );
56 } else {
57 $this->setMwGlobals( 'wgHooks', array(
58 'PrefixSearchBackend' => array(
59 function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
60 $srchres = $results;
61 return false;
62 }
63 ),
64 ) );
65 }
66 }
67
68 public static function provideSearch() {
69 return array(
70 array( array(
71 'Empty string',
72 'query' => '',
73 'results' => array(),
74 ) ),
75 array( array(
76 'Main namespace with title prefix',
77 'query' => 'Ex',
78 'results' => array(
79 'Example',
80 'Example/Baz',
81 'Example Bar',
82 ),
83 // Third result when testing offset
84 'offsetresult' => array(
85 'Example Foo',
86 ),
87 ) ),
88 array( array(
89 'Talk namespace prefix',
90 'query' => 'Talk:',
91 'results' => array(
92 'Talk:Example',
93 'Talk:Sandbox',
94 ),
95 ) ),
96 array( array(
97 'User namespace prefix',
98 'query' => 'User:',
99 'results' => array(
100 'User:Example',
101 ),
102 ) ),
103 array( array(
104 'Special namespace prefix',
105 'query' => 'Special:',
106 'results' => array(
107 'Special:ActiveUsers',
108 'Special:AllMessages',
109 'Special:AllMyFiles',
110 ),
111 // Third result when testing offset
112 'offsetresult' => array(
113 'Special:AllMyUploads',
114 ),
115 ) ),
116 array( array(
117 'Special namespace with prefix',
118 'query' => 'Special:Un',
119 'results' => array(
120 'Special:Unblock',
121 'Special:UncategorizedCategories',
122 'Special:UncategorizedFiles',
123 ),
124 // Third result when testing offset
125 'offsetresult' => array(
126 'Special:UncategorizedImages',
127 ),
128 ) ),
129 array( array(
130 'Special page name',
131 'query' => 'Special:EditWatchlist',
132 'results' => array(
133 'Special:EditWatchlist',
134 ),
135 ) ),
136 array( array(
137 'Special page subpages',
138 'query' => 'Special:EditWatchlist/',
139 'results' => array(
140 'Special:EditWatchlist/clear',
141 'Special:EditWatchlist/raw',
142 ),
143 ) ),
144 array( array(
145 'Special page subpages with prefix',
146 'query' => 'Special:EditWatchlist/cl',
147 'results' => array(
148 'Special:EditWatchlist/clear',
149 ),
150 ) ),
151 );
152 }
153
154 /**
155 * @dataProvider provideSearch
156 * @covers SearchEngine::defaultPrefixSearch
157 */
158 public function testSearch( Array $case ) {
159 $this->search->setLimitOffset( 3 );
160 $results = $this->search->defaultPrefixSearch( $case['query'] );
161 $results = array_map( function( Title $t ) {
162 return $t->getPrefixedText();
163 }, $results );
164 $this->assertEquals(
165 $case['results'],
166 $results,
167 $case[0]
168 );
169 }
170
171 /**
172 * @dataProvider provideSearch
173 * @covers SearchEngine::defaultPrefixSearch
174 */
175 public function testSearchWithOffset( Array $case ) {
176 $this->search->setLimitOffset( 3, 1 );
177 $results = $this->search->defaultPrefixSearch( $case['query'] );
178 $results = array_map( function( Title $t ) {
179 return $t->getPrefixedText();
180 }, $results );
181
182 // We don't expect the first result when offsetting
183 array_shift( $case['results'] );
184 // And sometimes we expect a different last result
185 $expected = isset( $case['offsetresult'] ) ?
186 array_merge( $case['results'], $case['offsetresult'] ) :
187 $case['results'];
188
189 $this->assertEquals(
190 $expected,
191 $results,
192 $case[0]
193 );
194 }
195
196 public static function provideSearchBackend() {
197 return array(
198 array( array(
199 'Simple case',
200 'provision' => array(
201 'Bar',
202 'Barcelona',
203 'Barbara',
204 ),
205 'query' => 'Bar',
206 'results' => array(
207 'Bar',
208 'Barcelona',
209 'Barbara',
210 ),
211 ) ),
212 array( array(
213 'Exact match not on top (bug 70958)',
214 'provision' => array(
215 'Barcelona',
216 'Bar',
217 'Barbara',
218 ),
219 'query' => 'Bar',
220 'results' => array(
221 'Bar',
222 'Barcelona',
223 'Barbara',
224 ),
225 ) ),
226 array( array(
227 'Exact match missing (bug 70958)',
228 'provision' => array(
229 'Barcelona',
230 'Barbara',
231 'Bart',
232 ),
233 'query' => 'Bar',
234 'results' => array(
235 'Bar',
236 'Barcelona',
237 'Barbara',
238 ),
239 ) ),
240 array( array(
241 'Exact match missing and not existing',
242 'provision' => array(
243 'Exile',
244 'Exist',
245 'External',
246 ),
247 'query' => 'Ex',
248 'results' => array(
249 'Exile',
250 'Exist',
251 'External',
252 ),
253 ) ),
254 array( array(
255 "Exact match shouldn't override already found match if " .
256 "exact is redirect and found isn't",
257 'provision' => array(
258 // Target of the exact match is low in the list
259 'Redirect Test Worse Result',
260 'Redirect Test',
261 ),
262 'query' => 'redirect test',
263 'results' => array(
264 // Redirect target is pulled up and exact match isn't added
265 'Redirect Test',
266 'Redirect Test Worse Result',
267 ),
268 ) ),
269 array( array(
270 "Exact match shouldn't override already found match if " .
271 "both exact match and found match are redirect",
272 'provision' => array(
273 // Another redirect to the same target as the exact match
274 // is low in the list
275 'Redirect Test2 Worse Result',
276 'Redirect test2',
277 ),
278 'query' => 'redirect TEST2',
279 'results' => array(
280 // Found redirect is pulled to the top and exact match isn't
281 // added
282 'Redirect test2',
283 'Redirect Test2 Worse Result',
284 ),
285 ) ),
286 array( array(
287 "Exact match should override any already found matches that " .
288 "are redirects to it",
289 'provision' => array(
290 // Another redirect to the same target as the exact match
291 // is low in the list
292 'Redirect Test Worse Result',
293 'Redirect test',
294 ),
295 'query' => 'Redirect Test',
296 'results' => array(
297 // Found redirect is pulled to the top and exact match isn't
298 // added
299 'Redirect Test',
300 'Redirect Test Worse Result',
301 'Redirect test',
302 ),
303 ) ),
304 );
305 }
306
307 /**
308 * @dataProvider provideSearchBackend
309 * @covers PrefixSearch::searchBackend
310 */
311 public function testSearchBackend( Array $case ) {
312 $search = $stub = $this->getMockBuilder( 'SearchEngine' )
313 ->setMethods( array( 'completionSearchBackend' ) )->getMock();
314
315 $return = SearchSuggestionSet::fromStrings( $case['provision'] );
316
317 $search->expects( $this->any() )
318 ->method( 'completionSearchBackend' )
319 ->will( $this->returnValue( $return ) );
320
321 $search->setLimitOffset( 3 );
322 $results = $search->completionSearch( $case['query'] );
323
324 $results = $results->map( function( SearchSuggestion $s ) {
325 return $s->getText();
326 } );
327
328 $this->assertEquals(
329 $case['results'],
330 $results,
331 $case[0]
332 );
333 }
334 }