3 namespace MediaWiki\Tests\Auth
;
5 use BadMethodCallException
;
6 use MediaWiki\Auth\AbstractPrimaryAuthenticationProvider
;
7 use MediaWiki\Auth\AuthenticationRequest
;
8 use MediaWiki\Auth\AuthenticationResponse
;
9 use MediaWiki\Auth\AuthManager
;
10 use MediaWiki\Auth\PrimaryAuthenticationProvider
;
11 use MediaWiki\Tests\Unit\Auth\AuthenticationProviderTestTrait
;
12 use MediaWiki\Tests\Unit\DummyServicesTrait
;
13 use MediaWiki\User\User
;
14 use MediaWikiIntegrationTestCase
;
19 * @covers \MediaWiki\Auth\AbstractPrimaryAuthenticationProvider
21 class AbstractPrimaryAuthenticationProviderTest
extends MediaWikiIntegrationTestCase
{
22 use DummyServicesTrait
;
23 use AuthenticationProviderTestTrait
;
25 public function testAbstractPrimaryAuthenticationProvider() {
26 $user = $this->createMock( User
::class );
28 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider
::class );
31 $provider->continuePrimaryAuthentication( [] );
32 $this->fail( 'Expected exception not thrown' );
33 } catch ( BadMethodCallException
$ex ) {
37 $provider->continuePrimaryAccountCreation( $user, $user, [] );
38 $this->fail( 'Expected exception not thrown' );
39 } catch ( BadMethodCallException
$ex ) {
42 $this->assertTrue( $provider->providerAllowsPropertyChange( 'foo' ) );
44 StatusValue
::newGood(),
45 $provider->testForAccountCreation( $user, $user, [] )
48 StatusValue
::newGood(),
49 $provider->testUserForCreation( $user, AuthManager
::AUTOCREATE_SOURCE_SESSION
)
52 StatusValue
::newGood(),
53 $provider->testUserForCreation( $user, false )
57 $provider->finishAccountCreation( $user, $user, AuthenticationResponse
::newPass() )
59 $provider->autoCreatedAccount( $user, AuthManager
::AUTOCREATE_SOURCE_SESSION
);
61 $res = AuthenticationResponse
::newPass();
62 $provider->postAuthentication( $user, $res );
63 $provider->postAccountCreation( $user, $user, $res );
64 $provider->postAccountLink( $user, $res );
66 $provider->expects( $this->once() )
67 ->method( 'testUserExists' )
70 $this->assertTrue( $provider->testUserCanAuthenticate( 'foo' ) );
73 public function testProviderRevokeAccessForUser() {
75 for ( $i = 0; $i < 3; $i++
) {
76 $reqs[$i] = $this->createMock( AuthenticationRequest
::class );
78 $username = 'TestProviderRevokeAccessForUser';
80 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider
::class );
81 $provider->expects( $this->once() )->method( 'getAuthenticationRequests' )
83 $this->identicalTo( AuthManager
::ACTION_REMOVE
),
84 $this->identicalTo( [ 'username' => $username ] )
86 ->willReturn( $reqs );
87 $provider->expects( $this->exactly( 3 ) )->method( 'providerChangeAuthenticationData' )
88 ->willReturnCallback( function ( $req ) use ( $username ) {
89 $this->assertSame( $username, $req->username
);
92 $provider->providerRevokeAccessForUser( $username );
94 foreach ( $reqs as $i => $req ) {
95 $this->assertNotNull( $req->username
, "#$i" );
100 * @dataProvider providePrimaryAccountLink
101 * @param string $type PrimaryAuthenticationProvider::TYPE_* constant
102 * @param string $msg Error message from beginPrimaryAccountLink
104 public function testPrimaryAccountLink( $type, $msg ) {
105 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider
::class );
106 $provider->method( 'accountCreationType' )
107 ->willReturn( $type );
109 $class = AbstractPrimaryAuthenticationProvider
::class;
110 $msg1 = "{$class}::beginPrimaryAccountLink $msg";
111 $msg2 = "{$class}::continuePrimaryAccountLink is not implemented.";
113 $user = User
::newFromName( 'Whatever' );
116 $provider->beginPrimaryAccountLink( $user, [] );
117 $this->fail( 'Expected exception not thrown' );
118 } catch ( BadMethodCallException
$ex ) {
119 $this->assertSame( $msg1, $ex->getMessage() );
122 $provider->continuePrimaryAccountLink( $user, [] );
123 $this->fail( 'Expected exception not thrown' );
124 } catch ( BadMethodCallException
$ex ) {
125 $this->assertSame( $msg2, $ex->getMessage() );
129 public static function providePrimaryAccountLink() {
132 PrimaryAuthenticationProvider
::TYPE_NONE
,
133 'should not be called on a non-link provider.',
136 PrimaryAuthenticationProvider
::TYPE_CREATE
,
137 'should not be called on a non-link provider.',
140 PrimaryAuthenticationProvider
::TYPE_LINK
,
141 'is not implemented.',
147 * @dataProvider provideProviderNormalizeUsername
149 public function testProviderNormalizeUsername( $name, $expect ) {
150 // fake interwiki map for the 'Interwiki prefix' testcase
151 $interwikiLookup = $this->getDummyInterwikiLookup( [ 'interwiki' ] );
152 $this->setService( 'InterwikiLookup', $interwikiLookup );
154 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider
::class );
155 $this->initProvider( $provider, null, null, null, null, $this->getServiceContainer()->getUserNameUtils() );
156 $this->assertSame( $expect, $provider->providerNormalizeUsername( $name ) );
159 public static function provideProviderNormalizeUsername() {
161 'Leading space' => [ ' Leading space', 'Leading space' ],
162 'Trailing space ' => [ 'Trailing space ', 'Trailing space' ],
163 'Namespace prefix' => [ 'Talk:Username', null ],
164 'Interwiki prefix' => [ 'interwiki:Username', null ],
165 'With hash' => [ 'name with # hash', null ],
166 'Multi spaces' => [ 'Multi spaces', 'Multi spaces' ],
167 'Lowercase' => [ 'lowercase', 'Lowercase' ],
168 'Invalid character' => [ 'in[]valid', null ],
169 'With slash' => [ 'with / slash', null ],
170 'Underscores' => [ '___under__scores___', 'Under scores' ],