MediaWiki
REL1_24
|
00001 <?php 00002 00003 define( 'NS_UNITTEST', 5600 ); 00004 define( 'NS_UNITTEST_TALK', 5601 ); 00005 00009 class UserTest extends MediaWikiTestCase { 00013 protected $user; 00014 00015 protected function setUp() { 00016 parent::setUp(); 00017 00018 $this->setMwGlobals( array( 00019 'wgGroupPermissions' => array(), 00020 'wgRevokePermissions' => array(), 00021 ) ); 00022 00023 $this->setUpPermissionGlobals(); 00024 00025 $this->user = new User; 00026 $this->user->addGroup( 'unittesters' ); 00027 } 00028 00029 private function setUpPermissionGlobals() { 00030 global $wgGroupPermissions, $wgRevokePermissions; 00031 00032 # Data for regular $wgGroupPermissions test 00033 $wgGroupPermissions['unittesters'] = array( 00034 'test' => true, 00035 'runtest' => true, 00036 'writetest' => false, 00037 'nukeworld' => false, 00038 ); 00039 $wgGroupPermissions['testwriters'] = array( 00040 'test' => true, 00041 'writetest' => true, 00042 'modifytest' => true, 00043 ); 00044 00045 # Data for regular $wgRevokePermissions test 00046 $wgRevokePermissions['formertesters'] = array( 00047 'runtest' => true, 00048 ); 00049 00050 # For the options test 00051 $wgGroupPermissions['*'] = array( 00052 'editmyoptions' => true, 00053 ); 00054 } 00055 00059 public function testGroupPermissions() { 00060 $rights = User::getGroupPermissions( array( 'unittesters' ) ); 00061 $this->assertContains( 'runtest', $rights ); 00062 $this->assertNotContains( 'writetest', $rights ); 00063 $this->assertNotContains( 'modifytest', $rights ); 00064 $this->assertNotContains( 'nukeworld', $rights ); 00065 00066 $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) ); 00067 $this->assertContains( 'runtest', $rights ); 00068 $this->assertContains( 'writetest', $rights ); 00069 $this->assertContains( 'modifytest', $rights ); 00070 $this->assertNotContains( 'nukeworld', $rights ); 00071 } 00072 00076 public function testRevokePermissions() { 00077 $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); 00078 $this->assertNotContains( 'runtest', $rights ); 00079 $this->assertNotContains( 'writetest', $rights ); 00080 $this->assertNotContains( 'modifytest', $rights ); 00081 $this->assertNotContains( 'nukeworld', $rights ); 00082 } 00083 00087 public function testUserPermissions() { 00088 $rights = $this->user->getRights(); 00089 $this->assertContains( 'runtest', $rights ); 00090 $this->assertNotContains( 'writetest', $rights ); 00091 $this->assertNotContains( 'modifytest', $rights ); 00092 $this->assertNotContains( 'nukeworld', $rights ); 00093 } 00094 00099 public function testGetGroupsWithPermission( $expected, $right ) { 00100 $result = User::getGroupsWithPermission( $right ); 00101 sort( $result ); 00102 sort( $expected ); 00103 00104 $this->assertEquals( $expected, $result, "Groups with permission $right" ); 00105 } 00106 00107 public static function provideGetGroupsWithPermission() { 00108 return array( 00109 array( 00110 array( 'unittesters', 'testwriters' ), 00111 'test' 00112 ), 00113 array( 00114 array( 'unittesters' ), 00115 'runtest' 00116 ), 00117 array( 00118 array( 'testwriters' ), 00119 'writetest' 00120 ), 00121 array( 00122 array( 'testwriters' ), 00123 'modifytest' 00124 ), 00125 ); 00126 } 00127 00132 public function testIsIP( $value, $result, $message ) { 00133 $this->assertEquals( $this->user->isIP( $value ), $result, $message ); 00134 } 00135 00136 public static function provideIPs() { 00137 return array( 00138 array( '', false, 'Empty string' ), 00139 array( ' ', false, 'Blank space' ), 00140 array( '10.0.0.0', true, 'IPv4 private 10/8' ), 00141 array( '10.255.255.255', true, 'IPv4 private 10/8' ), 00142 array( '192.168.1.1', true, 'IPv4 private 192.168/16' ), 00143 array( '203.0.113.0', true, 'IPv4 example' ), 00144 array( '2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff', true, 'IPv6 example' ), 00145 // Not valid IPs but classified as such by MediaWiki for negated asserting 00146 // of whether this might be the identifier of a logged-out user or whether 00147 // to allow usernames like it. 00148 array( '300.300.300.300', true, 'Looks too much like an IPv4 address' ), 00149 array( '203.0.113.xxx', true, 'Assigned by UseMod to cloaked logged-out users' ), 00150 ); 00151 } 00152 00157 public function testIsValidUserName( $username, $result, $message ) { 00158 $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); 00159 } 00160 00161 public static function provideUserNames() { 00162 return array( 00163 array( '', false, 'Empty string' ), 00164 array( ' ', false, 'Blank space' ), 00165 array( 'abcd', false, 'Starts with small letter' ), 00166 array( 'Ab/cd', false, 'Contains slash' ), 00167 array( 'Ab cd', true, 'Whitespace' ), 00168 array( '192.168.1.1', false, 'IP' ), 00169 array( 'User:Abcd', false, 'Reserved Namespace' ), 00170 array( '12abcd232', true, 'Starts with Numbers' ), 00171 array( '?abcd', true, 'Start with ? mark' ), 00172 array( '#abcd', false, 'Start with #' ), 00173 array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ), 00174 array( 'ജോസ്തോമസ്', false, 'ZWNJ- Format control character' ), 00175 array( 'Ab cd', false, ' Ideographic space' ), 00176 array( '300.300.300.300', false, 'Looks too much like an IPv4 address' ), 00177 array( '302.113.311.900', false, 'Looks too much like an IPv4 address' ), 00178 array( '203.0.113.xxx', false, 'Reserved for usage by UseMod for cloaked logged-out users' ), 00179 ); 00180 } 00181 00187 public function testAllRightsWithMessage() { 00188 // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights 00189 $allRights = User::getAllRights(); 00190 $allMessageKeys = Language::getMessageKeysFor( 'en' ); 00191 00192 $rightsWithMessage = array(); 00193 foreach ( $allMessageKeys as $message ) { 00194 // === 0: must be at beginning of string (position 0) 00195 if ( strpos( $message, 'right-' ) === 0 ) { 00196 $rightsWithMessage[] = substr( $message, strlen( 'right-' ) ); 00197 } 00198 } 00199 00200 sort( $allRights ); 00201 sort( $rightsWithMessage ); 00202 00203 $this->assertEquals( 00204 $allRights, 00205 $rightsWithMessage, 00206 'Each user rights (core/extensions) has a corresponding right- message.' 00207 ); 00208 } 00209 00215 public function testEditCount() { 00216 $user = User::newFromName( 'UnitTestUser' ); 00217 $user->loadDefaults(); 00218 $user->addToDatabase(); 00219 00220 // let the user have a few (3) edits 00221 $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) ); 00222 for ( $i = 0; $i < 3; $i++ ) { 00223 $page->doEdit( (string)$i, 'test', 0, false, $user ); 00224 } 00225 00226 $user->clearInstanceCache(); 00227 $this->assertEquals( 00228 3, 00229 $user->getEditCount(), 00230 'After three edits, the user edit count should be 3' 00231 ); 00232 00233 // increase the edit count and clear the cache 00234 $user->incEditCount(); 00235 00236 $user->clearInstanceCache(); 00237 $this->assertEquals( 00238 4, 00239 $user->getEditCount(), 00240 'After increasing the edit count manually, the user edit count should be 4' 00241 ); 00242 } 00243 00249 public function testOptions() { 00250 $user = User::newFromName( 'UnitTestUser' ); 00251 $user->addToDatabase(); 00252 00253 $user->setOption( 'someoption', 'test' ); 00254 $user->setOption( 'cols', 200 ); 00255 $user->saveSettings(); 00256 00257 $user = User::newFromName( 'UnitTestUser' ); 00258 $this->assertEquals( 'test', $user->getOption( 'someoption' ) ); 00259 $this->assertEquals( 200, $user->getOption( 'cols' ) ); 00260 } 00261 00267 public function testAnonOptions() { 00268 global $wgDefaultUserOptions; 00269 $this->user->setOption( 'someoption', 'test' ); 00270 $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) ); 00271 $this->assertEquals( 'test', $this->user->getOption( 'someoption' ) ); 00272 } 00273 00278 public function testPasswordExpire() { 00279 global $wgPasswordExpireGrace; 00280 $wgTemp = $wgPasswordExpireGrace; 00281 $wgPasswordExpireGrace = 3600 * 24 * 7; // 7 days 00282 00283 $user = User::newFromName( 'UnitTestUser' ); 00284 $user->loadDefaults(); 00285 $this->assertEquals( false, $user->getPasswordExpired() ); 00286 00287 $ts = time() - ( 3600 * 24 * 1 ); // 1 day ago 00288 $user->expirePassword( $ts ); 00289 $this->assertEquals( 'soft', $user->getPasswordExpired() ); 00290 00291 $ts = time() - ( 3600 * 24 * 10 ); // 10 days ago 00292 $user->expirePassword( $ts ); 00293 $this->assertEquals( 'hard', $user->getPasswordExpired() ); 00294 00295 $wgPasswordExpireGrace = $wgTemp; 00296 } 00297 00307 public function testCheckPasswordValidity() { 00308 $this->setMwGlobals( 'wgMinimalPasswordLength', 6 ); 00309 $user = User::newFromName( 'Useruser' ); 00310 // Sanity 00311 $this->assertTrue( $user->isValidPassword( 'Password1234' ) ); 00312 00313 // Minimum length 00314 $this->assertFalse( $user->isValidPassword( 'a' ) ); 00315 $this->assertFalse( $user->checkPasswordValidity( 'a' )->isGood() ); 00316 $this->assertEquals( 'passwordtooshort', $user->getPasswordValidity( 'a' ) ); 00317 00318 // Matches username 00319 $this->assertFalse( $user->checkPasswordValidity( 'Useruser' )->isGood() ); 00320 $this->assertEquals( 'password-name-match', $user->getPasswordValidity( 'Useruser' ) ); 00321 00322 // On the forbidden list 00323 $this->assertFalse( $user->checkPasswordValidity( 'Passpass' )->isGood() ); 00324 $this->assertEquals( 'password-login-forbidden', $user->getPasswordValidity( 'Passpass' ) ); 00325 } 00326 00331 public function testGetCanonicalName( $name, $expectedArray, $msg ) { 00332 foreach ( $expectedArray as $validate => $expected ) { 00333 $this->assertEquals( 00334 User::getCanonicalName( $name, $validate === 'false' ? false : $validate ), 00335 $expected, 00336 $msg . ' (' . $validate . ')' 00337 ); 00338 } 00339 } 00340 00341 public static function provideGetCanonicalName() { 00342 return array( 00343 array( ' trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ), 00344 // @todo FIXME: Maybe the createable name should be 'Talk:Username' or false to reject? 00345 array( 'Talk:Username', array( 'creatable' => 'Username', 'usable' => 'Username', 00346 'valid' => 'Username', 'false' => 'Talk:Username' ), 'Namespace prefix' ), 00347 array( ' name with # hash', array( 'creatable' => false, 'usable' => false ), 'With hash' ), 00348 array( 'Multi spaces', array( 'creatable' => 'Multi spaces', 00349 'usable' => 'Multi spaces' ), 'Multi spaces' ), 00350 array( 'lowercase', array( 'creatable' => 'Lowercase' ), 'Lowercase' ), 00351 array( 'in[]valid', array( 'creatable' => false, 'usable' => false, 'valid' => false, 00352 'false' => 'In[]valid' ), 'Invalid' ), 00353 array( 'with / slash', array( 'creatable' => false, 'usable' => false, 'valid' => false, 00354 'false' => 'With / slash' ), 'With slash' ), 00355 ); 00356 } 00357 }