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