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