Merge "Add action=query&meta=languageinfo API module"
[lhc/web/wiklou.git] / tests / phpunit / includes / user / PasswordResetTest.php
1 <?php
2
3 use MediaWiki\Auth\AuthManager;
4 use MediaWiki\Block\DatabaseBlock;
5 use MediaWiki\Block\SystemBlock;
6
7 /**
8 * @covers PasswordReset
9 * @group Database
10 */
11 class PasswordResetTest extends MediaWikiTestCase {
12 /**
13 * @dataProvider provideIsAllowed
14 */
15 public function testIsAllowed( $passwordResetRoutes, $enableEmail,
16 $allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
17 ) {
18 $config = new HashConfig( [
19 'PasswordResetRoutes' => $passwordResetRoutes,
20 'EnableEmail' => $enableEmail,
21 ] );
22
23 $authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
24 ->getMock();
25 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
26 ->willReturn( $allowsAuthenticationDataChange ? Status::newGood() : Status::newFatal( 'foo' ) );
27
28 $user = $this->getMockBuilder( User::class )->getMock();
29 $user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' );
30 $user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block );
31 $user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock );
32 $user->expects( $this->any() )->method( 'isAllowed' )
33 ->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) {
34 if ( $perm === 'editmyprivateinfo' ) {
35 return $canEditPrivate;
36 } else {
37 $this->fail( 'Unexpected permission check' );
38 }
39 } ) );
40
41 $passwordReset = new PasswordReset( $config, $authManager );
42
43 $this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
44 }
45
46 public function provideIsAllowed() {
47 return [
48 'no routes' => [
49 'passwordResetRoutes' => [],
50 'enableEmail' => true,
51 'allowsAuthenticationDataChange' => true,
52 'canEditPrivate' => true,
53 'block' => null,
54 'globalBlock' => null,
55 'isAllowed' => false,
56 ],
57 'email disabled' => [
58 'passwordResetRoutes' => [ 'username' => true ],
59 'enableEmail' => false,
60 'allowsAuthenticationDataChange' => true,
61 'canEditPrivate' => true,
62 'block' => null,
63 'globalBlock' => null,
64 'isAllowed' => false,
65 ],
66 'auth data change disabled' => [
67 'passwordResetRoutes' => [ 'username' => true ],
68 'enableEmail' => true,
69 'allowsAuthenticationDataChange' => false,
70 'canEditPrivate' => true,
71 'block' => null,
72 'globalBlock' => null,
73 'isAllowed' => false,
74 ],
75 'cannot edit private data' => [
76 'passwordResetRoutes' => [ 'username' => true ],
77 'enableEmail' => true,
78 'allowsAuthenticationDataChange' => true,
79 'canEditPrivate' => false,
80 'block' => null,
81 'globalBlock' => null,
82 'isAllowed' => false,
83 ],
84 'blocked with account creation disabled' => [
85 'passwordResetRoutes' => [ 'username' => true ],
86 'enableEmail' => true,
87 'allowsAuthenticationDataChange' => true,
88 'canEditPrivate' => true,
89 'block' => new DatabaseBlock( [ 'createAccount' => true ] ),
90 'globalBlock' => null,
91 'isAllowed' => false,
92 ],
93 'blocked w/o account creation disabled' => [
94 'passwordResetRoutes' => [ 'username' => true ],
95 'enableEmail' => true,
96 'allowsAuthenticationDataChange' => true,
97 'canEditPrivate' => true,
98 'block' => new DatabaseBlock( [] ),
99 'globalBlock' => null,
100 'isAllowed' => true,
101 ],
102 'using blocked proxy' => [
103 'passwordResetRoutes' => [ 'username' => true ],
104 'enableEmail' => true,
105 'allowsAuthenticationDataChange' => true,
106 'canEditPrivate' => true,
107 'block' => new SystemBlock(
108 [ 'systemBlock' => 'proxy' ]
109 ),
110 'globalBlock' => null,
111 'isAllowed' => false,
112 ],
113 'globally blocked with account creation not disabled' => [
114 'passwordResetRoutes' => [ 'username' => true ],
115 'enableEmail' => true,
116 'allowsAuthenticationDataChange' => true,
117 'canEditPrivate' => true,
118 'block' => null,
119 'globalBlock' => new SystemBlock(
120 [ 'systemBlock' => 'global-block' ]
121 ),
122 'isAllowed' => true,
123 ],
124 'blocked via wgSoftBlockRanges' => [
125 'passwordResetRoutes' => [ 'username' => true ],
126 'enableEmail' => true,
127 'allowsAuthenticationDataChange' => true,
128 'canEditPrivate' => true,
129 'block' => new SystemBlock(
130 [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ]
131 ),
132 'globalBlock' => null,
133 'isAllowed' => true,
134 ],
135 'blocked with an unknown system block type' => [
136 'passwordResetRoutes' => [ 'username' => true ],
137 'enableEmail' => true,
138 'allowsAuthenticationDataChange' => true,
139 'canEditPrivate' => true,
140 'block' => new SystemBlock( [ 'systemBlock' => 'unknown' ] ),
141 'globalBlock' => null,
142 'isAllowed' => false,
143 ],
144 'all OK' => [
145 'passwordResetRoutes' => [ 'username' => true ],
146 'enableEmail' => true,
147 'allowsAuthenticationDataChange' => true,
148 'canEditPrivate' => true,
149 'block' => null,
150 'globalBlock' => null,
151 'isAllowed' => true,
152 ],
153 ];
154 }
155
156 public function testExecute_email() {
157 $config = new HashConfig( [
158 'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
159 'EnableEmail' => true,
160 ] );
161
162 // Unregister the hooks for proper unit testing
163 $this->mergeMwGlobalArrayValue( 'wgHooks', [
164 'User::mailPasswordInternal' => [],
165 'SpecialPasswordResetOnSubmit' => [],
166 ] );
167
168 $authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
169 ->getMock();
170 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
171 ->willReturn( Status::newGood() );
172 $authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
173
174 $request = new FauxRequest();
175 $request->setIP( '1.2.3.4' );
176 $performingUser = $this->getMockBuilder( User::class )->getMock();
177 $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
178 $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
179 $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
180
181 $targetUser1 = $this->getMockBuilder( User::class )->getMock();
182 $targetUser2 = $this->getMockBuilder( User::class )->getMock();
183 $targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' );
184 $targetUser2->expects( $this->any() )->method( 'getName' )->willReturn( 'User2' );
185 $targetUser1->expects( $this->any() )->method( 'getId' )->willReturn( 1 );
186 $targetUser2->expects( $this->any() )->method( 'getId' )->willReturn( 2 );
187 $targetUser1->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
188 $targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
189
190 $passwordReset = $this->getMockBuilder( PasswordReset::class )
191 ->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] )
192 ->getMock();
193 $passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
194 ->willReturn( [ $targetUser1, $targetUser2 ] );
195
196 $status = $passwordReset->isAllowed( $performingUser );
197 $this->assertTrue( $status->isGood() );
198
199 $status = $passwordReset->execute( $performingUser, null, 'foo@bar.baz' );
200 $this->assertTrue( $status->isGood() );
201 }
202 }