Localisation updates from https://translatewiki.net.
[mediawiki.git] / tests / phpunit / maintenance / CreateAndPromoteTest.php
blob322aedc958584d26060e2a7cf466c64159ff4dfa
1 <?php
3 namespace MediaWiki\Tests\Maintenance;
5 use CreateAndPromote;
6 use MediaWiki\MainConfigNames;
7 use MediaWiki\Password\PasswordFactory;
8 use MediaWiki\SiteStats\SiteStats;
9 use MediaWiki\User\User;
11 /**
12 * @covers \CreateAndPromote
13 * @group Database
14 * @author Dreamy Jazz
16 class CreateAndPromoteTest extends MaintenanceBaseTestCase {
18 protected function getMaintenanceClass() {
19 return CreateAndPromote::class;
22 /** @dataProvider provideExecuteForExistingAccount */
23 public function testExecuteForExistingAccount(
24 $options, $expectedGroupsAfterCall, $expectedOutputRegex, $shouldCreateLogEntry
25 ) {
26 $testUser = $this->getMutableTestUser()->getUser();
27 // Set the user as the test user and use 'force' because we are not creating a user.
28 $this->maintenance->setArg( 'username', $testUser );
29 $this->maintenance->setOption( 'force', true );
30 // Add the options from $options
31 foreach ( $options as $option => $value ) {
32 $this->maintenance->setOption( $option, $value );
34 $this->maintenance->execute();
35 // Verify that the user is now in the expected groups
36 $this->assertArrayEquals(
37 $expectedGroupsAfterCall,
38 $this->getServiceContainer()->getUserGroupManager()->getUserGroups( $testUser )
40 $this->expectOutputRegex( $expectedOutputRegex );
41 // Verify that the log entry was created, if that is expected
42 $queryBuilder = $this->newSelectQueryBuilder()
43 ->field( 'COUNT(*)' )
44 ->from( 'logging' )
45 ->where( [
46 'log_actor' => $this->getServiceContainer()->getActorStore()
47 ->findActorIdByName( User::MAINTENANCE_SCRIPT_USER, $this->getDb() ),
48 'log_title' => $testUser->getUserPage()->getDBkey(),
49 'log_namespace' => NS_USER,
50 'log_comment_id' => $this->getServiceContainer()->getCommentStore()
51 ->createComment( $this->getDb(), $options['reason'] ?? '' )->id,
52 ] );
53 $this->assertSame( (int)$shouldCreateLogEntry, (int)$queryBuilder->fetchField() );
56 public static function provideExecuteForExistingAccount() {
57 return [
58 'Assigning no rights' => [ [], [], "/Account exists and nothing to do.\n/", false ],
59 'Assigning sysop with reason provided' => [
60 [ 'sysop' => 1, 'reason' => 'testing' ], [ 'sysop' ], "/Promoting .* into sysop...\ndone/", true
62 'Assigning bot' => [ [ 'bot' => 1 ], [ 'bot' ], "/Promoting .* into bot...\ndone/", true ],
63 'Assigning suppress, bureaucrat, and interface-admin' => [
64 [ 'custom-groups' => 'suppress', 'bureaucrat' => 1, 'interface-admin' => 1 ],
65 [ 'suppress', 'bureaucrat', 'interface-admin' ],
66 "/Promoting .* into bureaucrat, interface-admin, suppress...\ndone/",
67 true,
69 'Assigning unrecognised group' => [
70 [ 'custom-groups' => 'abctesting' ], [], "/Account exists and nothing to do.\n/", false,
75 public function testExecuteToSetPasswordForExistingUser() {
76 $password = PasswordFactory::generateRandomPasswordString( 128 );
77 $testUser = $this->getMutableTestUser()->getUser();
78 // Set the username as our existing test user and set the password option.
79 $this->maintenance->setArg( 'username', $testUser );
80 $this->maintenance->setArg( 'password', $password );
81 $this->maintenance->setOption( 'force', true );
82 $this->maintenance->execute();
83 $this->expectOutputRegex( '/Password set/' );
84 // Check that the password for the $testUser matches the password we set
85 $actualPasswordHash = $this->newSelectQueryBuilder()
86 ->select( 'user_password' )
87 ->from( 'user' )
88 ->where( [ 'user_name' => $testUser->getName() ] )
89 ->fetchField();
90 $this->assertTrue(
91 $this->getServiceContainer()->getPasswordFactory()
92 ->newFromCiphertext( $actualPasswordHash )->verify( $password )
96 public function testExecuteForInvalidUsername() {
97 // Call the maintenance script with a username that is more than wgMaxNameChars, and so shouldn't be valid.
98 $this->overrideConfigValue( MainConfigNames::MaxNameChars, 2 );
99 $this->expectCallToFatalError();
100 $this->expectOutputRegex( '/invalid username/' );
101 $this->maintenance->setArg( 'username', 'testing-username-1234' );
102 $this->maintenance->execute();
105 public function testExecuteWhenUserExistsButForceOptionNotProvided() {
106 $this->expectCallToFatalError();
107 $this->expectOutputRegex( '/Account exists.*--force/' );
108 $this->maintenance->setArg( 'username', $this->getTestUser()->getUserIdentity()->getName() );
109 $this->maintenance->execute();
112 public function testExecuteWhenUserDoesNotExistAndNoPasswordSpecified() {
113 $this->expectCallToFatalError();
114 $this->expectOutputRegex( '/Argument <password> required/' );
115 $this->maintenance->setName( 'createAndPromote.php' );
116 $this->maintenance->setArg( 'username', 'NonExistingTestUser1234' );
117 $this->maintenance->execute();
120 public function testExecuteForNewAccountButPasswordDoesNotMeetRequirements() {
121 $this->maintenance->setArg( 'username', 'NewTestUser1234' );
122 // Use a very commonly used password "abc" and check that it rejects this
123 $this->maintenance->setArg( 'password', 'abc' );
124 $this->expectCallToFatalError();
125 $this->expectOutputRegex( '/password entered is in a list of very commonly used passwords/' );
126 $this->maintenance->execute();
129 public function testExecuteForNewAccountWhenReadOnly() {
130 $this->getServiceContainer()->getReadOnlyMode()->setReason( 'test' );
131 $this->maintenance->setArg( 'username', 'NewTestUser1234' );
132 $this->maintenance->setArg( 'password', PasswordFactory::generateRandomPasswordString( 128 ) );
133 $this->expectCallToFatalError();
134 // Assert that the "readonlytext" message is displayed.
135 $this->expectOutputRegex( '/database is currently locked/' );
136 $this->maintenance->execute();
139 public function testExecuteForNewAccount() {
140 $this->assertSame( 0, SiteStats::users() );
141 $password = PasswordFactory::generateRandomPasswordString( 128 );
142 // Run the maintenance script
143 $this->maintenance->setArg( 'username', 'NewTestUser1234' );
144 $this->maintenance->setArg( 'password', $password );
145 $this->maintenance->setOption( 'sysop', 1 );
146 $this->maintenance->execute();
147 $this->expectOutputRegex( '/Creating and promoting User:NewTestUser1234[\s\S]*done/' );
148 // Check that the new user exists and that the password matches
149 $actualPasswordHash = $this->newSelectQueryBuilder()
150 ->select( 'user_password' )
151 ->from( 'user' )
152 ->where( [ 'user_name' => 'NewTestUser1234' ] )
153 ->fetchField();
154 $this->assertTrue(
155 $this->getServiceContainer()->getPasswordFactory()
156 ->newFromCiphertext( $actualPasswordHash )->verify( $password )
158 // Check that the number of users has increased to 2, one for the new user and the other for the maintenance
159 // script user.
160 $this->assertSame( 2, SiteStats::users() );