30ec6c3558c8c2413e4a018e721397c28e8fa00d
[lhc/web/wiklou.git] / tests / phpunit / includes / api / query / ApiQueryBasicTest.php
1 <?php
2 /**
3 *
4 *
5 * Created on Feb 6, 2013
6 *
7 * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 *
24 * @file
25 */
26
27 require_once( 'ApiQueryTestBase.php' );
28
29 /** These tests validate basic functionality of the api query module
30 *
31 * @group API
32 * @group Database
33 * @group medium
34 */
35 class ApiQueryBasicTest extends ApiQueryTestBase {
36 /**
37 * Create a set of pages. These must not change, otherwise the tests might give wrong results.
38 * @see MediaWikiTestCase::addDBData()
39 */
40 function addDBData() {
41 try {
42 if ( Title::newFromText( 'AQBT-All' )->exists() ) {
43 return;
44 }
45
46 // Ordering is important, as it will be returned in the same order as stored in the index
47 $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
48 $this->editPage( 'AQBT-Categories', '[[Category:AQBT-Cat]]' );
49 $this->editPage( 'AQBT-Links', '[[AQBT-All]] [[AQBT-Categories]] [[AQBT-Templates]]' );
50 $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
51 $this->editPage( 'AQBT-T', 'Content', '', NS_TEMPLATE );
52
53 // Refresh due to the bug with listing transclusions as links if they don't exist
54 $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
55 $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
56 } catch ( Exception $e ) {
57 $this->exceptionFromAddDBData = $e;
58 }
59 }
60
61 private static $links = array(
62 array( 'prop' => 'links', 'titles' => 'AQBT-All' ),
63 array( 'pages' => array(
64 '1' => array(
65 'pageid' => 1,
66 'ns' => 0,
67 'title' => 'AQBT-All',
68 'links' => array(
69 array( 'ns' => 0, 'title' => 'AQBT-Links' ),
70 )
71 )
72 ) )
73 );
74
75 private static $templates = array(
76 array( 'prop' => 'templates', 'titles' => 'AQBT-All' ),
77 array( 'pages' => array(
78 '1' => array(
79 'pageid' => 1,
80 'ns' => 0,
81 'title' => 'AQBT-All',
82 'templates' => array(
83 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
84 )
85 )
86 ) )
87 );
88
89 private static $categories = array(
90 array( 'prop' => 'categories', 'titles' => 'AQBT-All' ),
91 array( 'pages' => array(
92 '1' => array(
93 'pageid' => 1,
94 'ns' => 0,
95 'title' => 'AQBT-All',
96 'categories' => array(
97 array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ),
98 )
99 )
100 ) )
101 );
102
103 private static $allpages = array(
104 array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ),
105 array( 'allpages' => array(
106 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
107 array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
108 array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ),
109 array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
110 ) )
111 );
112
113 private static $alllinks = array(
114 array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ),
115 array( 'alllinks' => array(
116 array( 'ns' => 0, 'title' => 'AQBT-All' ),
117 array( 'ns' => 0, 'title' => 'AQBT-Categories' ),
118 array( 'ns' => 0, 'title' => 'AQBT-Links' ),
119 array( 'ns' => 0, 'title' => 'AQBT-Templates' ),
120 ) )
121 );
122
123 private static $alltransclusions = array(
124 array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ),
125 array( 'alltransclusions' => array(
126 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
127 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
128 ) )
129 );
130
131 private static $allcategories = array(
132 array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ),
133 array( 'allcategories' => array(
134 array( '*' => 'AQBT-Cat' ),
135 ) )
136 );
137
138 private static $backlinks = array(
139 array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ),
140 array( 'backlinks' => array(
141 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
142 ) )
143 );
144
145 private static $embeddedin = array(
146 array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ),
147 array( 'embeddedin' => array(
148 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
149 array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
150 ) )
151 );
152
153 private static $categorymembers = array(
154 array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ),
155 array( 'categorymembers' => array(
156 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
157 array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
158 ) )
159 );
160
161 private static $generatorAllpages = array(
162 array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ),
163 array( 'pages' => array(
164 '1' => array(
165 'pageid' => 1,
166 'ns' => 0,
167 'title' => 'AQBT-All' ),
168 '2' => array(
169 'pageid' => 2,
170 'ns' => 0,
171 'title' => 'AQBT-Categories' ),
172 '3' => array(
173 'pageid' => 3,
174 'ns' => 0,
175 'title' => 'AQBT-Links' ),
176 '4' => array(
177 'pageid' => 4,
178 'ns' => 0,
179 'title' => 'AQBT-Templates' ),
180 ) )
181 );
182
183 private static $generatorLinks = array(
184 array( 'generator' => 'links', 'titles' => 'AQBT-Links' ),
185 array( 'pages' => array(
186 '1' => array(
187 'pageid' => 1,
188 'ns' => 0,
189 'title' => 'AQBT-All' ),
190 '2' => array(
191 'pageid' => 2,
192 'ns' => 0,
193 'title' => 'AQBT-Categories' ),
194 '4' => array(
195 'pageid' => 4,
196 'ns' => 0,
197 'title' => 'AQBT-Templates' ),
198 ) )
199 );
200
201 private static $generatorLinksPropLinks = array(
202 array( 'prop' => 'links' ),
203 array( 'pages' => array(
204 '1' => array( 'links' => array(
205 array( 'ns' => 0, 'title' => 'AQBT-Links' ),
206 ) )
207 ) )
208 );
209
210 private static $generatorLinksPropTemplates = array(
211 array( 'prop' => 'templates' ),
212 array( 'pages' => array(
213 '1' => array( 'templates' => array(
214 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
215 '4' => array( 'templates' => array(
216 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
217 ) )
218 );
219
220 /**
221 * Test basic props
222 */
223 public function testProps() {
224 $this->check( self::$links );
225 $this->check( self::$templates );
226 $this->check( self::$categories );
227 }
228
229 /**
230 * Test basic lists
231 */
232 public function testLists() {
233 $this->check( self::$allpages );
234 $this->check( self::$alllinks );
235 $this->check( self::$alltransclusions );
236 // This test is temporarily disabled until a sqlite bug is fixed
237 // $this->check( self::$allcategories );
238 $this->check( self::$backlinks );
239 $this->check( self::$embeddedin );
240 $this->check( self::$categorymembers );
241 }
242
243 /**
244 * Test basic lists
245 */
246 public function testAllTogether() {
247
248 // All props together
249 $this->check( $this->merge(
250 self::$links,
251 self::$templates,
252 self::$categories
253 ) );
254
255 // All lists together
256 $this->check( $this->merge(
257 self::$allpages,
258 self::$alllinks,
259 self::$alltransclusions,
260 // This test is temporarily disabled until a sqlite bug is fixed
261 // self::$allcategories,
262 self::$backlinks,
263 self::$embeddedin,
264 self::$categorymembers
265 ) );
266
267 // All props+lists together
268 $this->check( $this->merge(
269 self::$links,
270 self::$templates,
271 self::$categories,
272 self::$allpages,
273 self::$alllinks,
274 self::$alltransclusions,
275 // This test is temporarily disabled until a sqlite bug is fixed
276 // self::$allcategories,
277 self::$backlinks,
278 self::$embeddedin,
279 self::$categorymembers
280 ) );
281 }
282
283 /**
284 * Test basic lists
285 */
286 public function testGenerator() {
287 // generator=allpages
288 $this->check( self::$generatorAllpages );
289 // generator=allpages & list=allpages
290 $this->check( $this->merge(
291 self::$generatorAllpages,
292 self::$allpages ) );
293 // generator=links
294 $this->check( self::$generatorLinks );
295 // generator=links & prop=links
296 $this->check( $this->merge(
297 self::$generatorLinks,
298 self::$generatorLinksPropLinks ) );
299 // generator=links & prop=templates
300 $this->check( $this->merge(
301 self::$generatorLinks,
302 self::$generatorLinksPropTemplates ) );
303 // generator=links & prop=links|templates
304 $this->check( $this->merge(
305 self::$generatorLinks,
306 self::$generatorLinksPropLinks,
307 self::$generatorLinksPropTemplates ) );
308 // generator=links & prop=links|templates & list=allpages|...
309 $this->check( $this->merge(
310 self::$generatorLinks,
311 self::$generatorLinksPropLinks,
312 self::$generatorLinksPropTemplates,
313 self::$allpages,
314 self::$alllinks,
315 self::$alltransclusions,
316 // This test is temporarily disabled until a sqlite bug is fixed
317 // self::$allcategories,
318 self::$backlinks,
319 self::$embeddedin,
320 self::$categorymembers ) );
321 }
322
323 /**
324 * Recursively merges the expected values in the $item into the $all
325 */
326 private function mergeExpected( &$all, $item ) {
327 foreach ( $item as $k => $v ) {
328 if ( array_key_exists( $k, $all ) ) {
329 if ( is_array( $all[$k] ) ) {
330 $this->mergeExpected( $all[$k], $v );
331 } else {
332 $this->assertEquals( $all[$k], $v );
333 }
334 } else {
335 $all[$k] = $v;
336 }
337 }
338 }
339
340 /**
341 * Recursively compare arrays, ignoring mismatches in numeric key and pageids.
342 * @param $expected array expected values
343 * @param $result array returned values
344 */
345 private function assertQueryResults( $expected, $result ) {
346 reset( $expected );
347 reset( $result );
348 while ( true ) {
349 $e = each( $expected );
350 $r = each( $result );
351 // If either of the arrays is shorter, abort. If both are done, success.
352 $this->assertEquals( (bool)$e, (bool)$r );
353 if ( !$e ) {
354 break; // done
355 }
356 // continue only if keys are identical or both keys are numeric
357 $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) );
358 // don't compare pageids
359 if ( $e['key'] !== 'pageid' ) {
360 // If values are arrays, compare recursively, otherwise compare with ===
361 if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) {
362 $this->assertQueryResults( $e['value'], $r['value'] );
363 } else {
364 $this->assertEquals( $e['value'], $r['value'] );
365 }
366 }
367 }
368 }
369 }