Merge "Revert "selenium: add new message banner test to user spec""
[lhc/web/wiklou.git] / tests / phpunit / includes / api / query / ApiQueryTestBase.php
1 <?php
2 /**
3 * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23 /** This class has some common functionality for testing query module
24 */
25 abstract class ApiQueryTestBase extends ApiTestCase {
26
27 const PARAM_ASSERT = <<<STR
28 Each parameter must be an array of two elements,
29 first - an array of params to the API call,
30 and the second array - expected results as returned by the API
31 STR;
32
33 /**
34 * Merges all requests parameter + expected values into one
35 * @param array $v,... List of arrays, each of which contains exactly two
36 * @return array
37 */
38 protected function merge( /*...*/ ) {
39 $request = [];
40 $expected = [];
41 foreach ( func_get_args() as $v ) {
42 list( $req, $exp ) = $this->validateRequestExpectedPair( $v );
43 $request = array_merge_recursive( $request, $req );
44 $this->mergeExpected( $expected, $exp );
45 }
46
47 return [ $request, $expected ];
48 }
49
50 /**
51 * Check that the parameter is a valid two element array,
52 * with the first element being API request and the second - expected result
53 * @param array $v
54 * @return array
55 */
56 private function validateRequestExpectedPair( $v ) {
57 $this->assertInternalType( 'array', $v, self::PARAM_ASSERT );
58 $this->assertEquals( 2, count( $v ), self::PARAM_ASSERT );
59 $this->assertArrayHasKey( 0, $v, self::PARAM_ASSERT );
60 $this->assertArrayHasKey( 1, $v, self::PARAM_ASSERT );
61 $this->assertInternalType( 'array', $v[0], self::PARAM_ASSERT );
62 $this->assertInternalType( 'array', $v[1], self::PARAM_ASSERT );
63
64 return $v;
65 }
66
67 /**
68 * Recursively merges the expected values in the $item into the $all
69 * @param array &$all
70 * @param array $item
71 */
72 private function mergeExpected( &$all, $item ) {
73 foreach ( $item as $k => $v ) {
74 if ( array_key_exists( $k, $all ) ) {
75 if ( is_array( $all[$k] ) ) {
76 $this->mergeExpected( $all[$k], $v );
77 } else {
78 $this->assertEquals( $all[$k], $v );
79 }
80 } else {
81 $all[$k] = $v;
82 }
83 }
84 }
85
86 /**
87 * Checks that the request's result matches the expected results.
88 * Assumes no rawcontinue and a complete batch.
89 * @param array $values Array is a two element array( request, expected_results )
90 * @param array $session
91 * @param bool $appendModule
92 * @param User $user
93 */
94 protected function check( $values, array $session = null,
95 $appendModule = false, User $user = null
96 ) {
97 list( $req, $exp ) = $this->validateRequestExpectedPair( $values );
98 if ( !array_key_exists( 'action', $req ) ) {
99 $req['action'] = 'query';
100 }
101 foreach ( $req as &$val ) {
102 if ( is_array( $val ) ) {
103 $val = implode( '|', array_unique( $val ) );
104 }
105 }
106 $result = $this->doApiRequest( $req, $session, $appendModule, $user );
107 $this->assertResult( [ 'batchcomplete' => true, 'query' => $exp ], $result[0], $req );
108 }
109
110 protected function assertResult( $exp, $result, $message = '' ) {
111 try {
112 $exp = self::sanitizeResultArray( $exp );
113 $result = self::sanitizeResultArray( $result );
114 $this->assertEquals( $exp, $result );
115 } catch ( PHPUnit_Framework_ExpectationFailedException $e ) {
116 if ( is_array( $message ) ) {
117 $message = http_build_query( $message );
118 }
119
120 // FIXME: once we migrate to phpunit 4.1+, hardcode ComparisonFailure exception use
121 $compEx = 'SebastianBergmann\Comparator\ComparisonFailure';
122 if ( !class_exists( $compEx ) ) {
123 $compEx = 'PHPUnit_Framework_ComparisonFailure';
124 }
125
126 throw new PHPUnit_Framework_ExpectationFailedException(
127 $e->getMessage() . "\nRequest: $message",
128 new $compEx(
129 $exp,
130 $result,
131 print_r( $exp, true ),
132 print_r( $result, true ),
133 false,
134 $e->getComparisonFailure()->getMessage() . "\nRequest: $message"
135 )
136 );
137 }
138 }
139
140 /**
141 * Recursively ksorts a result array and removes any 'pageid' keys.
142 * @param array $result
143 * @return array
144 */
145 private static function sanitizeResultArray( $result ) {
146 unset( $result['pageid'] );
147 foreach ( $result as $key => $value ) {
148 if ( is_array( $value ) ) {
149 $result[$key] = self::sanitizeResultArray( $value );
150 }
151 }
152
153 // Sort the result by keys, then take advantage of how array_merge will
154 // renumber numeric keys while leaving others alone.
155 ksort( $result );
156 return array_merge( $result );
157 }
158 }