6d4e3711df5b5d856f16e59d7d42223e2ee3449b
[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 private static $templates = array(
73 array( 'prop' => 'templates', 'titles' => 'AQBT-All' ),
74 array( 'pages' => array(
75 '1' => array(
76 'pageid' => 1,
77 'ns' => 0,
78 'title' => 'AQBT-All',
79 'templates' => array(
80 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
81 ) ) ) ) );
82
83 private static $categories = array(
84 array( 'prop' => 'categories', 'titles' => 'AQBT-All' ),
85 array( 'pages' => array(
86 '1' => array(
87 'pageid' => 1,
88 'ns' => 0,
89 'title' => 'AQBT-All',
90 'categories' => array(
91 array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ),
92 ) ) ) ) );
93
94 private static $allpages = array(
95 array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ),
96 array( 'allpages' => array(
97 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
98 array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
99 array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ),
100 array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
101 ) ) );
102
103 private static $alllinks = array(
104 array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ),
105 array( 'alllinks' => array(
106 array( 'ns' => 0, 'title' => 'AQBT-All' ),
107 array( 'ns' => 0, 'title' => 'AQBT-Categories' ),
108 array( 'ns' => 0, 'title' => 'AQBT-Links' ),
109 array( 'ns' => 0, 'title' => 'AQBT-Templates' ),
110 ) ) );
111
112 private static $alltransclusions = array(
113 array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ),
114 array( 'alltransclusions' => array(
115 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
116 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
117 ) ) );
118
119 private static $allcategories = array(
120 array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ),
121 array( 'allcategories' => array(
122 array( '*' => 'AQBT-Cat' ),
123 ) ) );
124
125 private static $backlinks = array(
126 array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ),
127 array( 'backlinks' => array(
128 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
129 ) ) );
130
131 private static $embeddedin = array(
132 array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ),
133 array( 'embeddedin' => array(
134 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
135 array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
136 ) ) );
137
138 private static $categorymembers = array(
139 array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ),
140 array( 'categorymembers' => array(
141 array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
142 array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
143 ) ) );
144
145 private static $generatorAllpages = array(
146 array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ),
147 array( 'pages' => array(
148 '1' => array(
149 'pageid' => 1,
150 'ns' => 0,
151 'title' => 'AQBT-All' ),
152 '2' => array(
153 'pageid' => 2,
154 'ns' => 0,
155 'title' => 'AQBT-Categories' ),
156 '3' => array(
157 'pageid' => 3,
158 'ns' => 0,
159 'title' => 'AQBT-Links' ),
160 '4' => array(
161 'pageid' => 4,
162 'ns' => 0,
163 'title' => 'AQBT-Templates' ),
164 ) ) );
165
166 private static $generatorLinks = array(
167 array( 'generator' => 'links', 'titles' => 'AQBT-Links' ),
168 array( 'pages' => array(
169 '1' => array(
170 'pageid' => 1,
171 'ns' => 0,
172 'title' => 'AQBT-All' ),
173 '2' => array(
174 'pageid' => 2,
175 'ns' => 0,
176 'title' => 'AQBT-Categories' ),
177 '4' => array(
178 'pageid' => 4,
179 'ns' => 0,
180 'title' => 'AQBT-Templates' ),
181 ) ) );
182
183 private static $generatorLinksPropLinks = array(
184 array( 'prop' => 'links' ),
185 array( 'pages' => array(
186 '1' => array( 'links' => array(
187 array( 'ns' => 0, 'title' => 'AQBT-Links' ),
188 ) ) ) ) );
189
190 private static $generatorLinksPropTemplates = array(
191 array( 'prop' => 'templates' ),
192 array( 'pages' => array(
193 '1' => array( 'templates' => array(
194 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
195 '4' => array( 'templates' => array(
196 array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
197 ) ) );
198
199 /**
200 * Test basic props
201 */
202 public function testProps() {
203 $this->check( self::$links );
204 $this->check( self::$templates );
205 $this->check( self::$categories );
206 }
207
208 /**
209 * Test basic lists
210 */
211 public function testLists() {
212 $this->check( self::$allpages );
213 $this->check( self::$alllinks );
214 $this->check( self::$alltransclusions );
215 // This test is temporarily disabled until a sqlite bug is fixed
216 // $this->check( self::$allcategories );
217 $this->check( self::$backlinks );
218 $this->check( self::$embeddedin );
219 $this->check( self::$categorymembers );
220 }
221
222 /**
223 * Test basic lists
224 */
225 public function testAllTogether() {
226
227 // All props together
228 $this->check( $this->merge(
229 self::$links,
230 self::$templates,
231 self::$categories
232 ) );
233
234 // All lists together
235 $this->check( $this->merge(
236 self::$allpages,
237 self::$alllinks,
238 self::$alltransclusions,
239 // This test is temporarily disabled until a sqlite bug is fixed
240 // self::$allcategories,
241 self::$backlinks,
242 self::$embeddedin,
243 self::$categorymembers
244 ) );
245
246 // All props+lists together
247 $this->check( $this->merge(
248 self::$links,
249 self::$templates,
250 self::$categories,
251 self::$allpages,
252 self::$alllinks,
253 self::$alltransclusions,
254 // This test is temporarily disabled until a sqlite bug is fixed
255 // self::$allcategories,
256 self::$backlinks,
257 self::$embeddedin,
258 self::$categorymembers
259 ) );
260 }
261
262 /**
263 * Test basic lists
264 */
265 public function testGenerator() {
266 // generator=allpages
267 $this->check( self::$generatorAllpages );
268 // generator=allpages & list=allpages
269 $this->check( $this->merge(
270 self::$generatorAllpages,
271 self::$allpages ) );
272 // generator=links
273 $this->check( self::$generatorLinks );
274 // generator=links & prop=links
275 $this->check( $this->merge(
276 self::$generatorLinks,
277 self::$generatorLinksPropLinks ) );
278 // generator=links & prop=templates
279 $this->check( $this->merge(
280 self::$generatorLinks,
281 self::$generatorLinksPropTemplates ) );
282 // generator=links & prop=links|templates
283 $this->check( $this->merge(
284 self::$generatorLinks,
285 self::$generatorLinksPropLinks,
286 self::$generatorLinksPropTemplates ) );
287 // generator=links & prop=links|templates & list=allpages|...
288 $this->check( $this->merge(
289 self::$generatorLinks,
290 self::$generatorLinksPropLinks,
291 self::$generatorLinksPropTemplates,
292 self::$allpages,
293 self::$alllinks,
294 self::$alltransclusions,
295 // This test is temporarily disabled until a sqlite bug is fixed
296 // self::$allcategories,
297 self::$backlinks,
298 self::$embeddedin,
299 self::$categorymembers ) );
300 }
301
302 /**
303 * Recursively merges the expected values in the $item into the $all
304 */
305 private function mergeExpected( &$all, $item ) {
306 foreach ( $item as $k => $v ) {
307 if ( array_key_exists( $k, $all ) ) {
308 if ( is_array( $all[$k] ) ) {
309 $this->mergeExpected( $all[$k], $v );
310 } else {
311 $this->assertEquals( $all[$k], $v );
312 }
313 } else {
314 $all[$k] = $v;
315 }
316 }
317 }
318
319 /**
320 * Recursively compare arrays, ignoring mismatches in numeric key and pageids.
321 * @param $expected array expected values
322 * @param $result array returned values
323 */
324 private function assertQueryResults( $expected, $result ) {
325 reset( $expected );
326 reset( $result );
327 while ( true ) {
328 $e = each( $expected );
329 $r = each( $result );
330 // If either of the arrays is shorter, abort. If both are done, success.
331 $this->assertEquals( (bool)$e, (bool)$r );
332 if ( !$e ) {
333 break; // done
334 }
335 // continue only if keys are identical or both keys are numeric
336 $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) );
337 // don't compare pageids
338 if ( $e['key'] !== 'pageid' ) {
339 // If values are arrays, compare recursively, otherwise compare with ===
340 if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) {
341 $this->assertQueryResults( $e['value'], $r['value'] );
342 } else {
343 $this->assertEquals( $e['value'], $r['value'] );
344 }
345 }
346 }
347 }
348 }