]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - tests/phpunit/includes/session/SessionProviderTest.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / tests / phpunit / includes / session / SessionProviderTest.php
1 <?php
2
3 namespace MediaWiki\Session;
4
5 use MediaWikiTestCase;
6 use Wikimedia\TestingAccessWrapper;
7
8 /**
9  * @group Session
10  * @group Database
11  * @covers MediaWiki\Session\SessionProvider
12  */
13 class SessionProviderTest extends MediaWikiTestCase {
14
15         public function testBasics() {
16                 $manager = new SessionManager();
17                 $logger = new \TestLogger();
18                 $config = new \HashConfig();
19
20                 $provider = $this->getMockForAbstractClass( SessionProvider::class );
21                 $priv = TestingAccessWrapper::newFromObject( $provider );
22
23                 $provider->setConfig( $config );
24                 $this->assertSame( $config, $priv->config );
25                 $provider->setLogger( $logger );
26                 $this->assertSame( $logger, $priv->logger );
27                 $provider->setManager( $manager );
28                 $this->assertSame( $manager, $priv->manager );
29                 $this->assertSame( $manager, $provider->getManager() );
30
31                 $provider->invalidateSessionsForUser( new \User );
32
33                 $this->assertSame( [], $provider->getVaryHeaders() );
34                 $this->assertSame( [], $provider->getVaryCookies() );
35                 $this->assertSame( null, $provider->suggestLoginUsername( new \FauxRequest ) );
36
37                 $this->assertSame( get_class( $provider ), (string)$provider );
38
39                 $this->assertNull( $provider->getRememberUserDuration() );
40
41                 $this->assertNull( $provider->whyNoSession() );
42
43                 $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
44                         'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
45                         'provider' => $provider,
46                 ] );
47                 $metadata = [ 'foo' ];
48                 $this->assertTrue( $provider->refreshSessionInfo( $info, new \FauxRequest, $metadata ) );
49                 $this->assertSame( [ 'foo' ], $metadata );
50         }
51
52         /**
53          * @dataProvider provideNewSessionInfo
54          * @param bool $persistId Return value for ->persistsSessionId()
55          * @param bool $persistUser Return value for ->persistsSessionUser()
56          * @param bool $ok Whether a SessionInfo is provided
57          */
58         public function testNewSessionInfo( $persistId, $persistUser, $ok ) {
59                 $manager = new SessionManager();
60
61                 $provider = $this->getMockBuilder( SessionProvider::class )
62                         ->setMethods( [ 'canChangeUser', 'persistsSessionId' ] )
63                         ->getMockForAbstractClass();
64                 $provider->expects( $this->any() )->method( 'persistsSessionId' )
65                         ->will( $this->returnValue( $persistId ) );
66                 $provider->expects( $this->any() )->method( 'canChangeUser' )
67                         ->will( $this->returnValue( $persistUser ) );
68                 $provider->setManager( $manager );
69
70                 if ( $ok ) {
71                         $info = $provider->newSessionInfo();
72                         $this->assertNotNull( $info );
73                         $this->assertFalse( $info->wasPersisted() );
74                         $this->assertTrue( $info->isIdSafe() );
75
76                         $id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
77                         $info = $provider->newSessionInfo( $id );
78                         $this->assertNotNull( $info );
79                         $this->assertSame( $id, $info->getId() );
80                         $this->assertFalse( $info->wasPersisted() );
81                         $this->assertTrue( $info->isIdSafe() );
82                 } else {
83                         $this->assertNull( $provider->newSessionInfo() );
84                 }
85         }
86
87         public function testMergeMetadata() {
88                 $provider = $this->getMockBuilder( SessionProvider::class )
89                         ->getMockForAbstractClass();
90
91                 try {
92                         $provider->mergeMetadata(
93                                 [ 'foo' => 1, 'baz' => 3 ],
94                                 [ 'bar' => 2, 'baz' => '3' ]
95                         );
96                         $this->fail( 'Expected exception not thrown' );
97                 } catch ( MetadataMergeException $ex ) {
98                         $this->assertSame( 'Key "baz" changed', $ex->getMessage() );
99                         $this->assertSame(
100                                 [ 'old_value' => 3, 'new_value' => '3' ], $ex->getContext() );
101                 }
102
103                 $res = $provider->mergeMetadata(
104                         [ 'foo' => 1, 'baz' => 3 ],
105                         [ 'bar' => 2, 'baz' => 3 ]
106                 );
107                 $this->assertSame( [ 'bar' => 2, 'baz' => 3 ], $res );
108         }
109
110         public static function provideNewSessionInfo() {
111                 return [
112                         [ false, false, false ],
113                         [ true, false, false ],
114                         [ false, true, false ],
115                         [ true, true, true ],
116                 ];
117         }
118
119         public function testImmutableSessions() {
120                 $provider = $this->getMockBuilder( SessionProvider::class )
121                         ->setMethods( [ 'canChangeUser', 'persistsSessionId' ] )
122                         ->getMockForAbstractClass();
123                 $provider->expects( $this->any() )->method( 'canChangeUser' )
124                         ->will( $this->returnValue( true ) );
125                 $provider->preventSessionsForUser( 'Foo' );
126
127                 $provider = $this->getMockBuilder( SessionProvider::class )
128                         ->setMethods( [ 'canChangeUser', 'persistsSessionId' ] )
129                         ->getMockForAbstractClass();
130                 $provider->expects( $this->any() )->method( 'canChangeUser' )
131                         ->will( $this->returnValue( false ) );
132                 try {
133                         $provider->preventSessionsForUser( 'Foo' );
134                         $this->fail( 'Expected exception not thrown' );
135                 } catch ( \BadMethodCallException $ex ) {
136                         $this->assertSame(
137                                 'MediaWiki\\Session\\SessionProvider::preventSessionsForUser must be implmented ' .
138                                         'when canChangeUser() is false',
139                                 $ex->getMessage()
140                         );
141                 }
142         }
143
144         public function testHashToSessionId() {
145                 $config = new \HashConfig( [
146                         'SecretKey' => 'Shhh!',
147                 ] );
148
149                 $provider = $this->getMockForAbstractClass( SessionProvider::class,
150                         [], 'MockSessionProvider' );
151                 $provider->setConfig( $config );
152                 $priv = TestingAccessWrapper::newFromObject( $provider );
153
154                 $this->assertSame( 'eoq8cb1mg7j30ui5qolafps4hg29k5bb', $priv->hashToSessionId( 'foobar' ) );
155                 $this->assertSame( '4do8j7tfld1g8tte9jqp3csfgmulaun9',
156                         $priv->hashToSessionId( 'foobar', 'secret' ) );
157
158                 try {
159                         $priv->hashToSessionId( [] );
160                         $this->fail( 'Expected exception not thrown' );
161                 } catch ( \InvalidArgumentException $ex ) {
162                         $this->assertSame(
163                                 '$data must be a string, array was passed',
164                                 $ex->getMessage()
165                         );
166                 }
167                 try {
168                         $priv->hashToSessionId( '', false );
169                         $this->fail( 'Expected exception not thrown' );
170                 } catch ( \InvalidArgumentException $ex ) {
171                         $this->assertSame(
172                                 '$key must be a string or null, boolean was passed',
173                                 $ex->getMessage()
174                         );
175                 }
176         }
177
178         public function testDescribe() {
179                 $provider = $this->getMockForAbstractClass( SessionProvider::class,
180                         [], 'MockSessionProvider' );
181
182                 $this->assertSame(
183                         'MockSessionProvider sessions',
184                         $provider->describe( \Language::factory( 'en' ) )
185                 );
186         }
187
188         public function testGetAllowedUserRights() {
189                 $provider = $this->getMockForAbstractClass( SessionProvider::class );
190                 $backend = TestUtils::getDummySessionBackend();
191
192                 try {
193                         $provider->getAllowedUserRights( $backend );
194                         $this->fail( 'Expected exception not thrown' );
195                 } catch ( \InvalidArgumentException $ex ) {
196                         $this->assertSame(
197                                 'Backend\'s provider isn\'t $this',
198                                 $ex->getMessage()
199                         );
200                 }
201
202                 TestingAccessWrapper::newFromObject( $backend )->provider = $provider;
203                 $this->assertNull( $provider->getAllowedUserRights( $backend ) );
204         }
205
206 }