3 use MediaWiki\MainConfigNames
;
4 use MediaWiki\Tests\Maintenance\MaintenanceBaseTestCase
;
5 use Wikimedia\Timestamp\ConvertibleTimestamp
;
8 * @covers \ResetUserEmail
12 class ResetUserEmailTest
extends MaintenanceBaseTestCase
{
13 public function getMaintenanceClass() {
14 return ResetUserEmail
::class;
17 private function commonTestEmailReset( $userArg, $options, $userName, $oldEmail ) {
18 ConvertibleTimestamp
::setFakeTime( '20240506070809' );
19 // Execute the maintenance script
20 $this->maintenance
->loadWithArgv( [ $userArg, 'new@mediawiki.test' ] );
21 foreach ( $options as $name => $value ) {
22 $this->maintenance
->setOption( $name, $value );
24 $this->maintenance
->execute();
26 // Check that the email address was changed and invalidated
27 $userFactory = $this->getServiceContainer()->getUserFactory();
28 $testUserAfterExecution = $userFactory->newFromName( $userName );
29 $this->assertNotEquals( $oldEmail, $testUserAfterExecution->getEmail() );
30 $this->assertSame( 'new@mediawiki.test', $testUserAfterExecution->getEmail() );
33 $testUserAfterExecution->getEmailAuthenticationTimestamp()
36 // Check that the script returns the right output
37 $this->expectOutputRegex( '/Done!/' );
40 public function testEmailResetWithNoPasswordResetWhenProvidingName() {
41 // Target an existing user with an email attached
42 $testUserBeforeExecution = $this->getTestSysop()->getUser();
43 $oldEmail = $testUserBeforeExecution->getEmail();
44 $this->assertNotNull( $oldEmail );
45 // Test providing the maintenance script with a username.
46 $this->commonTestEmailReset(
47 $testUserBeforeExecution->getName(), [ 'no-reset-password' => 1 ], $testUserBeforeExecution->getName(),
52 public function testEmailResetWithNoPasswordResetWhenProvidingId() {
53 // Target an existing user with an email attached
54 $testUserBeforeExecution = $this->getTestSysop()->getUser();
55 $oldEmail = $testUserBeforeExecution->getEmail();
56 $this->assertNotNull( $oldEmail );
57 $passwordHashBeforeExecution = $this->newSelectQueryBuilder()
58 ->select( 'user_password' )
60 ->where( [ 'user_id' => $testUserBeforeExecution->getId() ] )
62 // Test providing the maintenance script with a user ID.
63 $this->commonTestEmailReset(
64 "#" . $testUserBeforeExecution->getId(), [ 'no-reset-password' => 1 ],
65 $testUserBeforeExecution->getName(), $oldEmail
67 // Check that the password hash for the user has not changed
68 $passwordAfterExecution = $this->newSelectQueryBuilder()
69 ->select( 'user_password' )
71 ->where( [ 'user_id' => $testUserBeforeExecution->getId() ] )
73 $this->assertSame( $passwordHashBeforeExecution, $passwordAfterExecution );
76 public function testEmailReset() {
77 // Target an existing user with an email attached
78 $testUserBeforeExecution = $this->getTestSysop()->getUser();
79 $oldEmail = $testUserBeforeExecution->getEmail();
80 $this->assertNotNull( $oldEmail );
81 $passwordHashBeforeExecution = $this->newSelectQueryBuilder()
82 ->select( 'user_password' )
84 ->where( [ 'user_id' => $testUserBeforeExecution->getId() ] )
86 // Test providing the maintenance script with a user ID.
87 $this->commonTestEmailReset(
88 "#" . $testUserBeforeExecution->getId(), [],
89 $testUserBeforeExecution->getName(), $oldEmail
91 // Check that the password hash for the user has changed
92 $passwordAfterExecution = $this->newSelectQueryBuilder()
93 ->select( 'user_password' )
95 ->where( [ 'user_id' => $testUserBeforeExecution->getId() ] )
97 $this->assertNotSame( $passwordHashBeforeExecution, $passwordAfterExecution );
100 public function testEmailResetWithNoPasswordResetAndEmailPasswordOnFailure() {
101 $this->overrideConfigValue( MainConfigNames
::EnableEmail
, true );
102 // Abort all password reset submissions for the test
103 $this->setTemporaryHook( 'SpecialPasswordResetOnSubmit', static function ( $users, $data, &$error ) {
107 // Target an existing user with an email attached
108 $testUserBeforeExecution = $this->getTestSysop()->getUser();
109 $oldEmail = $testUserBeforeExecution->getEmail();
110 $this->assertNotNull( $oldEmail );
111 // Test providing the maintenance script with a username.
112 $this->commonTestEmailReset(
113 $testUserBeforeExecution->getName(), [ 'no-reset-password' => 1, 'email-password' => 1 ],
114 $testUserBeforeExecution->getName(),
117 $this->expectOutputRegex( "/Email couldn't be sent because[\s\S]*Done/" );
120 public function testEmailResetOnInvalidNewEmail() {
121 $this->expectCallToFatalError();
122 $this->expectOutputRegex( "/testemail.*is not valid/" );
123 // Execute the maintenance script
124 $this->maintenance
->setArg( 0, $this->getTestUser()->getUserIdentity()->getName() );
125 $this->maintenance
->setArg( 1, 'testemail' );
126 $this->maintenance
->execute();
129 public function testEmailResetOnInvalidUsername() {
130 $this->expectCallToFatalError();
131 $this->expectOutputRegex( "/Non-existent-test-user.*does not exist/" );
132 // Execute the maintenance script
133 $this->maintenance
->setArg( 0, 'Non-existent-test-user' );
134 $this->maintenance
->setArg( 1, 'new@mediawiki.test' );
135 $this->maintenance
->execute();