MediaWiki
REL1_22
|
00001 <?php 00002 00008 class ApiOptionsTest extends MediaWikiLangTestCase { 00009 00010 private $mTested, $mUserMock, $mContext, $mSession; 00011 00012 private $mOldGetPreferencesHooks = false; 00013 00014 private static $Success = array( 'options' => 'success' ); 00015 00016 protected function setUp() { 00017 parent::setUp(); 00018 00019 $this->mUserMock = $this->getMockBuilder( 'User' ) 00020 ->disableOriginalConstructor() 00021 ->getMock(); 00022 00023 // Set up groups and rights 00024 $this->mUserMock->expects( $this->any() ) 00025 ->method( 'getEffectiveGroups' )->will( $this->returnValue( array( '*', 'user' ) ) ); 00026 $this->mUserMock->expects( $this->any() ) 00027 ->method( 'isAllowed' )->will( $this->returnValue( true ) ); 00028 00029 // Set up callback for User::getOptionKinds 00030 $this->mUserMock->expects( $this->any() ) 00031 ->method( 'getOptionKinds' )->will( $this->returnCallback( array( $this, 'getOptionKinds' ) ) ); 00032 00033 // Create a new context 00034 $this->mContext = new DerivativeContext( new RequestContext() ); 00035 $this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) ); 00036 $this->mContext->setUser( $this->mUserMock ); 00037 00038 $main = new ApiMain( $this->mContext ); 00039 00040 // Empty session 00041 $this->mSession = array(); 00042 00043 $this->mTested = new ApiOptions( $main, 'options' ); 00044 00045 global $wgHooks; 00046 if ( !isset( $wgHooks['GetPreferences'] ) ) { 00047 $wgHooks['GetPreferences'] = array(); 00048 } 00049 $this->mOldGetPreferencesHooks = $wgHooks['GetPreferences']; 00050 $wgHooks['GetPreferences'][] = array( $this, 'hookGetPreferences' ); 00051 } 00052 00053 protected function tearDown() { 00054 global $wgHooks; 00055 00056 if ( $this->mOldGetPreferencesHooks !== false ) { 00057 $wgHooks['GetPreferences'] = $this->mOldGetPreferencesHooks; 00058 $this->mOldGetPreferencesHooks = false; 00059 } 00060 00061 parent::tearDown(); 00062 } 00063 00064 public function hookGetPreferences( $user, &$preferences ) { 00065 $preferences = array(); 00066 00067 foreach ( array( 'name', 'willBeNull', 'willBeEmpty', 'willBeHappy' ) as $k ) { 00068 $preferences[$k] = array( 00069 'type' => 'text', 00070 'section' => 'test', 00071 'label' => ' ', 00072 ); 00073 } 00074 00075 $preferences['testmultiselect'] = array( 00076 'type' => 'multiselect', 00077 'options' => array( 00078 'Test' => array( 00079 '<span dir="auto">Some HTML here for option 1</span>' => 'opt1', 00080 '<span dir="auto">Some HTML here for option 2</span>' => 'opt2', 00081 '<span dir="auto">Some HTML here for option 3</span>' => 'opt3', 00082 '<span dir="auto">Some HTML here for option 4</span>' => 'opt4', 00083 ), 00084 ), 00085 'section' => 'test', 00086 'label' => ' ', 00087 'prefix' => 'testmultiselect-', 00088 'default' => array(), 00089 ); 00090 00091 return true; 00092 } 00093 00094 public function getOptionKinds( IContextSource $context, $options = null ) { 00095 // Match with above. 00096 $kinds = array( 00097 'name' => 'registered', 00098 'willBeNull' => 'registered', 00099 'willBeEmpty' => 'registered', 00100 'willBeHappy' => 'registered', 00101 'testmultiselect-opt1' => 'registered-multiselect', 00102 'testmultiselect-opt2' => 'registered-multiselect', 00103 'testmultiselect-opt3' => 'registered-multiselect', 00104 'testmultiselect-opt4' => 'registered-multiselect', 00105 ); 00106 00107 if ( $options === null ) { 00108 return $kinds; 00109 } 00110 00111 $mapping = array(); 00112 foreach ( $options as $key => $value ) { 00113 if ( isset( $kinds[$key] ) ) { 00114 $mapping[$key] = $kinds[$key]; 00115 } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) { 00116 $mapping[$key] = 'userjs'; 00117 } else { 00118 $mapping[$key] = 'unused'; 00119 } 00120 } 00121 00122 return $mapping; 00123 } 00124 00125 private function getSampleRequest( $custom = array() ) { 00126 $request = array( 00127 'token' => '123ABC', 00128 'change' => null, 00129 'optionname' => null, 00130 'optionvalue' => null, 00131 ); 00132 00133 return array_merge( $request, $custom ); 00134 } 00135 00136 private function executeQuery( $request ) { 00137 $this->mContext->setRequest( new FauxRequest( $request, true, $this->mSession ) ); 00138 $this->mTested->execute(); 00139 00140 return $this->mTested->getResult()->getData(); 00141 } 00142 00146 public function testNoToken() { 00147 $request = $this->getSampleRequest( array( 'token' => null ) ); 00148 00149 $this->executeQuery( $request ); 00150 } 00151 00152 public function testAnon() { 00153 $this->mUserMock->expects( $this->once() ) 00154 ->method( 'isAnon' ) 00155 ->will( $this->returnValue( true ) ); 00156 00157 try { 00158 $request = $this->getSampleRequest(); 00159 00160 $this->executeQuery( $request ); 00161 } catch ( UsageException $e ) { 00162 $this->assertEquals( 'notloggedin', $e->getCodeString() ); 00163 $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); 00164 00165 return; 00166 } 00167 $this->fail( "UsageException was not thrown" ); 00168 } 00169 00170 public function testNoOptionname() { 00171 try { 00172 $request = $this->getSampleRequest( array( 'optionvalue' => '1' ) ); 00173 00174 $this->executeQuery( $request ); 00175 } catch ( UsageException $e ) { 00176 $this->assertEquals( 'nooptionname', $e->getCodeString() ); 00177 $this->assertEquals( 'The optionname parameter must be set', $e->getMessage() ); 00178 00179 return; 00180 } 00181 $this->fail( "UsageException was not thrown" ); 00182 } 00183 00184 public function testNoChanges() { 00185 $this->mUserMock->expects( $this->never() ) 00186 ->method( 'resetOptions' ); 00187 00188 $this->mUserMock->expects( $this->never() ) 00189 ->method( 'setOption' ); 00190 00191 $this->mUserMock->expects( $this->never() ) 00192 ->method( 'saveSettings' ); 00193 00194 try { 00195 $request = $this->getSampleRequest(); 00196 00197 $this->executeQuery( $request ); 00198 } catch ( UsageException $e ) { 00199 $this->assertEquals( 'nochanges', $e->getCodeString() ); 00200 $this->assertEquals( 'No changes were requested', $e->getMessage() ); 00201 00202 return; 00203 } 00204 $this->fail( "UsageException was not thrown" ); 00205 } 00206 00207 public function testReset() { 00208 $this->mUserMock->expects( $this->once() ) 00209 ->method( 'resetOptions' ) 00210 ->with( $this->equalTo( array( 'all' ) ) ); 00211 00212 $this->mUserMock->expects( $this->never() ) 00213 ->method( 'setOption' ); 00214 00215 $this->mUserMock->expects( $this->once() ) 00216 ->method( 'saveSettings' ); 00217 00218 $request = $this->getSampleRequest( array( 'reset' => '' ) ); 00219 00220 $response = $this->executeQuery( $request ); 00221 00222 $this->assertEquals( self::$Success, $response ); 00223 } 00224 00225 public function testResetKinds() { 00226 $this->mUserMock->expects( $this->once() ) 00227 ->method( 'resetOptions' ) 00228 ->with( $this->equalTo( array( 'registered' ) ) ); 00229 00230 $this->mUserMock->expects( $this->never() ) 00231 ->method( 'setOption' ); 00232 00233 $this->mUserMock->expects( $this->once() ) 00234 ->method( 'saveSettings' ); 00235 00236 $request = $this->getSampleRequest( array( 'reset' => '', 'resetkinds' => 'registered' ) ); 00237 00238 $response = $this->executeQuery( $request ); 00239 00240 $this->assertEquals( self::$Success, $response ); 00241 } 00242 00243 public function testOptionWithValue() { 00244 $this->mUserMock->expects( $this->never() ) 00245 ->method( 'resetOptions' ); 00246 00247 $this->mUserMock->expects( $this->once() ) 00248 ->method( 'setOption' ) 00249 ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); 00250 00251 $this->mUserMock->expects( $this->once() ) 00252 ->method( 'saveSettings' ); 00253 00254 $request = $this->getSampleRequest( array( 'optionname' => 'name', 'optionvalue' => 'value' ) ); 00255 00256 $response = $this->executeQuery( $request ); 00257 00258 $this->assertEquals( self::$Success, $response ); 00259 } 00260 00261 public function testOptionResetValue() { 00262 $this->mUserMock->expects( $this->never() ) 00263 ->method( 'resetOptions' ); 00264 00265 $this->mUserMock->expects( $this->once() ) 00266 ->method( 'setOption' ) 00267 ->with( $this->equalTo( 'name' ), $this->identicalTo( null ) ); 00268 00269 $this->mUserMock->expects( $this->once() ) 00270 ->method( 'saveSettings' ); 00271 00272 $request = $this->getSampleRequest( array( 'optionname' => 'name' ) ); 00273 $response = $this->executeQuery( $request ); 00274 00275 $this->assertEquals( self::$Success, $response ); 00276 } 00277 00278 public function testChange() { 00279 $this->mUserMock->expects( $this->never() ) 00280 ->method( 'resetOptions' ); 00281 00282 $this->mUserMock->expects( $this->at( 2 ) ) 00283 ->method( 'getOptions' ); 00284 00285 $this->mUserMock->expects( $this->at( 4 ) ) 00286 ->method( 'setOption' ) 00287 ->with( $this->equalTo( 'willBeNull' ), $this->identicalTo( null ) ); 00288 00289 $this->mUserMock->expects( $this->at( 5 ) ) 00290 ->method( 'getOptions' ); 00291 00292 $this->mUserMock->expects( $this->at( 6 ) ) 00293 ->method( 'setOption' ) 00294 ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); 00295 00296 $this->mUserMock->expects( $this->at( 7 ) ) 00297 ->method( 'getOptions' ); 00298 00299 $this->mUserMock->expects( $this->at( 8 ) ) 00300 ->method( 'setOption' ) 00301 ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); 00302 00303 $this->mUserMock->expects( $this->once() ) 00304 ->method( 'saveSettings' ); 00305 00306 $request = $this->getSampleRequest( array( 'change' => 'willBeNull|willBeEmpty=|willBeHappy=Happy' ) ); 00307 00308 $response = $this->executeQuery( $request ); 00309 00310 $this->assertEquals( self::$Success, $response ); 00311 } 00312 00313 public function testResetChangeOption() { 00314 $this->mUserMock->expects( $this->once() ) 00315 ->method( 'resetOptions' ); 00316 00317 $this->mUserMock->expects( $this->at( 4 ) ) 00318 ->method( 'getOptions' ); 00319 00320 $this->mUserMock->expects( $this->at( 5 ) ) 00321 ->method( 'setOption' ) 00322 ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); 00323 00324 $this->mUserMock->expects( $this->at( 6 ) ) 00325 ->method( 'getOptions' ); 00326 00327 $this->mUserMock->expects( $this->at( 7 ) ) 00328 ->method( 'setOption' ) 00329 ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); 00330 00331 $this->mUserMock->expects( $this->once() ) 00332 ->method( 'saveSettings' ); 00333 00334 $args = array( 00335 'reset' => '', 00336 'change' => 'willBeHappy=Happy', 00337 'optionname' => 'name', 00338 'optionvalue' => 'value' 00339 ); 00340 00341 $response = $this->executeQuery( $this->getSampleRequest( $args ) ); 00342 00343 $this->assertEquals( self::$Success, $response ); 00344 } 00345 00346 public function testMultiSelect() { 00347 $this->mUserMock->expects( $this->never() ) 00348 ->method( 'resetOptions' ); 00349 00350 $this->mUserMock->expects( $this->at( 3 ) ) 00351 ->method( 'setOption' ) 00352 ->with( $this->equalTo( 'testmultiselect-opt1' ), $this->identicalTo( true ) ); 00353 00354 $this->mUserMock->expects( $this->at( 4 ) ) 00355 ->method( 'setOption' ) 00356 ->with( $this->equalTo( 'testmultiselect-opt2' ), $this->identicalTo( null ) ); 00357 00358 $this->mUserMock->expects( $this->at( 5 ) ) 00359 ->method( 'setOption' ) 00360 ->with( $this->equalTo( 'testmultiselect-opt3' ), $this->identicalTo( false ) ); 00361 00362 $this->mUserMock->expects( $this->at( 6 ) ) 00363 ->method( 'setOption' ) 00364 ->with( $this->equalTo( 'testmultiselect-opt4' ), $this->identicalTo( false ) ); 00365 00366 $this->mUserMock->expects( $this->once() ) 00367 ->method( 'saveSettings' ); 00368 00369 $request = $this->getSampleRequest( array( 00370 'change' => 'testmultiselect-opt1=1|testmultiselect-opt2|testmultiselect-opt3=|testmultiselect-opt4=0' 00371 ) ); 00372 00373 $response = $this->executeQuery( $request ); 00374 00375 $this->assertEquals( self::$Success, $response ); 00376 } 00377 00378 public function testUnknownOption() { 00379 $this->mUserMock->expects( $this->never() ) 00380 ->method( 'resetOptions' ); 00381 00382 $this->mUserMock->expects( $this->never() ) 00383 ->method( 'saveSettings' ); 00384 00385 $request = $this->getSampleRequest( array( 00386 'change' => 'unknownOption=1' 00387 ) ); 00388 00389 $response = $this->executeQuery( $request ); 00390 00391 $this->assertEquals( array( 00392 'options' => 'success', 00393 'warnings' => array( 00394 'options' => array( 00395 '*' => "Validation error for 'unknownOption': not a valid preference" 00396 ) 00397 ) 00398 ), $response ); 00399 } 00400 00401 public function testUserjsOption() { 00402 $this->mUserMock->expects( $this->never() ) 00403 ->method( 'resetOptions' ); 00404 00405 $this->mUserMock->expects( $this->at( 3 ) ) 00406 ->method( 'setOption' ) 00407 ->with( $this->equalTo( 'userjs-option' ), $this->equalTo( '1' ) ); 00408 00409 $this->mUserMock->expects( $this->once() ) 00410 ->method( 'saveSettings' ); 00411 00412 $request = $this->getSampleRequest( array( 00413 'change' => 'userjs-option=1' 00414 ) ); 00415 00416 $response = $this->executeQuery( $request ); 00417 00418 $this->assertEquals( self::$Success, $response ); 00419 } 00420 }