Localisation updates from https://translatewiki.net.
[mediawiki.git] / tests / phpunit / includes / session / SessionProviderTest.php
blob453b29b4cc7302ef966a6bf93e3fdf3cdbf94e52
1 <?php
3 namespace MediaWiki\Tests\Session;
5 use BadMethodCallException;
6 use InvalidArgumentException;
7 use MediaWiki\Config\HashConfig;
8 use MediaWiki\MainConfigNames;
9 use MediaWiki\Request\FauxRequest;
10 use MediaWiki\Session\MetadataMergeException;
11 use MediaWiki\Session\SessionInfo;
12 use MediaWiki\Session\SessionManager;
13 use MediaWiki\Session\SessionProvider;
14 use MediaWiki\User\User;
15 use MediaWiki\User\UserNameUtils;
16 use MediaWikiIntegrationTestCase;
17 use TestLogger;
18 use Wikimedia\TestingAccessWrapper;
20 /**
21 * @group Session
22 * @group Database
23 * @covers \MediaWiki\Session\SessionProvider
25 class SessionProviderTest extends MediaWikiIntegrationTestCase {
26 use SessionProviderTestTrait;
28 public function testBasics() {
29 $this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setConfig' );
30 $this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setLogger' );
31 $this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setManager' );
32 $this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setHookContainer' );
34 $manager = new SessionManager();
35 $logger = new TestLogger();
36 $config = new HashConfig();
37 $hookContainer = $this->createHookContainer();
38 $userNameUtils = $this->createNoOpMock( UserNameUtils::class );
40 $provider = $this->getMockForAbstractClass( SessionProvider::class );
41 $priv = TestingAccessWrapper::newFromObject( $provider );
43 $this->initProvider( $provider, $logger, $config, $manager, $hookContainer, $userNameUtils );
44 $this->assertSame( $logger, $priv->logger );
45 $this->assertSame( $config, $priv->getConfig() );
46 $this->assertSame( $manager, $priv->manager );
47 $this->assertSame( $manager, $provider->getManager() );
48 $this->assertSame( $hookContainer, $priv->getHookContainer() );
49 $this->assertSame( $userNameUtils, $priv->userNameUtils );
50 $provider->setConfig( $config );
51 $this->assertSame( $config, $priv->getConfig() );
52 $provider->setLogger( $logger );
53 $this->assertSame( $logger, $priv->logger );
54 $provider->setManager( $manager );
55 $this->assertSame( $manager, $priv->manager );
56 $this->assertSame( $manager, $provider->getManager() );
57 $provider->setHookContainer( $hookContainer );
58 $this->assertSame( $hookContainer, $priv->getHookContainer() );
60 $provider->invalidateSessionsForUser( new User );
62 $this->assertSame( [], $provider->getVaryHeaders() );
63 $this->assertSame( [], $provider->getVaryCookies() );
64 $this->assertSame( null, $provider->suggestLoginUsername( new FauxRequest ) );
66 $this->assertSame( get_class( $provider ), (string)$provider );
68 $this->assertNull( $provider->getRememberUserDuration() );
70 $this->assertNull( $provider->whyNoSession() );
71 $this->assertFalse( $provider->safeAgainstCsrf() );
73 $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
74 'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
75 'provider' => $provider,
76 ] );
77 $metadata = [ 'foo' ];
78 $this->assertTrue( $provider->refreshSessionInfo( $info, new FauxRequest, $metadata ) );
79 $this->assertSame( [ 'foo' ], $metadata );
82 /**
83 * @dataProvider provideNewSessionInfo
84 * @param bool $persistId Return value for ->persistsSessionId()
85 * @param bool $persistUser Return value for ->persistsSessionUser()
86 * @param bool $ok Whether a SessionInfo is provided
88 public function testNewSessionInfo( $persistId, $persistUser, $ok ) {
89 $manager = new SessionManager();
91 $provider = $this->getMockBuilder( SessionProvider::class )
92 ->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
93 ->getMockForAbstractClass();
94 $provider->method( 'persistsSessionId' )
95 ->willReturn( $persistId );
96 $provider->method( 'canChangeUser' )
97 ->willReturn( $persistUser );
98 $this->initProvider( $provider, null, null, $manager );
100 if ( $ok ) {
101 $info = $provider->newSessionInfo();
102 $this->assertNotNull( $info );
103 $this->assertFalse( $info->wasPersisted() );
104 $this->assertTrue( $info->isIdSafe() );
106 $id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
107 $info = $provider->newSessionInfo( $id );
108 $this->assertNotNull( $info );
109 $this->assertSame( $id, $info->getId() );
110 $this->assertFalse( $info->wasPersisted() );
111 $this->assertTrue( $info->isIdSafe() );
112 } else {
113 $this->assertNull( $provider->newSessionInfo() );
117 public function testMergeMetadata() {
118 $provider = $this->getMockBuilder( SessionProvider::class )
119 ->getMockForAbstractClass();
121 try {
122 $provider->mergeMetadata(
123 [ 'foo' => 1, 'baz' => 3 ],
124 [ 'bar' => 2, 'baz' => '3' ]
126 $this->fail( 'Expected exception not thrown' );
127 } catch ( MetadataMergeException $ex ) {
128 $this->assertSame( 'Key "baz" changed', $ex->getMessage() );
129 $this->assertSame(
130 [ 'old_value' => 3, 'new_value' => '3' ], $ex->getContext() );
133 $res = $provider->mergeMetadata(
134 [ 'foo' => 1, 'baz' => 3 ],
135 [ 'bar' => 2, 'baz' => 3 ]
137 $this->assertSame( [ 'bar' => 2, 'baz' => 3 ], $res );
140 public static function provideNewSessionInfo() {
141 return [
142 [ false, false, false ],
143 [ true, false, false ],
144 [ false, true, false ],
145 [ true, true, true ],
149 public function testImmutableSessions() {
150 $provider = $this->getMockBuilder( SessionProvider::class )
151 ->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
152 ->getMockForAbstractClass();
153 $provider->method( 'canChangeUser' )
154 ->willReturn( true );
155 $provider->preventSessionsForUser( 'Foo' );
157 $provider = $this->getMockBuilder( SessionProvider::class )
158 ->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
159 ->getMockForAbstractClass();
160 $provider->method( 'canChangeUser' )
161 ->willReturn( false );
162 try {
163 $provider->preventSessionsForUser( 'Foo' );
164 $this->fail( 'Expected exception not thrown' );
165 } catch ( BadMethodCallException $ex ) {
166 $this->assertSame(
167 'MediaWiki\\Session\\SessionProvider::preventSessionsForUser must be implemented ' .
168 'when canChangeUser() is false',
169 $ex->getMessage()
174 public function testHashToSessionId() {
175 $config = new HashConfig( [
176 MainConfigNames::SecretKey => 'Shhh!',
177 ] );
179 $provider = $this->getMockForAbstractClass( SessionProvider::class,
180 [], 'MockSessionProvider' );
181 $this->initProvider( $provider, null, $config );
182 $priv = TestingAccessWrapper::newFromObject( $provider );
184 $this->assertSame( 'eoq8cb1mg7j30ui5qolafps4hg29k5bb', $priv->hashToSessionId( 'foobar' ) );
185 $this->assertSame( '4do8j7tfld1g8tte9jqp3csfgmulaun9',
186 $priv->hashToSessionId( 'foobar', 'secret' ) );
188 try {
189 $priv->hashToSessionId( [] );
190 $this->fail( 'Expected exception not thrown' );
191 } catch ( InvalidArgumentException $ex ) {
192 $this->assertSame(
193 '$data must be a string, array was passed',
194 $ex->getMessage()
197 try {
198 $priv->hashToSessionId( '', false );
199 $this->fail( 'Expected exception not thrown' );
200 } catch ( InvalidArgumentException $ex ) {
201 $this->assertSame(
202 '$key must be a string or null, bool was passed',
203 $ex->getMessage()
208 public function testDescribe() {
209 $provider = $this->getMockForAbstractClass( SessionProvider::class,
210 [], 'MockSessionProvider' );
212 $this->assertSame(
213 'MockSessionProvider sessions',
214 $provider->describe(
215 $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' ) )
219 public function testGetAllowedUserRights() {
220 $provider = $this->getMockForAbstractClass( SessionProvider::class );
221 $backend = TestUtils::getDummySessionBackend();
223 try {
224 $provider->getAllowedUserRights( $backend );
225 $this->fail( 'Expected exception not thrown' );
226 } catch ( InvalidArgumentException $ex ) {
227 $this->assertSame(
228 'Backend\'s provider isn\'t $this',
229 $ex->getMessage()
233 TestingAccessWrapper::newFromObject( $backend )->provider = $provider;
234 $this->assertNull( $provider->getAllowedUserRights( $backend ) );