Whenever possible, reuse User objects in unit tests
authorOri Livneh <ori@wikimedia.org>
Wed, 18 May 2016 09:19:20 +0000 (02:19 -0700)
committerOri.livneh <ori@wikimedia.org>
Thu, 26 May 2016 20:42:31 +0000 (20:42 +0000)
The unit tests spend nearly half of their run time resetting the user table for
each test. But the majority of tests do not depend on the user table having the
exact value that the setup code resets it to, and do not need to modify the
user objects they require to run.

Fix that by providing an API for tests to get User objects, and to indicate
whether the User object will be subject to destructive modification or not.
This allows User objects to be reused across multiple unit tests.

Change-Id: I17ef1f519759c5e7796c259282afe730ef722e96

19 files changed:
tests/TestsAutoLoader.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/MergeHistoryTest.php
tests/phpunit/includes/TestUserRegistry.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/auth/LocalPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/cache/GenderCacheTest.php
tests/phpunit/includes/changes/CategoryMembershipChangeTest.php
tests/phpunit/includes/changes/EnhancedChangesListTest.php
tests/phpunit/includes/changes/OldChangesListTest.php
tests/phpunit/includes/changes/RCCacheEntryFactoryTest.php
tests/phpunit/includes/session/BotPasswordSessionProviderTest.php
tests/phpunit/includes/session/CookieSessionProviderTest.php
tests/phpunit/includes/session/SessionBackendTest.php
tests/phpunit/includes/user/BotPasswordTest.php
tests/phpunit/includes/user/CentralIdLookupTest.php
tests/phpunit/includes/user/LocalIdLookupTest.php
tests/phpunit/includes/user/UserTest.php

index ebb6d90..8b100a2 100644 (file)
@@ -46,6 +46,7 @@ $wgAutoloadClasses += [
        'ResourceLoaderTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
        'ResourceLoaderFileModuleTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
        'TestUser' => "$testDir/phpunit/includes/TestUser.php",
+       'TestUserRegistry' => "$testDir/phpunit/includes/TestUserRegistry.php",
        'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
 
        # tests/phpunit/includes
index 9672cdc..47d96e1 100644 (file)
@@ -127,6 +127,42 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                self::prepareServices( new GlobalVarConfig() );
        }
 
+       /**
+        * Convenience method for getting an immutable test user
+        *
+        * @since 1.28
+        *
+        * @param string[] $groups Groups the test user should be in.
+        * @return TestUser
+        */
+       public static function getTestUser( $groups = [] ) {
+               return TestUserRegistry::getImmutableTestUser( $groups );
+       }
+
+       /**
+        * Convenience method for getting a mutable test user
+        *
+        * @since 1.28
+        *
+        * @param string[] $groups Groups the test user should be added in.
+        * @return TestUser
+        */
+       public static function getMutableTestUser( $groups = [] ) {
+               return TestUserRegistry::getMutableTestUser( __CLASS__, $groups );
+       }
+
+       /**
+        * Convenience method for getting an immutable admin test user
+        *
+        * @since 1.28
+        *
+        * @param string[] $groups Groups the test user should be added to.
+        * @return TestUser
+        */
+       public static function getTestSysop() {
+               return self::getTestUser( [ 'sysop', 'bureaucrat' ] );
+       }
+
        /**
         * Prepare service configuration for unit testing.
         *
@@ -321,7 +357,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                $needsResetDB = false;
 
-               if ( $this->needsDB() ) {
+               if ( !self::$dbSetup || $this->needsDB() ) {
                        // set up a DB connection for this test to use
 
                        self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' );
@@ -883,7 +919,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function insertPage( $pageName, $text = 'Sample page for unit test.' ) {
                $title = Title::newFromText( $pageName, 0 );
 
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $comment = __METHOD__ . ': Sample page for unit test.';
 
                // Avoid memory leak...?
@@ -934,36 +970,33 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                        # Insert 0 user to prevent FK violations
                        # Anonymous user
-                       $this->db->insert( 'user', [
-                               'user_id' => 0,
-                               'user_name' => 'Anonymous' ], __METHOD__, [ 'IGNORE' ] );
+                       if ( !$this->db->selectField( 'user', '1', [ 'user_id' => 0 ] ) ) {
+                               $this->db->insert( 'user', [
+                                       'user_id' => 0,
+                                       'user_name' => 'Anonymous' ], __METHOD__, [ 'IGNORE' ] );
+                       }
 
                        # Insert 0 page to prevent FK violations
                        # Blank page
-                       $this->db->insert( 'page', [
-                               'page_id' => 0,
-                               'page_namespace' => 0,
-                               'page_title' => ' ',
-                               'page_restrictions' => null,
-                               'page_is_redirect' => 0,
-                               'page_is_new' => 0,
-                               'page_random' => 0,
-                               'page_touched' => $this->db->timestamp(),
-                               'page_latest' => 0,
-                               'page_len' => 0 ], __METHOD__, [ 'IGNORE' ] );
+                       if ( !$this->db->selectField( 'page', '1', [ 'page_id' => 0 ] ) ) {
+                               $this->db->insert( 'page', [
+                                       'page_id' => 0,
+                                       'page_namespace' => 0,
+                                       'page_title' => ' ',
+                                       'page_restrictions' => null,
+                                       'page_is_redirect' => 0,
+                                       'page_is_new' => 0,
+                                       'page_random' => 0,
+                                       'page_touched' => $this->db->timestamp(),
+                                       'page_latest' => 0,
+                                       'page_len' => 0 ], __METHOD__, [ 'IGNORE' ] );
+                       }
                }
 
                User::resetIdByNameCache();
 
                // Make sysop user
-               $user = User::newFromName( 'UTSysop' );
-
-               if ( $user->idForName() == 0 ) {
-                       $user->addToDatabase();
-                       TestUser::setPasswordForUser( $user, 'UTSysopPassword' );
-                       $user->addGroup( 'sysop' );
-                       $user->addGroup( 'bureaucrat' );
-               }
+               $user = static::getTestSysop()->getUser();
 
                // Make 1 page with 1 revision
                $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
@@ -1187,6 +1220,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                                TestingAccessWrapper::newFromClass( 'User' )
                                        ->getInProcessCache()
                                        ->clear();
+
+                               TestUserRegistry::clear();
                        }
 
                        $truncate = in_array( $db->getType(), [ 'oracle', 'mysql' ] );
index 22f6fa6..f44ae32 100644 (file)
@@ -97,13 +97,12 @@ class MergeHistoryTest extends MediaWikiTestCase {
                );
 
                // Sysop with mergehistory permission
-               $sysop = User::newFromName( 'UTSysop' );
+               $sysop = static::getTestSysop()->getUser();
                $status = $mh->checkPermissions( $sysop, '' );
                $this->assertTrue( $status->isOK() );
 
                // Normal user
-               $notSysop = User::newFromName( 'UTNotSysop' );
-               $notSysop->addToDatabase();
+               $notSysop = static::getTestUser()->getUser();
                $status = $mh->checkPermissions( $notSysop, '' );
                $this->assertTrue( $status->hasMessage( 'mergehistory-fail-permission' ) );
        }
@@ -118,7 +117,8 @@ class MergeHistoryTest extends MediaWikiTestCase {
                        Title::newFromText( 'Merge2' )
                );
 
-               $mh->merge( User::newFromName( 'UTSysop' ) );
+               $sysop = static::getTestSysop()->getUser();
+               $mh->merge( $sysop );
                $this->assertEquals( $mh->getMergedRevisionCount(), 1 );
        }
 }
diff --git a/tests/phpunit/includes/TestUserRegistry.php b/tests/phpunit/includes/TestUserRegistry.php
new file mode 100644 (file)
index 0000000..4818b49
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @since 1.28
+ */
+class TestUserRegistry {
+
+       /** @var TestUser[] (group key => TestUser) */
+       private static $testUsers = [];
+
+       /** @var int Count of users that have been generated */
+       private static $counter = 0;
+
+       /** @var int Random int, included in IDs */
+       private static $randInt;
+
+       public static function getNextId() {
+               if ( !self::$randInt ) {
+                       self::$randInt = mt_rand( 1, 0xFFFFFF );
+               }
+               return sprintf( '%06x.%03x', self::$randInt, ++self::$counter );
+       }
+
+       /**
+        * Get a TestUser object that the caller may modify.
+        *
+        * @since 1.28
+        *
+        * @param string $testName Caller's __CLASS__. Used to generate the
+        *  user's username.
+        * @param string[] $groups Groups the test user should be added to.
+        * @return TestUser
+        */
+       public static function getMutableTestUser( $testName, $groups = [] ) {
+               $id = self::getNextId();
+               $password = wfRandomString( 20 );
+               $testUser = new TestUser(
+                       "TestUser $testName $id",  // username
+                       "Name $id",                // real name
+                       "$id@mediawiki.test",      // e-mail
+                       $groups,                   // groups
+                       $password                  // password
+               );
+               $testUser->getUser()->clearInstanceCache();
+               return $testUser;
+       }
+
+       /**
+        * Get a TestUser object that the caller may not modify.
+        *
+        * Whenever possible, unit tests should use immutable users, because
+        * immutable users can be reused in multiple tests, which helps keep
+        * the unit tests fast.
+        *
+        * @since 1.28
+        *
+        * @param string[] $groups Groups the test user should be added to.
+        * @return TestUser
+        */
+       public static function getImmutableTestUser( $groups = [] ) {
+               $groups = array_unique( $groups );
+               sort( $groups );
+               $key = implode( ',', $groups );
+
+               $testUser = isset( self::$testUsers[$key] )
+                       ? self::$testUsers[$key]
+                       : false;
+
+               if ( !$testUser || !$testUser->getUser()->isLoggedIn() ) {
+                       $id = self::getNextId();
+                       // Hack! If this is the primary sysop account, make the username
+                       // be 'UTSysop', for back-compat, and for the sake of PHPUnit data
+                       // provider methods, which are executed before the test database
+                       // is set up. See T136348.
+                       if ( $groups === [ 'bureaucrat', 'sysop' ] ) {
+                               $username = 'UTSysop';
+                               $password = 'UTSysopPassword';
+                       } else {
+                               $username = "TestUser $id";
+                               $password = wfRandomString( 20 );
+                       }
+                       self::$testUsers[$key] = $testUser = new TestUser(
+                               $username,            // username
+                               "Name $id",           // real name
+                               "$id@mediawiki.test", // e-mail
+                               $groups,              // groups
+                               $password             // password
+                       );
+               }
+
+               $testUser->getUser()->clearInstanceCache();
+               return self::$testUsers[$key];
+       }
+
+       /**
+        * Clear the registry.
+        *
+        * TestUsers created by this class will not be deleted, but any handles
+        * to existing immutable TestUsers will be deleted, ensuring these users
+        * are not reused. We don't reset the counter or random string by design.
+        *
+        * @since 1.28
+        *
+        * @param string[] $groups Groups the test user should be added to.
+        * @return TestUser
+        */
+       public static function clear() {
+               self::$testUsers = [];
+       }
+}
index f1f9295..def9c5d 100644 (file)
@@ -21,14 +21,12 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
 
        protected function setUp() {
                parent::setUp();
-               self::$users['ApiQueryWatchlistIntegrationTestUser']
-                       = new TestUser( 'ApiQueryWatchlistIntegrationTestUser' );
-               self::$users['ApiQueryWatchlistIntegrationTestUser2']
-                       = new TestUser( 'ApiQueryWatchlistIntegrationTestUser2' );
+               self::$users['ApiQueryWatchlistIntegrationTestUser'] = $this->getMutableTestUser();
+               self::$users['ApiQueryWatchlistIntegrationTestUser2'] = $this->getMutableTestUser();
                $this->doLogin( 'ApiQueryWatchlistIntegrationTestUser' );
        }
 
