Merge "Update docs/hooks.txt for ShowSearchHitTitle"
[mediawiki.git] / tests / phpunit / includes / auth / AbstractPrimaryAuthenticationProviderTest.php
blobd8588d51d1bb74c155016c4aba89fd9127e810ed
1 <?php
3 namespace MediaWiki\Auth;
5 /**
6 * @group AuthManager
7 * @covers MediaWiki\Auth\AbstractPrimaryAuthenticationProvider
8 */
9 class AbstractPrimaryAuthenticationProviderTest extends \MediaWikiTestCase {
10 public function testAbstractPrimaryAuthenticationProvider() {
11 $user = \User::newFromName( 'UTSysop' );
13 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider::class );
15 try {
16 $provider->continuePrimaryAuthentication( [] );
17 $this->fail( 'Expected exception not thrown' );
18 } catch ( \BadMethodCallException $ex ) {
21 try {
22 $provider->continuePrimaryAccountCreation( $user, $user, [] );
23 $this->fail( 'Expected exception not thrown' );
24 } catch ( \BadMethodCallException $ex ) {
27 $req = $this->getMockForAbstractClass( AuthenticationRequest::class );
29 $this->assertTrue( $provider->providerAllowsPropertyChange( 'foo' ) );
30 $this->assertEquals(
31 \StatusValue::newGood(),
32 $provider->testForAccountCreation( $user, $user, [] )
34 $this->assertEquals(
35 \StatusValue::newGood(),
36 $provider->testUserForCreation( $user, AuthManager::AUTOCREATE_SOURCE_SESSION )
38 $this->assertEquals(
39 \StatusValue::newGood(),
40 $provider->testUserForCreation( $user, false )
43 $this->assertNull(
44 $provider->finishAccountCreation( $user, $user, AuthenticationResponse::newPass() )
46 $provider->autoCreatedAccount( $user, AuthManager::AUTOCREATE_SOURCE_SESSION );
48 $res = AuthenticationResponse::newPass();
49 $provider->postAuthentication( $user, $res );
50 $provider->postAccountCreation( $user, $user, $res );
51 $provider->postAccountLink( $user, $res );
53 $provider->expects( $this->once() )
54 ->method( 'testUserExists' )
55 ->with( $this->equalTo( 'foo' ) )
56 ->will( $this->returnValue( true ) );
57 $this->assertTrue( $provider->testUserCanAuthenticate( 'foo' ) );
60 public function testProviderRevokeAccessForUser() {
61 $reqs = [];
62 for ( $i = 0; $i < 3; $i++ ) {
63 $reqs[$i] = $this->getMock( AuthenticationRequest::class );
64 $reqs[$i]->done = false;
67 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider::class );
68 $provider->expects( $this->once() )->method( 'getAuthenticationRequests' )
69 ->with(
70 $this->identicalTo( AuthManager::ACTION_REMOVE ),
71 $this->identicalTo( [ 'username' => 'UTSysop' ] )
73 ->will( $this->returnValue( $reqs ) );
74 $provider->expects( $this->exactly( 3 ) )->method( 'providerChangeAuthenticationData' )
75 ->will( $this->returnCallback( function ( $req ) {
76 $this->assertSame( 'UTSysop', $req->username );
77 $this->assertFalse( $req->done );
78 $req->done = true;
79 } ) );
81 $provider->providerRevokeAccessForUser( 'UTSysop' );
83 foreach ( $reqs as $i => $req ) {
84 $this->assertTrue( $req->done, "#$i" );
88 /**
89 * @dataProvider providePrimaryAccountLink
90 * @param string $type PrimaryAuthenticationProvider::TYPE_* constant
91 * @param string $msg Error message from beginPrimaryAccountLink
93 public function testPrimaryAccountLink( $type, $msg ) {
94 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider::class );
95 $provider->expects( $this->any() )->method( 'accountCreationType' )
96 ->will( $this->returnValue( $type ) );
98 $class = AbstractPrimaryAuthenticationProvider::class;
99 $msg1 = "{$class}::beginPrimaryAccountLink $msg";
100 $msg2 = "{$class}::continuePrimaryAccountLink is not implemented.";
102 $user = \User::newFromName( 'Whatever' );
104 try {
105 $provider->beginPrimaryAccountLink( $user, [] );
106 $this->fail( 'Expected exception not thrown' );
107 } catch ( \BadMethodCallException $ex ) {
108 $this->assertSame( $msg1, $ex->getMessage() );
110 try {
111 $provider->continuePrimaryAccountLink( $user, [] );
112 $this->fail( 'Expected exception not thrown' );
113 } catch ( \BadMethodCallException $ex ) {
114 $this->assertSame( $msg2, $ex->getMessage() );
118 public static function providePrimaryAccountLink() {
119 return [
121 PrimaryAuthenticationProvider::TYPE_NONE,
122 'should not be called on a non-link provider.',
125 PrimaryAuthenticationProvider::TYPE_CREATE,
126 'should not be called on a non-link provider.',
129 PrimaryAuthenticationProvider::TYPE_LINK,
130 'is not implemented.',
136 * @dataProvider provideProviderNormalizeUsername
138 public function testProviderNormalizeUsername( $name, $expect ) {
139 // fake interwiki map for the 'Interwiki prefix' testcase
140 $this->mergeMwGlobalArrayValue( 'wgHooks', [
141 'InterwikiLoadPrefix' => [
142 function ( $prefix, &$iwdata ) {
143 if ( $prefix === 'interwiki' ) {
144 $iwdata = [
145 'iw_url' => 'http://example.com/',
146 'iw_local' => 0,
147 'iw_trans' => 0,
149 return false;
153 ] );
155 $provider = $this->getMockForAbstractClass( AbstractPrimaryAuthenticationProvider::class );
156 $this->assertSame( $expect, $provider->providerNormalizeUsername( $name ) );
159 public static function provideProviderNormalizeUsername() {
160 return [
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' ],