3 namespace MediaWiki\Tests\Auth
;
5 use MediaWiki\Auth\AuthenticationRequest
;
6 use MediaWiki\Auth\AuthenticationResponse
;
7 use MediaWiki\Auth\AuthManager
;
8 use MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider
;
9 use MediaWiki\Config\HashConfig
;
10 use MediaWiki\MainConfigNames
;
11 use MediaWiki\Request\FauxRequest
;
12 use MediaWiki\Status\Status
;
13 use MediaWiki\Tests\Unit\Auth\AuthenticationProviderTestTrait
;
14 use MediaWiki\Tests\Unit\DummyServicesTrait
;
15 use MediaWiki\User\User
;
16 use MediaWiki\User\UserNameUtils
;
17 use MediaWikiIntegrationTestCase
;
18 use Psr\Log\LoggerInterface
;
19 use Wikimedia\TestingAccessWrapper
;
22 * @covers \MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider
25 class EmailNotificationSecondaryAuthenticationProviderTest
extends MediaWikiIntegrationTestCase
{
26 use AuthenticationProviderTestTrait
;
27 use DummyServicesTrait
;
30 * @param array $options
31 * @return EmailNotificationSecondaryAuthenticationProvider
33 private function getProvider( array $options = [] ): EmailNotificationSecondaryAuthenticationProvider
{
34 $services = $this->getServiceContainer();
35 $provider = new EmailNotificationSecondaryAuthenticationProvider(
36 $options['dbProvider'] ??
$services->getConnectionProvider(),
37 $options // make things easier for tests by using the same options
41 $options['config'] ??
null,
42 $options['logger'] ??
null,
43 $options['authManager'] ??
null,
44 $options['hookContainer'] ??
null,
45 $options['userNameUtils'] ??
null
50 public function testConstructor() {
51 $config = new HashConfig( [
52 MainConfigNames
::EnableEmail
=> true,
53 MainConfigNames
::EmailAuthentication
=> true,
56 $provider = $this->getProvider( [
59 $providerPriv = TestingAccessWrapper
::newFromObject( $provider );
60 $this->assertTrue( $providerPriv->sendConfirmationEmail
);
62 $provider = $this->getProvider( [
64 'sendConfirmationEmail' => false,
66 $providerPriv = TestingAccessWrapper
::newFromObject( $provider );
67 $this->assertFalse( $providerPriv->sendConfirmationEmail
);
71 * @dataProvider provideGetAuthenticationRequests
72 * @param string $action
73 * @param AuthenticationRequest[] $expected
75 public function testGetAuthenticationRequests( $action, $expected ) {
76 $provider = $this->getProvider( [
77 'sendConfirmationEmail' => true,
79 $this->assertSame( $expected, $provider->getAuthenticationRequests( $action, [] ) );
82 public static function provideGetAuthenticationRequests() {
84 [ AuthManager
::ACTION_LOGIN
, [] ],
85 [ AuthManager
::ACTION_CREATE
, [] ],
86 [ AuthManager
::ACTION_LINK
, [] ],
87 [ AuthManager
::ACTION_CHANGE
, [] ],
88 [ AuthManager
::ACTION_REMOVE
, [] ],
92 public function testBeginSecondaryAuthentication() {
93 $provider = $this->getProvider( [
94 'sendConfirmationEmail' => true,
96 $this->assertEquals( AuthenticationResponse
::newAbstain(),
97 $provider->beginSecondaryAuthentication( User
::newFromName( 'Foo' ), [] ) );
100 public function testBeginSecondaryAccountCreation() {
101 $mwServices = $this->getServiceContainer();
102 $hookContainer = $this->createHookContainer();
103 $userNameUtils = $this->createNoOpMock( UserNameUtils
::class );
104 $authManager = new AuthManager(
107 $this->getDummyObjectFactory(),
109 $mwServices->getReadOnlyMode(),
111 $mwServices->getBlockManager(),
112 $mwServices->getWatchlistManager(),
113 $mwServices->getDBLoadBalancer(),
114 $mwServices->getContentLanguage(),
115 $mwServices->getLanguageConverterFactory(),
116 $mwServices->getBotPasswordStore(),
117 $mwServices->getUserFactory(),
118 $mwServices->getUserIdentityLookup(),
119 $mwServices->getUserOptionsManager()
122 $creator = $this->createMock( User
::class );
123 $userWithoutEmail = $this->createMock( User
::class );
124 $userWithoutEmail->method( 'getEmail' )->willReturn( '' );
125 $userWithoutEmail->method( 'getInstanceForUpdate' )->willReturnSelf();
126 $userWithoutEmail->expects( $this->never() )->method( 'sendConfirmationMail' );
127 $userWithEmailError = $this->createMock( User
::class );
128 $userWithEmailError->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
129 $userWithEmailError->method( 'getInstanceForUpdate' )->willReturnSelf();
130 $userWithEmailError->method( 'sendConfirmationMail' )
131 ->willReturn( Status
::newFatal( 'fail' ) );
132 $userExpectsConfirmation = $this->createMock( User
::class );
133 $userExpectsConfirmation->method( 'getEmail' )
134 ->willReturn( 'foo@bar.baz' );
135 $userExpectsConfirmation->method( 'getInstanceForUpdate' )
137 $userExpectsConfirmation->expects( $this->once() )->method( 'sendConfirmationMail' )
138 ->willReturn( Status
::newGood() );
139 $userNotExpectsConfirmation = $this->createMock( User
::class );
140 $userNotExpectsConfirmation->method( 'getEmail' )
141 ->willReturn( 'foo@bar.baz' );
142 $userNotExpectsConfirmation->method( 'getInstanceForUpdate' )
144 $userNotExpectsConfirmation->expects( $this->never() )->method( 'sendConfirmationMail' );
146 $provider = $this->getProvider( [
147 'sendConfirmationEmail' => false,
148 'authManager' => $authManager,
149 'hookContainer' => $hookContainer,
150 'userNameUtils' => $userNameUtils
152 $provider->beginSecondaryAccountCreation( $userNotExpectsConfirmation, $creator, [] );
154 $provider = $this->getProvider( [
155 'sendConfirmationEmail' => true,
156 'authManager' => $authManager,
157 'userNameUtils' => $userNameUtils
159 $provider->beginSecondaryAccountCreation( $userWithoutEmail, $creator, [] );
160 $provider->beginSecondaryAccountCreation( $userExpectsConfirmation, $creator, [] );
162 // test logging of email errors
163 $logger = $this->getMockForAbstractClass( LoggerInterface
::class );
164 $logger->expects( $this->once() )->method( 'warning' );
165 $this->initProvider( $provider, null, $logger, $authManager );
166 $provider->beginSecondaryAccountCreation( $userWithEmailError, $creator, [] );
168 // test disable flag used by other providers
169 $authManager->setAuthenticationSessionData( 'no-email', true );
170 $this->initProvider( $provider, null, null, $authManager );
171 $provider->beginSecondaryAccountCreation( $userNotExpectsConfirmation, $creator, [] );