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