-       private function getTestUser() {
+       private function getLoggedInTestUser() {
                return self::$users['ApiQueryWatchlistIntegrationTestUser']->getUser();
        }
 
@@ -36,10 +34,6 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                return self::$users['ApiQueryWatchlistIntegrationTestUser2']->getUser();
        }
 
-       private function getSysopTestUser() {
-               return self::$users['sysop']->getUser();
-       }
-
        private function doPageEdit( User $user, LinkTarget $target, $content, $summary ) {
                $title = Title::newFromLinkTarget( $target );
                $page = WikiPage::factory( $title );
@@ -244,7 +238,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        private function cleanTestUsersWatchlist() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $store = $this->getWatchedItemStore();
                $items = $store->getWatchedItemsForUser( $user );
                foreach ( $items as $item ) {
@@ -257,7 +251,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                // the user with the same user ID as user used here as the test user
                $this->cleanTestUsersWatchlist();
 
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -290,7 +284,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testIdsPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -311,7 +305,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testTitlePropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
@@ -351,7 +345,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testFlagsPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $normalEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $minorEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageM' );
                $botEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageB' );
@@ -412,7 +406,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testUserPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
                $this->doPageEdit(
@@ -447,7 +441,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testUserIdPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
                $this->doPageEdit(
@@ -484,7 +478,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testCommentPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -508,7 +502,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testParsedCommentPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -532,7 +526,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testTimestampPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -551,7 +545,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testSizesPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -585,7 +579,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                        'Create the page'
                );
                $store = $this->getWatchedItemStore();
-               $store->addWatch( $this->getTestUser(), $target );
+               $store->addWatch( $this->getLoggedInTestUser(), $target );
                $store->updateNotificationTimestamp(
                        $otherUser,
                        $target,
@@ -620,7 +614,8 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testPatrolPropParameter() {
-               $user = $this->getSysopTestUser();
+               $testUser = static::getTestSysop();
+               $user = $testUser->getUser();
                $this->setupPatrolledSpecificFixtures( $user );
 
                $result = $this->doListWatchlistRequest( [ 'wlprop' => 'patrol', ], $user );
@@ -639,7 +634,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
 
        private function createPageAndDeleteIt( LinkTarget $target ) {
                $this->doPageEdit(
-                       $this->getTestUser(),
+                       $this->getLoggedInTestUser(),
                        $target,
                        'Some Content',
                        'Create the page that will be deleted'
@@ -651,7 +646,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->createPageAndDeleteIt( $target );
 
-               $this->watchPages( $this->getTestUser(), [ $target ] );
+               $this->watchPages( $this->getLoggedInTestUser(), [ $target ] );
 
                $result = $this->doListWatchlistRequest( [ 'wlprop' => 'loginfo', ] );
 
@@ -671,7 +666,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testEmptyPropParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -694,7 +689,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testNamespaceParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
@@ -729,7 +724,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testUserParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $otherUser = $this->getNonLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
@@ -766,7 +761,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testExcludeUserParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $otherUser = $this->getNonLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
@@ -803,7 +798,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testShowMinorParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
                        $user,
@@ -837,7 +832,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testShowBotParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doBotPageEdit(
                        $user,
@@ -861,7 +856,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testShowAnonParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doAnonPageEdit(
                        $target,
@@ -890,7 +885,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testShowUnreadParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $otherUser = $this->getNonLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
@@ -948,7 +943,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testShowPatrolledParams() {
-               $user = $this->getSysopTestUser();
+               $user = static::getTestSysop()->getUser();
                $this->setupPatrolledSpecificFixtures( $user );
 
                $resultPatrolled = $this->doListWatchlistRequest( [
@@ -974,7 +969,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testNewAndEditTypeParameters() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
@@ -1025,7 +1020,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testLogTypeParameters() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->createPageAndDeleteIt( $subjectTarget );
@@ -1093,7 +1088,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testExternalTypeParameters() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
@@ -1129,7 +1124,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testCategorizeTypeParameter() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryWatchlistIntegrationTestCategory' );
                $this->doPageEdits(
@@ -1180,7 +1175,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testLimitParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
@@ -1249,7 +1244,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testAllRevParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
                        $user,
@@ -1299,7 +1294,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testDirParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
@@ -1355,7 +1350,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testStartEndParams() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -1390,7 +1385,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testContinueParam() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
                $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
@@ -1456,7 +1451,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        public function testOwnerAndTokenParams() {
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
-                       $this->getTestUser(),
+                       $this->getLoggedInTestUser(),
                        $target,
                        'Some Content',
                        'Create the page'
@@ -1509,7 +1504,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testGeneratorWatchlistPropInfo_returnsWatchedPages() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdit(
                        $user,
@@ -1541,7 +1536,7 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
        }
 
        public function testGeneratorWatchlistPropRevisions_returnsWatchedItemsRevisions() {
-               $user = $this->getTestUser();
+               $user = $this->getLoggedInTestUser();
                $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
                $this->doPageEdits(
                        $user,
index ff5640a..e90b46f 100644 (file)
@@ -8,11 +8,6 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
         */
        protected $apiContext;
 
-       /**
-        * @var array
-        */
-       protected $tablesUsed = [ 'user', 'user_groups', 'user_properties' ];
-
        protected function setUp() {
                global $wgServer, $wgDisableAuthManager;
 
@@ -22,18 +17,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session
 
                self::$users = [
-                       'sysop' => new TestUser(
-                               'Apitestsysop',
-                               'Api Test Sysop',
-                               'api_test_sysop@example.com',
-                               [ 'sysop' ]
-                       ),
-                       'uploader' => new TestUser(
-                               'Apitestuser',
-                               'Api Test User',
-                               'api_test_user@example.com',
-                               []
-                       )
+                       'sysop' => static::getTestSysop(),
+                       'uploader' => static::getTestUser(),
                ];
 
                $this->setMwGlobals( [
@@ -162,15 +147,19 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                }
        }
 
-       protected function doLogin( $user = 'sysop' ) {
-               if ( !array_key_exists( $user, self::$users ) ) {
-                       throw new MWException( "Can not log in to undefined user $user" );
+       protected function doLogin( $testUser = 'sysop' ) {
+               if ( $testUser === null ) {
+                       $testUser = static::getTestSysop();
+               } elseif ( is_string( $testUser ) && array_key_exists( $testUser, self::$users ) ) {
+                       $testUser = self::$users[ $testUser ];
+               } elseif ( !$testUser instanceof TestUser ) {
+                       throw new MWException( "Can not log in to undefined user $testUser" );
                }
 
                $data = $this->doApiRequest( [
                        'action' => 'login',
-                       'lgname' => self::$users[$user]->username,
-                       'lgpassword' => self::$users[$user]->password ] );
+                       'lgname' => $testUser->username,
+                       'lgpassword' => $testUser->password ] );
 
                $token = $data[0]['login']['token'];
 
@@ -178,8 +167,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                        [
                                'action' => 'login',
                                'lgtoken' => $token,
-                               'lgname' => self::$users[$user]->username,
-                               'lgpassword' => self::$users[$user]->password,
+                               'lgname' => $testUser->username,
+                               'lgpassword' => $testUser->password,
                        ],
                        $data[2]
                );
@@ -187,7 +176,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                if ( $data[0]['login']['result'] === 'Success' ) {
                        // DWIM
                        global $wgUser;
-                       $wgUser = self::$users[$user]->getUser();
+                       $wgUser = $testUser->getUser();
                        RequestContext::getMain()->setUser( $wgUser );
                }
 
index fa68dee..713c27e 100644 (file)
@@ -62,6 +62,10 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
        }
 
        public function testBasics() {
+               $user = $this->getMutableTestUser()->getUser();
+               $userName = $user->getName();
+               $lowerInitialUserName = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
+
                $provider = new LocalPasswordPrimaryAuthenticationProvider();
 
                $this->assertSame(
@@ -69,8 +73,8 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                        $provider->accountCreationType()
                );
 
-               $this->assertTrue( $provider->testUserExists( 'UTSysop' ) );
-               $this->assertTrue( $provider->testUserExists( 'uTSysop' ) );
+               $this->assertTrue( $provider->testUserExists( $userName ) );
+               $this->assertTrue( $provider->testUserExists( $lowerInitialUserName ) );
                $this->assertFalse( $provider->testUserExists( 'DoesNotExist' ) );
                $this->assertFalse( $provider->testUserExists( '<invalid>' ) );
 
@@ -81,7 +85,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                        $provider->accountCreationType()
                );
 
-               $this->assertTrue( $provider->testUserExists( 'UTSysop' ) );
+               $this->assertTrue( $provider->testUserExists( $userName ) );
                $this->assertFalse( $provider->testUserExists( 'DoesNotExist' ) );
 
                $req = new PasswordAuthenticationRequest;
@@ -91,12 +95,9 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
        }
 
        public function testTestUserCanAuthenticate() {
+               $user = $this->getMutableTestUser()->getUser();
+               $userName = $user->getName();
                $dbw = wfGetDB( DB_MASTER );
-               $oldHash = $dbw->selectField( 'user', 'user_password', [ 'user_name' => 'UTSysop' ] );
-               $cb = new \ScopedCallback( function () use ( $dbw, $oldHash ) {
-                       $dbw->update( 'user', [ 'user_password' => $oldHash ], [ 'user_name' => 'UTSysop' ] );
-               } );
-               $id = \User::idFromName( 'UTSysop' );
 
                $provider = $this->getProvider();
 
@@ -104,23 +105,24 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                $this->assertFalse( $provider->testUserCanAuthenticate( 'DoesNotExist' ) );
 
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'uTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $userName ) );
+               $lowerInitialUserName = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $lowerInitialUserName ) );
 
                $dbw->update(
                        'user',
                        [ 'user_password' => \PasswordFactory::newInvalidPassword()->toString() ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_name' => $userName ]
                );
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertFalse( $provider->testUserCanAuthenticate( $userName ) );
 
                // Really old format
                $dbw->update(
                        'user',
                        [ 'user_password' => '0123456789abcdef0123456789abcdef' ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_name' => $userName ]
                );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $userName ) );
        }
 
        public function testSetPasswordResetFlag() {
@@ -139,22 +141,24 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $provider->setManager( $this->manager );
                $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
 
+               $user = $this->getMutableTestUser()->getUser();
+               $userName = $user->getName();
                $dbw = wfGetDB( DB_MASTER );
                $row = $dbw->selectRow(
                        'user',
                        '*',
-                       [ 'user_name' => 'UTSysop' ],
+                       [ 'user_name' => $userName ],
                        __METHOD__
                );
 
                $this->manager->removeAuthenticationSessionData( null );
                $row->user_password_expires = wfTimestamp( TS_MW, time() + 200 );
-               $providerPriv->setPasswordResetFlag( 'UTSysop', \Status::newGood(), $row );
+               $providerPriv->setPasswordResetFlag( $userName, \Status::newGood(), $row );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
 
                $this->manager->removeAuthenticationSessionData( null );
                $row->user_password_expires = wfTimestamp( TS_MW, time() - 200 );
-               $providerPriv->setPasswordResetFlag( 'UTSysop', \Status::newGood(), $row );
+               $providerPriv->setPasswordResetFlag( $userName, \Status::newGood(), $row );
                $ret = $this->manager->getAuthenticationSessionData( 'reset-pass' );
                $this->assertNotNull( $ret );
                $this->assertSame( 'resetpass-expired', $ret->msg->getKey() );
@@ -162,7 +166,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                $this->manager->removeAuthenticationSessionData( null );
                $row->user_password_expires = wfTimestamp( TS_MW, time() - 1 );
-               $providerPriv->setPasswordResetFlag( 'UTSysop', \Status::newGood(), $row );
+               $providerPriv->setPasswordResetFlag( $userName, \Status::newGood(), $row );
                $ret = $this->manager->getAuthenticationSessionData( 'reset-pass' );
                $this->assertNotNull( $ret );
                $this->assertSame( 'resetpass-expired-soft', $ret->msg->getKey() );
@@ -172,7 +176,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $row->user_password_expires = null;
                $status = \Status::newGood();
                $status->error( 'testing' );
-               $providerPriv->setPasswordResetFlag( 'UTSysop', $status, $row );
+               $providerPriv->setPasswordResetFlag( $userName, $status, $row );
                $ret = $this->manager->getAuthenticationSessionData( 'reset-pass' );
                $this->assertNotNull( $ret );
                $this->assertSame( 'resetpass-validity-soft', $ret->msg->getKey() );
@@ -180,12 +184,11 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
        }
 
        public function testAuthentication() {
+               $testUser = $this->getMutableTestUser();
+               $userName = $testUser->getUser()->getName();
+
                $dbw = wfGetDB( DB_MASTER );
-               $oldHash = $dbw->selectField( 'user', 'user_password', [ 'user_name' => 'UTSysop' ] );
-               $cb = new \ScopedCallback( function () use ( $dbw, $oldHash ) {
-                       $dbw->update( 'user', [ 'user_password' => $oldHash ], [ 'user_name' => 'UTSysop' ] );
-               } );
-               $id = \User::idFromName( 'UTSysop' );
+               $id = \User::idFromName( $userName );
 
                $req = new PasswordAuthenticationRequest();
                $req->action = AuthManager::ACTION_LOGIN;
@@ -230,8 +233,8 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                );
 
                // Validation failure
-               $req->username = 'UTSysop';
-               $req->password = 'UTSysopPassword';
+               $req->username = $userName;
+               $req->password = $testUser->getPassword();
                $this->validity = \Status::newFatal( 'arbitrary-failure' );
                $ret = $provider->beginPrimaryAuthentication( $reqs );
                $this->assertEquals(
@@ -247,7 +250,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
@@ -255,19 +258,19 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                // Successful auth after normalizing name
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
-               $req->username = 'uTSysop';
+               $req->username = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
-               $req->username = 'UTSysop';
+               $req->username = $userName;
 
                // Successful auth with reset
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity->error( 'arbitrary-warning' );
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNotNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
@@ -287,7 +290,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                // Correct handling of legacy encodings
                $password = ':B:salt:' . md5( 'salt-' . md5( "\xe1\xe9\xed\xf3\xfa" ) );
-               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => 'UTSysop' ] );
+               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => $userName ] );
                $req->password = 'áéíóú';
                $ret = $provider->beginPrimaryAuthentication( $reqs );
                $this->assertEquals(
@@ -301,7 +304,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                $this->config->set( 'LegacyEncoding', true );
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
 
@@ -319,19 +322,19 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                // Correct handling of really old password hashes
                $this->config->set( 'PasswordSalt', false );
                $password = md5( 'FooBar' );
-               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => 'UTSysop' ] );
+               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => $userName ] );
                $req->password = 'FooBar';
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
 
                $this->config->set( 'PasswordSalt', true );
                $password = md5( "$id-" . md5( 'FooBar' ) );
-               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => 'UTSysop' ] );
+               $dbw->update( 'user', [ 'user_password' => $password ], [ 'user_name' => $userName ] );
                $req->password = 'FooBar';
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
 
@@ -407,29 +410,24 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
        /**
         * @dataProvider provideProviderChangeAuthenticationData
-        * @param string $user
+        * @param callable|bool $usernameTransform
         * @param string $type
         * @param bool $loginOnly
         * @param bool $changed
         */
-       public function testProviderChangeAuthenticationData( $user, $type, $loginOnly, $changed ) {
+       public function testProviderChangeAuthenticationData(
+                       $usernameTransform, $type, $loginOnly, $changed ) {
+               $testUser = $this->getMutableTestUser();
+               $user = $testUser->getUser()->getName();
+               if ( is_callable( $usernameTransform ) ) {
+                       $user = call_user_func( $usernameTransform, $user );
+               }
                $cuser = ucfirst( $user );
-               $oldpass = 'UTSysopPassword';
+               $oldpass = $testUser->getPassword();
                $newpass = 'NewPassword';
 
                $dbw = wfGetDB( DB_MASTER );
-               $oldHash = $dbw->selectField( 'user', 'user_password', [ 'user_name' => $cuser ] );
                $oldExpiry = $dbw->selectField( 'user', 'user_password_expires', [ 'user_name' => $cuser ] );
-               $cb = new \ScopedCallback( function () use ( $dbw, $cuser, $oldHash, $oldExpiry ) {
-                       $dbw->update(
-                               'user',
-                               [
-                                       'user_password' => $oldHash,
-                                       'user_password_expires' => $oldExpiry,
-                               ],
-                               [ 'user_name' => $cuser ]
-                       );
-               } );
 
                $this->mergeMwGlobalArrayValue( 'wgHooks', [
                        'ResetPasswordExpiration' => [ function ( $user, &$expires ) {
@@ -525,12 +523,12 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
        public static function provideProviderChangeAuthenticationData() {
                return [
-                       [ 'UTSysop', AuthenticationRequest::class, false, false ],
-                       [ 'UTSysop', PasswordAuthenticationRequest::class, false, true ],
-                       [ 'UTSysop', AuthenticationRequest::class, true, false ],
-                       [ 'UTSysop', PasswordAuthenticationRequest::class, true, true ],
-                       [ 'uTSysop', PasswordAuthenticationRequest::class, false, true ],
-                       [ 'uTSysop', PasswordAuthenticationRequest::class, true, true ],
+                       [ false, AuthenticationRequest::class, false, false ],
+                       [ false, PasswordAuthenticationRequest::class, false, true ],
+                       [ false, AuthenticationRequest::class, true, false ],
+                       [ false, PasswordAuthenticationRequest::class, true, true ],
+                       [ 'ucfirst', PasswordAuthenticationRequest::class, false, true ],
+                       [ 'ucfirst', PasswordAuthenticationRequest::class, true, true ],
                ];
        }
 
@@ -640,10 +638,6 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                // We have to cheat a bit to avoid having to add a new user to
                // the database to test the actual setting of the password works right
                $dbw = wfGetDB( DB_MASTER );
-               $oldHash = $dbw->selectField( 'user', 'user_password', [ 'user_name' => $user ] );
-               $cb = new \ScopedCallback( function () use ( $dbw, $user, $oldHash ) {
-                       $dbw->update( 'user', [ 'user_password' => $oldHash ], [ 'user_name' => $user ] );
-               } );
 
                $user = \User::newFromName( 'UTSysop' );
                $req->username = $user->getName();
index e329f8d..9c723c0 100644 (file)
@@ -6,36 +6,30 @@
  */
 class GenderCacheTest extends MediaWikiLangTestCase {
 
+       /** @var string[] User key => username */
+       private static $nameMap;
+
        function addDBDataOnce() {
                // ensure the correct default gender
                $this->mergeMwGlobalArrayValue( 'wgDefaultUserOptions', [ 'gender' => 'unknown' ] );
 
-               $user = User::newFromName( 'UTMale' );
-               if ( $user->getId() == 0 ) {
-                       $user->addToDatabase();
-                       TestUser::setPasswordForUser( $user, 'UTMalePassword' );
-               }
-               // ensure the right gender
-               $user->setOption( 'gender', 'male' );
-               $user->saveSettings();
+               $male = $this->getMutableTestUser()->getUser();
+               $male->setOption( 'gender', 'male' );
+               $male->saveSettings();
+
+               $female = $this->getMutableTestUser()->getUser();
+               $female->setOption( 'gender', 'female' );
+               $female->saveSettings();
 
-               $user = User::newFromName( 'UTFemale' );
-               if ( $user->getId() == 0 ) {
-                       $user->addToDatabase();
-                       TestUser::setPasswordForUser( $user, 'UTFemalePassword' );
-               }
-               // ensure the right gender
-               $user->setOption( 'gender', 'female' );
-               $user->saveSettings();
+               $default = $this->getMutableTestUser()->getUser();
+               $default->setOption( 'gender', null );
+               $default->saveSettings();
 
-               $user = User::newFromName( 'UTDefaultGender' );
-               if ( $user->getId() == 0 ) {
-                       $user->addToDatabase();
-                       TestUser::setPasswordForUser( $user, 'UTDefaultGenderPassword' );
-               }
-               // ensure the default gender
-               $user->setOption( 'gender', null );
-               $user->saveSettings();
+               self::$nameMap = [
+                       'UTMale'          => $male->getName(),
+                       'UTFemale'        => $female->getName(),
+                       'UTDefaultGender' => $default->getName()
+               ];
        }
 
        /**
@@ -44,8 +38,9 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         * @dataProvider provideUserGenders
         * @covers GenderCache::getGenderOf
         */
-       public function testUserName( $username, $expectedGender ) {
+       public function testUserName( $userKey, $expectedGender ) {
                $genderCache = GenderCache::singleton();
+               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
                $gender = $genderCache->getGenderOf( $username );
                $this->assertEquals( $gender, $expectedGender, "GenderCache normal" );
        }
@@ -56,10 +51,10 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         * @dataProvider provideUserGenders
         * @covers GenderCache::getGenderOf
         */
-       public function testUserObjects( $username, $expectedGender ) {
+       public function testUserObjects( $userKey, $expectedGender ) {
+               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
                $genderCache = GenderCache::singleton();
-               $user = User::newFromName( $username );
-               $gender = $genderCache->getGenderOf( $user );
+               $gender = $genderCache->getGenderOf( $username );
                $this->assertEquals( $gender, $expectedGender, "GenderCache normal" );
        }
 
@@ -79,22 +74,13 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         * test strip of subpages to avoid unnecessary queries
         * against the never existing username
         *
-        * @dataProvider provideStripSubpages
+        * @dataProvider provideUserGenders
         * @covers GenderCache::getGenderOf
         */
-       public function testStripSubpages( $pageWithSubpage, $expectedGender ) {
+       public function testStripSubpages( $userKey, $expectedGender ) {
+               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
                $genderCache = GenderCache::singleton();
-               $gender = $genderCache->getGenderOf( $pageWithSubpage );
+               $gender = $genderCache->getGenderOf( "$username/subpage" );
                $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" );
        }
-
-       public static function provideStripSubpages() {
-               return [
-                       [ 'UTMale/subpage', 'male' ],
-                       [ 'UTFemale/subpage', 'female' ],
-                       [ 'UTDefaultGender/subpage', 'unknown' ],
-                       [ 'UTNotExist/subpage', 'unknown' ],
-                       [ '127.0.0.1/subpage', 'unknown' ],
-               ];
-       }
 }
index 1d86fb4..e44de09 100644 (file)
@@ -29,6 +29,11 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
         */
        private static $pageRev = null;
 
+       /**
+        * @var User
+        */
+       private static $revUser = null;
+
        /**
         * @var string
         */
@@ -54,6 +59,7 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
 
                $page = WikiPage::factory( $title );
                self::$pageRev = $page->getRevision();
+               self::$revUser = User::newFromId( self::$pageRev->getUser( Revision::RAW ) );
        }
 
        private function newChange( Revision $revision = null ) {
@@ -114,7 +120,7 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
 
                $this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
                $this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
-               $this->assertEquals( 'UTSysop', self::$lastNotifyArgs[2]->getName() );
+               $this->assertEquals( self::$revUser->getName(), self::$lastNotifyArgs[2]->getName() );
                $this->assertEquals( '(recentchanges-page-added-to-category: ' . self::$pageName . ')',
                        self::$lastNotifyArgs[3] );
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
@@ -135,7 +141,7 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
 
                $this->assertTrue( strlen( self::$lastNotifyArgs[0] ) === 14 );
                $this->assertEquals( 'Category:CategoryName', self::$lastNotifyArgs[1]->getPrefixedText() );
-               $this->assertEquals( 'UTSysop', self::$lastNotifyArgs[2]->getName() );
+               $this->assertEquals( self::$revUser->getName(), self::$lastNotifyArgs[2]->getName() );
                $this->assertEquals( '(recentchanges-page-removed-from-category: ' . self::$pageName . ')',
                        self::$lastNotifyArgs[3] );
                $this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
index b8be8d4..308e6de 100644 (file)
@@ -121,7 +121,7 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
         * @return RecentChange
         */
        private function getEditChange( $timestamp ) {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
                $recentChange = $this->testRecentChangesHelper->makeEditRecentChange(
                        $user, 'Cat', $timestamp, 5, 191, 190, 0, 0
                );
@@ -139,7 +139,7 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                $wikiPage = new WikiPage( Title::newFromText( 'Category:Foo' ) );
                $wikiPage->doEditContent( new WikitextContent( 'Some random text' ), 'category page created' );
 
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
                $recentChange = $this->testRecentChangesHelper->makeCategorizationRecentChange(
                        $user, 'Category:Foo', $wikiPage->getId(), $thisId, $lastId, $timestamp
                );
@@ -147,19 +147,6 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                return $recentChange;
        }
 
-       /**
-        * @return User
-        */
-       private function getTestUser() {
-               $user = User::newFromName( 'TestRecentChangesUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               return $user;
-       }
-
        private function createCategorizationLine( $recentChange ) {
                $enhancedChangesList = $this->newEnhancedChangesList();
                $cacheEntry = $this->testRecentChangesHelper->getCacheEntry( $recentChange );
index bc70a13..51cfadc 100644 (file)
@@ -150,7 +150,7 @@ class OldChangesListTest extends MediaWikiLangTestCase {
        }
 
        private function getNewBotEditChange() {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
 
                $recentChange = $this->testRecentChangesHelper->makeNewBotEditRecentChange(
                        $user, 'Abc', '20131103212153', 5, 191, 190, 0, 0
@@ -160,7 +160,7 @@ class OldChangesListTest extends MediaWikiLangTestCase {
        }
 
        private function getLogChange( $logType, $logAction ) {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
 
                $recentChange = $this->testRecentChangesHelper->makeLogRecentChange(
                        $logType, $logAction, $user, 'Abc', '20131103212153', 0, 0
@@ -170,7 +170,7 @@ class OldChangesListTest extends MediaWikiLangTestCase {
        }
 
        private function getEditChange() {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
                $recentChange = $this->testRecentChangesHelper->makeEditRecentChange(
                        $user, 'Cat', '20131103212153', 5, 191, 190, 0, 0
                );
@@ -183,18 +183,8 @@ class OldChangesListTest extends MediaWikiLangTestCase {
                return new OldChangesList( $context );
        }
 
-       private function getTestUser() {
-               $user = User::newFromName( 'TestRecentChangesUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               return $user;
-       }
-
        private function getContext() {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
                $context = $this->testRecentChangesHelper->getTestContext( $user );
                $context->setLanguage( 'qqx' );
 
index 602340b..9debc03 100644 (file)
@@ -28,131 +28,95 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
                ] );
        }
 
-       /**
-        * @dataProvider editChangeProvider
-        */
-       public function testNewFromRecentChange( $expected, $context, $messages,
-               $recentChange, $watched
-       ) {
-               $cacheEntryFactory = new RCCacheEntryFactory( $context, $messages );
-               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, $watched );
+       public function testNewFromRecentChange() {
+               $user = $this->getMutableTestUser()->getUser();
+               $recentChange = $this->testRecentChangesHelper->makeEditRecentChange(
+                       $user,
+                       'Xyz',
+                       5, // curid
+                       191, // thisid
+                       190, // lastid
+                       '20131103212153',
+                       0, // counter
+                       0 // number of watching users
+               );
+               $cacheEntryFactory = new RCCacheEntryFactory( $this->getContext(), $this->getMessages() );
+               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
 
                $this->assertInstanceOf( 'RCCacheEntry', $cacheEntry );
 
-               $this->assertEquals( $watched, $cacheEntry->watched, 'watched' );
-               $this->assertEquals( $expected['timestamp'], $cacheEntry->timestamp, 'timestamp' );
-               $this->assertEquals(
-                       $expected['numberofWatchingusers'], $cacheEntry->numberofWatchingusers,
-                       'watching users'
-               );
-               $this->assertEquals( $expected['unpatrolled'], $cacheEntry->unpatrolled, 'unpatrolled' );
+               $this->assertEquals( false, $cacheEntry->watched, 'watched' );
+               $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
+               $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+               $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
 
-               $this->assertUserLinks( 'TestRecentChangesUser', $cacheEntry );
+               $this->assertUserLinks( $user->getName(), $cacheEntry );
                $this->assertTitleLink( 'Xyz', $cacheEntry );
 
-               $this->assertQueryLink( 'cur', $expected['cur'], $cacheEntry->curlink, 'cur link' );
-               $this->assertQueryLink( 'prev', $expected['diff'], $cacheEntry->lastlink, 'prev link' );
-               $this->assertQueryLink( 'diff', $expected['diff'], $cacheEntry->difflink, 'diff link' );
+               $diff = [ 'curid' => 5, 'diff' => 191, 'oldid' => 190 ];
+               $cur = [ 'curid' => 5, 'diff' => 0, 'oldid' => 191 ];
+               $this->assertQueryLink( 'cur', $cur, $cacheEntry->curlink, 'cur link' );
+               $this->assertQueryLink( 'prev', $diff, $cacheEntry->lastlink, 'prev link' );
+               $this->assertQueryLink( 'diff', $diff, $cacheEntry->difflink, 'diff link' );
        }
 
-       public function editChangeProvider() {
-               return [
-                       [
-                               [
-                                       'title' => 'Xyz',
-                                       'user' => 'TestRecentChangesUser',
-                                       'diff' => [ 'curid' => 5, 'diff' => 191, 'oldid' => 190 ],
-                                       'cur' => [ 'curid' => 5, 'diff' => 0, 'oldid' => 191 ],
-                                       'timestamp' => '21:21',
-                                       'numberofWatchingusers' => 0,
-                                       'unpatrolled' => false
-                               ],
-                               $this->getContext(),
-                               $this->getMessages(),
-                               $this->testRecentChangesHelper->makeEditRecentChange(
-                                       $this->getTestUser(),
-                                       'Xyz',
-                                       5, // curid
-                                       191, // thisid
-                                       190, // lastid
-                                       '20131103212153',
-                                       0, // counter
-                                       0 // number of watching users
-                               ),
-                               false
-                       ]
+       public function testNewForDeleteChange() {
+               $expected = [
+                       'title' => 'Abc',
+                       'user' => 'TestRecentChangesUser',
+                       'timestamp' => '21:21',
+                       'numberofWatchingusers' => 0,
+                       'unpatrolled' => false
                ];
-       }
-
-       /**
-        * @dataProvider deleteChangeProvider
-        */
-       public function testNewForDeleteChange( $expected, $context, $messages, $recentChange, $watched ) {
-               $cacheEntryFactory = new RCCacheEntryFactory( $context, $messages );
-               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, $watched );
+               $user = $this->getMutableTestUser()->getUser();
+               $recentChange = $this->testRecentChangesHelper->makeLogRecentChange(
+                       'delete',
+                       'delete',
+                       $user,
+                       'Abc',
+                       '20131103212153',
+                       0, // counter
+                       0 // number of watching users
+               );
+               $cacheEntryFactory = new RCCacheEntryFactory( $this->getContext(), $this->getMessages() );
+               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
 
                $this->assertInstanceOf( 'RCCacheEntry', $cacheEntry );
 
-               $this->assertEquals( $watched, $cacheEntry->watched, 'watched' );
-               $this->assertEquals( $expected['timestamp'], $cacheEntry->timestamp, 'timestamp' );
-               $this->assertEquals(
-                       $expected['numberofWatchingusers'],
-                       $cacheEntry->numberofWatchingusers, 'watching users'
-               );
-               $this->assertEquals( $expected['unpatrolled'], $cacheEntry->unpatrolled, 'unpatrolled' );
+               $this->assertEquals( false, $cacheEntry->watched, 'watched' );
+               $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
+               $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+               $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
 
                $this->assertDeleteLogLink( $cacheEntry );
-               $this->assertUserLinks( 'TestRecentChangesUser', $cacheEntry );
+               $this->assertUserLinks( $user->getName(), $cacheEntry );
 
                $this->assertEquals( 'cur', $cacheEntry->curlink, 'cur link for delete log or rev' );
                $this->assertEquals( 'diff', $cacheEntry->difflink, 'diff link for delete log or rev' );
                $this->assertEquals( 'prev', $cacheEntry->lastlink, 'pref link for delete log or rev' );
        }
 
-       public function deleteChangeProvider() {
-               return [
-                       [
-                               [
-                                       'title' => 'Abc',
-                                       'user' => 'TestRecentChangesUser',
-                                       'timestamp' => '21:21',
-                                       'numberofWatchingusers' => 0,
-                                       'unpatrolled' => false
-                               ],
-                               $this->getContext(),
-                               $this->getMessages(),
-                               $this->testRecentChangesHelper->makeLogRecentChange(
-                                       'delete',
-                                       'delete',
-                                       $this->getTestUser(),
-                                       'Abc',
-                                       '20131103212153',
-                                       0, // counter
-                                       0 // number of watching users
-                               ),
-                               false
-                       ]
-               ];
-       }
-
-       /**
-        * @dataProvider revUserDeleteProvider
-        */
-       public function testNewForRevUserDeleteChange( $expected, $context, $messages,
-               $recentChange, $watched
-       ) {
-               $cacheEntryFactory = new RCCacheEntryFactory( $context, $messages );
-               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, $watched );
+       public function testNewForRevUserDeleteChange() {
+               $user = $this->getMutableTestUser()->getUser();
+               $recentChange = $this->testRecentChangesHelper->makeDeletedEditRecentChange(
+                       $user,
+                       'Zzz',
+                       '20131103212153',
+                       191, // thisid
+                       190, // lastid
+                       '20131103212153',
+                       0, // counter
+                       0 // number of watching users
+               );
+               $cacheEntryFactory = new RCCacheEntryFactory( $this->getContext(), $this->getMessages() );
+               $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
 
                $this->assertInstanceOf( 'RCCacheEntry', $cacheEntry );
 
-               $this->assertEquals( $watched, $cacheEntry->watched, 'watched' );
-               $this->assertEquals( $expected['timestamp'], $cacheEntry->timestamp, 'timestamp' );
-               $this->assertEquals(
-                       $expected['numberofWatchingusers'],
-                       $cacheEntry->numberofWatchingusers, 'watching users'
-               );
-               $this->assertEquals( $expected['unpatrolled'], $cacheEntry->unpatrolled, 'unpatrolled' );
+               $this->assertEquals( false, $cacheEntry->watched, 'watched' );
+               $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
+               $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+               $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
 
                $this->assertRevDel( $cacheEntry );
                $this->assertTitleLink( 'Zzz', $cacheEntry );
@@ -162,35 +126,6 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
                $this->assertEquals( 'prev', $cacheEntry->lastlink, 'pref link for delete log or rev' );
        }
 
-       public function revUserDeleteProvider() {
-               return [
-                       [
-                               [
-                                       'title' => 'Zzz',
-                                       'user' => 'TestRecentChangesUser',
-                                       'diff' => '',
-                                       'cur' => '',
-                                       'timestamp' => '21:21',
-                                       'numberofWatchingusers' => 0,
-                                       'unpatrolled' => false
-                               ],
-                               $this->getContext(),
-                               $this->getMessages(),
-                               $this->testRecentChangesHelper->makeDeletedEditRecentChange(
-                                       $this->getTestUser(),
-                                       'Zzz',
-                                       '20131103212153',
-                                       191, // thisid
-                                       190, // lastid
-                                       '20131103212153',
-                                       0, // counter
-                                       0 // number of watching users
-                               ),
-                               false
-                       ]
-               ];
-       }
-
        private function assertUserLinks( $user, $cacheEntry ) {
                $this->assertTag(
                        [
@@ -308,18 +243,8 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
                ];
        }
 
-       private function getTestUser() {
-               $user = User::newFromName( 'TestRecentChangesUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               return $user;
-       }
-
        private function getContext() {
-               $user = $this->getTestUser();
+               $user = $this->getMutableTestUser()->getUser();
                $context = $this->testRecentChangesHelper->getTestContext( $user );
 
                $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
index d4b1587..9bc41c0 100644 (file)
@@ -67,7 +67,8 @@ class BotPasswordSessionProviderTest extends MediaWikiTestCase {
                $passwordFactory->init( \RequestContext::getMain()->getConfig() );
                $passwordHash = $passwordFactory->newFromPlaintext( 'foobaz' );
 
-               $userId = \CentralIdLookup::factory( 'local' )->centralIdFromName( 'UTSysop' );
+               $sysop = static::getTestSysop()->getUser();
+               $userId = \CentralIdLookup::factory( 'local' )->centralIdFromName( $sysop->getName() );
 
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete(
@@ -182,7 +183,7 @@ class BotPasswordSessionProviderTest extends MediaWikiTestCase {
 
        public function testNewSessionInfoForRequest() {
                $provider = $this->getProvider();
-               $user = \User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $request = $this->getMock( 'FauxRequest', [ 'getIP' ] );
                $request->expects( $this->any() )->method( 'getIP' )
                        ->will( $this->returnValue( '127.0.0.1' ) );
@@ -209,7 +210,7 @@ class BotPasswordSessionProviderTest extends MediaWikiTestCase {
                $provider = $this->getProvider();
                $provider->setLogger( $logger );
 
-               $user = \User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $request = $this->getMock( 'FauxRequest', [ 'getIP' ] );
                $request->expects( $this->any() )->method( 'getIP' )
                        ->will( $this->returnValue( '127.0.0.1' ) );
index 9600184..b35b685 100644 (file)
@@ -165,7 +165,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                $provider->setConfig( $this->getConfig() );
                $provider->setManager( new SessionManager() );
 
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $id = $user->getId();
                $name = $user->getName();
                $token = $user->getToken( true );
@@ -390,7 +390,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
 
                $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
                $store = new TestBagOStuff();
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $anon = new User;
 
                $backend = new SessionBackend(
@@ -475,7 +475,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                $provider->setManager( SessionManager::singleton() );
 
                $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $this->assertFalse( $user->requiresHTTPS(), 'sanity check' );
 
                $backend = new SessionBackend(
@@ -577,7 +577,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
 
                $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
                $store = new TestBagOStuff();
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $anon = new User;
 
                $backend = new SessionBackend(
index 0b5f4c2..a3d5de7 100644 (file)
@@ -360,7 +360,7 @@ class SessionBackendTest extends MediaWikiTestCase {
        }
 
        public function testSetUser() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
 
                $this->provider = $this->getMock( 'DummySessionProvider', [ 'canChangeUser' ] );
                $this->provider->expects( $this->any() )->method( 'canChangeUser' )
@@ -484,7 +484,7 @@ class SessionBackendTest extends MediaWikiTestCase {
        }
 
        public function testSave() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $this->store = new TestBagOStuff();
                $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
 
@@ -733,7 +733,7 @@ class SessionBackendTest extends MediaWikiTestCase {
        }
 
        public function testRenew() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $this->store = new TestBagOStuff();
                $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
 
@@ -829,7 +829,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                        $handler->enable = true;
                }
 
-               $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
+               $backend = $this->getBackend( static::getTestSysop()->getUser() );
                \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
 
                $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
index 629c6e5..1ef5082 100644 (file)
@@ -7,6 +7,13 @@ use MediaWiki\Session\SessionManager;
  * @group Database
  */
 class BotPasswordTest extends MediaWikiTestCase {
+
+       /** @var TestUser */
+       private $testUser;
+
+       /** @var string */
+       private $testUserName;
+
        protected function setUp() {
                parent::setUp();
 
@@ -20,11 +27,14 @@ class BotPasswordTest extends MediaWikiTestCase {
                        'wgUserrightsInterwikiDelimiter' => '@',
                ] );
 
+               $this->testUser = $this->getMutableTestUser();
+               $this->testUserName = $this->testUser->getUser()->getName();
+
                $mock1 = $this->getMockForAbstractClass( 'CentralIdLookup' );
                $mock1->expects( $this->any() )->method( 'isAttached' )
                        ->will( $this->returnValue( true ) );
                $mock1->expects( $this->any() )->method( 'lookupUserNames' )
-                       ->will( $this->returnValue( [ 'UTSysop' => 42, 'UTDummy' => 43, 'UTInvalid' => 0 ] ) );
+                       ->will( $this->returnValue( [ $this->testUserName => 42, 'UTDummy' => 43, 'UTInvalid' => 0 ] ) );
                $mock1->expects( $this->never() )->method( 'lookupCentralIds' );
 
                $mock2 = $this->getMockForAbstractClass( 'CentralIdLookup' );
@@ -82,7 +92,7 @@ class BotPasswordTest extends MediaWikiTestCase {
        }
 
        public function testBasics() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = $this->testUser->getUser();
                $bp = BotPassword::newFromUser( $user, 'BotPassword' );
                $this->assertInstanceOf( 'BotPassword', $bp );
                $this->assertTrue( $bp->isSaved() );
@@ -107,7 +117,7 @@ class BotPasswordTest extends MediaWikiTestCase {
        }
 
        public function testUnsaved() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = $this->testUser->getUser();
                $bp = BotPassword::newUnsaved( [
                        'user' => $user,
                        'appId' => 'DoesNotExist'
@@ -132,7 +142,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                $this->assertEquals( '{"IPAddresses":["127.0.0.0/8"]}', $bp->getRestrictions()->toJson() );
                $this->assertSame( [ 'test' ], $bp->getGrants() );
 
-               $user = User::newFromName( 'UTSysop' );
+               $user = $this->testUser->getUser();
                $bp = BotPassword::newUnsaved( [
                        'centralId' => 45,
                        'appId' => 'DoesNotExist'
@@ -142,7 +152,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                $this->assertSame( 45, $bp->getUserCentralId() );
                $this->assertSame( 'DoesNotExist', $bp->getAppId() );
 
-               $user = User::newFromName( 'UTSysop' );
+               $user = $this->testUser->getUser();
                $bp = BotPassword::newUnsaved( [
                        'user' => $user,
                        'appId' => 'BotPassword'
@@ -159,7 +169,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                        'appId' => str_repeat( 'X', BotPassword::APPID_MAXLENGTH + 1 ),
                ] ) );
                $this->assertNull( BotPassword::newUnsaved( [
-                       'user' => 'UTSysop',
+                       'user' => $this->testUserName,
                        'appId' => 'Ok',
                ] ) );
                $this->assertNull( BotPassword::newUnsaved( [
@@ -200,7 +210,7 @@ class BotPasswordTest extends MediaWikiTestCase {
 
                $this->assertNotInstanceOf( 'InvalidPassword', $bp1->getPassword(), 'sanity check' );
                $this->assertNotInstanceOf( 'InvalidPassword', $bp2->getPassword(), 'sanity check' );
-               BotPassword::invalidateAllPasswordsForUser( 'UTSysop' );
+               BotPassword::invalidateAllPasswordsForUser( $this->testUserName );
                $this->assertInstanceOf( 'InvalidPassword', $bp1->getPassword() );
                $this->assertNotInstanceOf( 'InvalidPassword', $bp2->getPassword() );
 
@@ -212,7 +222,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                $this->assertNotNull( BotPassword::newFromCentralId( 42, 'BotPassword' ), 'sanity check' );
                $this->assertNotNull( BotPassword::newFromCentralId( 43, 'BotPassword' ), 'sanity check' );
 
-               BotPassword::removeAllPasswordsForUser( 'UTSysop' );
+               BotPassword::removeAllPasswordsForUser( $this->testUserName );
 
                $this->assertNull( BotPassword::newFromCentralId( 42, 'BotPassword' ) );
                $this->assertNotNull( BotPassword::newFromCentralId( 43, 'BotPassword' ) );
@@ -221,7 +231,7 @@ class BotPasswordTest extends MediaWikiTestCase {
        public function testLogin() {
                // Test failure when bot passwords aren't enabled
                $this->setMwGlobals( 'wgEnableBotPasswords', false );
-               $status = BotPassword::login( 'UTSysop@BotPassword', 'foobaz', new FauxRequest );
+               $status = BotPassword::login( "{$this->testUserName}@BotPassword", 'foobaz', new FauxRequest );
                $this->assertEquals( Status::newFatal( 'botpasswords-disabled' ), $status );
                $this->setMwGlobals( 'wgEnableBotPasswords', true );
 
@@ -235,7 +245,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                        $manager->getProvider( MediaWiki\Session\BotPasswordSessionProvider::class ),
                        'sanity check'
                );
-               $status = BotPassword::login( 'UTSysop@BotPassword', 'foobaz', new FauxRequest );
+               $status = BotPassword::login( "{$this->testUserName}@BotPassword", 'foobaz', new FauxRequest );
                $this->assertEquals( Status::newFatal( 'botpasswords-no-provider' ), $status );
                ScopedCallback::consume( $reset );
 
@@ -257,7 +267,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                $reset = MediaWiki\Session\TestUtils::setSessionManagerSingleton( $manager );
 
                // No "@"-thing in the username
-               $status = BotPassword::login( 'UTSysop', 'foobaz', new FauxRequest );
+               $status = BotPassword::login( $this->testUserName, 'foobaz', new FauxRequest );
                $this->assertEquals( Status::newFatal( 'botpasswords-invalid-name', '@' ), $status );
 
                // No base user
@@ -265,9 +275,9 @@ class BotPasswordTest extends MediaWikiTestCase {
                $this->assertEquals( Status::newFatal( 'nosuchuser', 'UTDummy' ), $status );
 
                // No bot password
-               $status = BotPassword::login( 'UTSysop@DoesNotExist', 'foobaz', new FauxRequest );
+               $status = BotPassword::login( "{$this->testUserName}@DoesNotExist", 'foobaz', new FauxRequest );
                $this->assertEquals(
-                       Status::newFatal( 'botpasswords-not-exist', 'UTSysop', 'DoesNotExist' ),
+                       Status::newFatal( 'botpasswords-not-exist', $this->testUserName, 'DoesNotExist' ),
                        $status
                );
 
@@ -275,11 +285,12 @@ class BotPasswordTest extends MediaWikiTestCase {
                $request = $this->getMock( 'FauxRequest', [ 'getIP' ] );
                $request->expects( $this->any() )->method( 'getIP' )
                        ->will( $this->returnValue( '10.0.0.1' ) );
-               $status = BotPassword::login( 'UTSysop@BotPassword', 'foobaz', $request );
+               $status = BotPassword::login( "{$this->testUserName}@BotPassword", 'foobaz', $request );
                $this->assertEquals( Status::newFatal( 'botpasswords-restriction-failed' ), $status );
 
                // Wrong password
-               $status = BotPassword::login( 'UTSysop@BotPassword', 'UTSysopPassword', new FauxRequest );
+               $status = BotPassword::login(
+                       "{$this->testUserName}@BotPassword", $this->testUser->password, new FauxRequest );
                $this->assertEquals( Status::newFatal( 'wrongpassword' ), $status );
 
                // Success!
@@ -289,7 +300,7 @@ class BotPasswordTest extends MediaWikiTestCase {
                        $request->getSession()->getProvider(),
                        'sanity check'
                );
-               $status = BotPassword::login( 'UTSysop@BotPassword', 'foobaz', $request );
+               $status = BotPassword::login( "{$this->testUserName}@BotPassword", 'foobaz', $request );
                $this->assertInstanceOf( 'Status', $status );
                $this->assertTrue( $status->isGood() );
                $session = $status->getValue();
index 1786261..feac641 100644 (file)
@@ -45,7 +45,7 @@ class CentralIdLookupTest extends MediaWikiTestCase {
                        $this->getMockForAbstractClass( 'CentralIdLookup' )
                );
 
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestSysop()->getUser();
                $this->assertSame( $user, $mock->checkAudience( $user ) );
 
                $user = $mock->checkAudience( CentralIdLookup::AUDIENCE_PUBLIC );
index c86fb6c..c91d8e0 100644 (file)
@@ -18,18 +18,14 @@ class LocalIdLookupTest extends MediaWikiTestCase {
 
        public function addDBData() {
                for ( $i = 1; $i <= 4; $i++ ) {
-                       $user = User::newFromName( "UTLocalIdLookup$i" );
-                       if ( $user->getId() == 0 ) {
-                               $user->addToDatabase();
-                       }
-                       $this->localUsers["UTLocalIdLookup$i"] = $user->getId();
+                       $this->localUsers[] = $this->getMutableTestUser()->getUser();
                }
 
-               User::newFromName( 'UTLocalIdLookup1' )->addGroup( 'local-id-lookup-test' );
+               $sysop = static::getTestSysop()->getUser();
 
                $block = new Block( [
-                       'address' => 'UTLocalIdLookup3',
-                       'by' => User::idFromName( 'UTSysop' ),
+                       'address' => $this->localUsers[2]->getName(),
+                       'by' => $sysop->getId(),
                        'reason' => __METHOD__,
                        'expiry' => '1 day',
                        'hideName' => false,
@@ -37,8 +33,8 @@ class LocalIdLookupTest extends MediaWikiTestCase {
                $block->insert();
 
                $block = new Block( [
-                       'address' => 'UTLocalIdLookup4',
-                       'by' => User::idFromName( 'UTSysop' ),
+                       'address' => $this->localUsers[3]->getName(),
+                       'by' => $sysop->getId(),
                        'reason' => __METHOD__,
                        'expiry' => '1 day',
                        'hideName' => true,
@@ -46,9 +42,14 @@ class LocalIdLookupTest extends MediaWikiTestCase {
                $block->insert();
        }
 
+       public function getLookupUser() {
+               return static::getTestUser( [ 'local-id-lookup-test' ] )->getUser();
+       }
+
        public function testLookupCentralIds() {
                $lookup = new LocalIdLookup();
-               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+
+               $user1 = $this->getLookupUser();
                $user2 = User::newFromName( 'UTLocalIdLookup2' );
 
                $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' );
@@ -56,12 +57,15 @@ class LocalIdLookupTest extends MediaWikiTestCase {
 
                $this->assertSame( [], $lookup->lookupCentralIds( [] ) );
 
-               $expect = array_flip( $this->localUsers );
-               $expect[123] = 'X';
+               $expect = [];
+               foreach ( $this->localUsers as $localUser ) {
+                       $expect[$localUser->getId()] = $localUser->getName();
+               }
+               $expect[12345] = 'X';
                ksort( $expect );
 
                $expect2 = $expect;
-               $expect2[$this->localUsers['UTLocalIdLookup4']] = '';
+               $expect2[$this->localUsers[3]->getId()] = '';
 
                $arg = array_fill_keys( array_keys( $expect ), 'X' );
 
@@ -73,7 +77,7 @@ class LocalIdLookupTest extends MediaWikiTestCase {
 
        public function testLookupUserNames() {
                $lookup = new LocalIdLookup();
-               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+               $user1 = $this->getLookupUser();
                $user2 = User::newFromName( 'UTLocalIdLookup2' );
 
                $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' );
@@ -81,12 +85,15 @@ class LocalIdLookupTest extends MediaWikiTestCase {
 
                $this->assertSame( [], $lookup->lookupUserNames( [] ) );
 
-               $expect = $this->localUsers;
+               $expect = [];
+               foreach ( $this->localUsers as $localUser ) {
+                       $expect[$localUser->getName()] = $localUser->getId();
+               }
                $expect['UTDoesNotExist'] = 'X';
                ksort( $expect );
 
                $expect2 = $expect;
-               $expect2['UTLocalIdLookup4'] = 'X';
+               $expect2[$this->localUsers[3]->getName()] = 'X';
 
                $arg = array_fill_keys( array_keys( $expect ), 'X' );
 
@@ -98,7 +105,7 @@ class LocalIdLookupTest extends MediaWikiTestCase {
 
        public function testIsAttached() {
                $lookup = new LocalIdLookup();
-               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+               $user1 = $this->getLookupUser();
                $user2 = User::newFromName( 'DoesNotExist' );
 
                $this->assertTrue( $lookup->isAttached( $user1 ) );
@@ -130,7 +137,7 @@ class LocalIdLookupTest extends MediaWikiTestCase {
                $lookup = new LocalIdLookup();
                $this->assertSame(
                        $sharedDB && $sharedTable && $localDBSet,
-                       $lookup->isAttached( User::newFromName( 'UTLocalIdLookup1' ), 'shared' )
+                       $lookup->isAttached( $this->getLookupUser(), 'shared' )
                );
        }
 
index c9b6929..801ab91 100644 (file)
@@ -213,11 +213,7 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::getEditCount
         */
        public function testEditCount() {
-               $user = User::newFromName( 'UnitTestUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
+               $user = $this->getMutableTestUser()->getUser();
 
                // let the user have a few (3) edits
                $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
@@ -249,17 +245,13 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::getOption
         */
        public function testOptions() {
-               $user = User::newFromName( 'UnitTestUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
+               $user = $this->getMutableTestUser()->getUser();
 
                $user->setOption( 'userjs-someoption', 'test' );
                $user->setOption( 'cols', 200 );
                $user->saveSettings();
 
-               $user = User::newFromName( 'UnitTestUser' );
+               $user = User::newFromName( $user->getName() );
                $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
                $this->assertEquals( 200, $user->getOption( 'cols' ) );
        }
@@ -298,7 +290,7 @@ class UserTest extends MediaWikiTestCase {
                                                'MinimalPasswordLength' => 6,
                                                'PasswordCannotMatchUsername' => true,
                                                'PasswordCannotMatchBlacklist' => true,
-                                               'MaximalPasswordLength' => 30,
+                                               'MaximalPasswordLength' => 40,
                                        ],
                                ],
                                'checks' => [
@@ -311,7 +303,8 @@ class UserTest extends MediaWikiTestCase {
                        ],
                ] );
 
-               $user = User::newFromName( 'Useruser' );
+               $user = static::getTestUser()->getUser();
+
                // Sanity
                $this->assertTrue( $user->isValidPassword( 'Password1234' ) );
 
@@ -322,18 +315,19 @@ class UserTest extends MediaWikiTestCase {
                $this->assertEquals( 'passwordtooshort', $user->getPasswordValidity( 'a' ) );
 
                // Maximum length
-               $longPass = str_repeat( 'a', 31 );
+               $longPass = str_repeat( 'a', 41 );
                $this->assertFalse( $user->isValidPassword( $longPass ) );
                $this->assertFalse( $user->checkPasswordValidity( $longPass )->isGood() );
                $this->assertFalse( $user->checkPasswordValidity( $longPass )->isOK() );
                $this->assertEquals( 'passwordtoolong', $user->getPasswordValidity( $longPass ) );
 
                // Matches username
-               $this->assertFalse( $user->checkPasswordValidity( 'Useruser' )->isGood() );
-               $this->assertTrue( $user->checkPasswordValidity( 'Useruser' )->isOK() );
-               $this->assertEquals( 'password-name-match', $user->getPasswordValidity( 'Useruser' ) );
+               $this->assertFalse( $user->checkPasswordValidity( $user->getName() )->isGood() );
+               $this->assertTrue( $user->checkPasswordValidity( $user->getName() )->isOK() );
+               $this->assertEquals( 'password-name-match', $user->getPasswordValidity( $user->getName() ) );
 
                // On the forbidden list
+               $user = User::newFromName( 'Useruser' );
                $this->assertFalse( $user->checkPasswordValidity( 'Passpass' )->isGood() );
                $this->assertEquals( 'password-login-forbidden', $user->getPasswordValidity( 'Passpass' ) );
        }
@@ -389,29 +383,23 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::equals
         */
        public function testEquals() {
-               $first = User::newFromName( 'EqualUser' );
-               $second = User::newFromName( 'EqualUser' );
+               $first = $this->getMutableTestUser()->getUser();
+               $second = User::newFromName( $first->getName() );
 
                $this->assertTrue( $first->equals( $first ) );
                $this->assertTrue( $first->equals( $second ) );
                $this->assertTrue( $second->equals( $first ) );
 
-               $third = User::newFromName( '0' );
-               $fourth = User::newFromName( '000' );
+               $third = $this->getMutableTestUser()->getUser();
+               $fourth = $this->getMutableTestUser()->getUser();
 
                $this->assertFalse( $third->equals( $fourth ) );
                $this->assertFalse( $fourth->equals( $third ) );
 
                // Test users loaded from db with id
-               $user = User::newFromName( 'EqualUnitTestUser' );
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               $id = $user->getId();
-
-               $fifth = User::newFromId( $id );
-               $sixth = User::newFromName( 'EqualUnitTestUser' );
+               $user = $this->getMutableTestUser()->getUser();
+               $fifth = User::newFromId( $user->getId() );
+               $sixth = User::newFromName( $user->getName() );
                $this->assertTrue( $fifth->equals( $sixth ) );
        }
 
@@ -419,7 +407,7 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::getId
         */
        public function testGetId() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = static::getTestUser()->getUser();
                $this->assertTrue( $user->getId() > 0 );
 
        }
@@ -429,7 +417,7 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::isAnon
         */
        public function testLoggedIn() {
-               $user = User::newFromName( 'UTSysop' );
+               $user = $this->getMutableTestUser()->getUser();
                $this->assertTrue( $user->isLoggedIn() );
                $this->assertFalse( $user->isAnon() );
 
@@ -447,7 +435,8 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::checkAndSetTouched
         */
        public function testCheckAndSetTouched() {
-               $user = TestingAccessWrapper::newFromObject( User::newFromName( 'UTSysop' ) );
+               $user = $this->getMutableTestUser()->getUser();
+               $user = TestingAccessWrapper::newFromObject( $user );
                $this->assertTrue( $user->isLoggedIn() );
 
                $touched = $user->getDBTouched();