8 use Wikimedia\TestingAccessWrapper;
16 const SESSIONID =
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
39 if ( !$this->config ) {
40 $this->config = new \HashConfig();
41 $this->manager =
null;
43 if ( !$this->
store ) {
45 $this->manager =
null;
48 $logger = new \Psr\Log\NullLogger();
49 if ( !$this->manager ) {
51 'store' => $this->
store,
53 'config' => $this->config,
57 if ( !$this->provider ) {
58 $this->provider = new \DummySessionProvider();
60 $this->provider->setLogger( $logger );
61 $this->provider->setConfig( $this->config );
62 $this->provider->setManager( $this->manager );
65 'provider' => $this->provider,
66 'id' => $id ?: self::SESSIONID,
74 $priv = TestingAccessWrapper::newFromObject( $backend );
75 $priv->persist =
false;
76 $priv->requests = [ 100 => new \FauxRequest() ];
77 $priv->requests[100]->setSessionId( $id );
78 $priv->usePhpSessionHandling =
false;
80 $manager = TestingAccessWrapper::newFromObject( $this->manager );
83 $manager->sessionProviders = [ (
string)$this->provider => $this->provider ];
93 'provider' => $this->provider,
94 'id' => self::SESSIONID,
100 $logger = new \Psr\Log\NullLogger();
103 $this->fail(
'Expected exception not thrown' );
104 }
catch ( \InvalidArgumentException $ex ) {
106 "Refusing to create session for unverified user {$info->getUserInfo()}",
112 'id' => self::SESSIONID,
119 $this->fail(
'Expected exception not thrown' );
120 }
catch ( \InvalidArgumentException $ex ) {
121 $this->assertSame(
'Cannot create session without a provider', $ex->getMessage() );
125 'provider' => $this->provider,
126 'id' => self::SESSIONID,
131 $id =
new SessionId(
'!' . $info->getId() );
134 $this->fail(
'Expected exception not thrown' );
135 }
catch ( \InvalidArgumentException $ex ) {
137 'SessionId and SessionInfo don\'t match',
143 'provider' => $this->provider,
144 'id' => self::SESSIONID,
151 $this->assertSame( self::SESSIONID, $backend->
getId() );
152 $this->assertSame( $id, $backend->getSessionId() );
153 $this->assertSame( $this->provider, $backend->getProvider() );
154 $this->assertInstanceOf(
User::class, $backend->getUser() );
155 $this->assertSame(
'UTSysop', $backend->getUser()->getName() );
156 $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
157 $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
158 $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
160 $expire = time() + 100;
161 $this->
store->setSessionMeta( self::SESSIONID, [
'expires' => $expire ] );
164 'provider' => $this->provider,
165 'id' => self::SESSIONID,
167 'forceHTTPS' =>
true,
168 'metadata' => [
'foo' ],
173 $this->assertSame( self::SESSIONID, $backend->
getId() );
174 $this->assertSame( $id, $backend->getSessionId() );
175 $this->assertSame( $this->provider, $backend->getProvider() );
176 $this->assertInstanceOf(
User::class, $backend->getUser() );
177 $this->assertTrue( $backend->getUser()->isAnon() );
178 $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
179 $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
180 $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
181 $this->assertSame( $expire, TestingAccessWrapper::newFromObject( $backend )->expires );
182 $this->assertSame( [
'foo' ], $backend->getProviderMetadata() );
187 $priv = TestingAccessWrapper::newFromObject( $backend );
188 $priv->requests = [];
190 $manager = TestingAccessWrapper::newFromObject( $this->manager );
192 $request1 = new \FauxRequest();
193 $session1 = $backend->getSession( $request1 );
194 $request2 = new \FauxRequest();
195 $session2 = $backend->getSession( $request2 );
199 $this->assertSame( 2,
count( $priv->requests ) );
201 $index = TestingAccessWrapper::newFromObject( $session1 )->index;
203 $this->assertSame( $request1, $backend->getRequest( $index ) );
204 $this->assertSame(
null, $backend->suggestLoginUsername( $index ) );
205 $request1->setCookie(
'UserName',
'Example' );
206 $this->assertSame(
'Example', $backend->suggestLoginUsername( $index ) );
209 $this->assertSame( 1,
count( $priv->requests ) );
210 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionBackends );
211 $this->assertSame( $backend,
$manager->allSessionBackends[$backend->getId()] );
213 $backend->getRequest( $index );
214 $this->fail(
'Expected exception not thrown' );
215 }
catch ( \InvalidArgumentException $ex ) {
216 $this->assertSame(
'Invalid session index', $ex->getMessage() );
219 $backend->suggestLoginUsername( $index );
220 $this->fail(
'Expected exception not thrown' );
221 }
catch ( \InvalidArgumentException $ex ) {
222 $this->assertSame(
'Invalid session index', $ex->getMessage() );
226 $this->assertSame( 0,
count( $priv->requests ) );
227 $this->assertArrayNotHasKey( $backend->getId(),
$manager->allSessionBackends );
228 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionIds );
233 $priv = TestingAccessWrapper::newFromObject( $backend );
234 $priv->providerMetadata = [
'dummy' ];
237 $backend->setProviderMetadata(
'foo' );
238 $this->fail(
'Expected exception not thrown' );
239 }
catch ( \InvalidArgumentException $ex ) {
240 $this->assertSame(
'$metadata must be an array or null', $ex->getMessage() );
244 $backend->setProviderMetadata( (
object)[] );
245 $this->fail(
'Expected exception not thrown' );
246 }
catch ( \InvalidArgumentException $ex ) {
247 $this->assertSame(
'$metadata must be an array or null', $ex->getMessage() );
250 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
251 $backend->setProviderMetadata( [
'dummy' ] );
252 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
254 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
255 $backend->setProviderMetadata( [
'test' ] );
256 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ) );
257 $this->assertSame( [
'test' ], $backend->getProviderMetadata() );
258 $this->
store->deleteSession( self::SESSIONID );
260 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
261 $backend->setProviderMetadata(
null );
262 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ) );
263 $this->assertSame(
null, $backend->getProviderMetadata() );
264 $this->
store->deleteSession( self::SESSIONID );
271 ->setMethods( [
'persistsSessionId',
'sessionIdWasReset' ] );
273 $this->provider = $builder->getMock();
274 $this->provider->expects( $this->
any() )->method(
'persistsSessionId' )
275 ->will( $this->returnValue(
false ) );
276 $this->provider->expects( $this->never() )->method(
'sessionIdWasReset' );
278 $manager = TestingAccessWrapper::newFromObject( $this->manager );
279 $sessionId = $backend->getSessionId();
281 $this->assertSame( self::SESSIONID, $backend->getId() );
282 $this->assertSame( $backend->getId(), $sessionId->getId() );
283 $this->assertSame( $id, session_id() );
284 $this->assertSame( $backend,
$manager->allSessionBackends[self::SESSIONID] );
286 $this->provider = $builder->getMock();
287 $this->provider->expects( $this->
any() )->method(
'persistsSessionId' )
288 ->will( $this->returnValue(
true ) );
290 $this->provider->expects( $this->once() )->method(
'sessionIdWasReset' )
291 ->with( $this->identicalTo( $backend ), $this->identicalTo( self::SESSIONID ) );
292 $manager = TestingAccessWrapper::newFromObject( $this->manager );
293 $sessionId = $backend->getSessionId();
295 $this->assertNotEquals( self::SESSIONID, $backend->getId() );
296 $this->assertSame( $backend->getId(), $sessionId->getId() );
297 $this->assertInternalType(
'array', $this->
store->getSession( $backend->getId() ) );
298 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
299 $this->assertSame( $id, session_id() );
300 $this->assertArrayNotHasKey( self::SESSIONID,
$manager->allSessionBackends );
301 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionBackends );
302 $this->assertSame( $backend,
$manager->allSessionBackends[$backend->getId()] );
307 ->setMethods( [
'persistSession' ] )->getMock();
308 $this->provider->expects( $this->once() )->method(
'persistSession' );
310 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
314 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
316 $this->provider =
null;
318 $wrap = TestingAccessWrapper::newFromObject( $backend );
319 $wrap->persist =
true;
322 $this->assertNotEquals( 0, $wrap->expires );
327 ->setMethods( [
'unpersistSession' ] )->getMock();
328 $this->provider->expects( $this->once() )->method(
'unpersistSession' );
330 $wrap = TestingAccessWrapper::newFromObject( $backend );
331 $wrap->store = new \CachedBagOStuff( $this->
store );
332 $wrap->persist =
true;
333 $wrap->dataDirty =
true;
336 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
337 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
339 $backend->unpersist();
340 $this->assertFalse( $backend->isPersistent() );
341 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
342 $this->assertNotFalse(
343 $wrap->store->get( $wrap->store->makeKey(
'MWSession', self::SESSIONID ) )
350 $remembered = $backend->shouldRememberUser();
351 $backend->setRememberUser( !$remembered );
352 $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
353 $backend->setRememberUser( $remembered );
354 $this->assertEquals( $remembered, $backend->shouldRememberUser() );
360 $force = $backend->shouldForceHTTPS();
361 $backend->setForceHTTPS( !$force );
362 $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
363 $backend->setForceHTTPS( $force );
364 $this->assertEquals( $force, $backend->shouldForceHTTPS() );
370 $backend->setLoggedOutTimestamp( 42 );
371 $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
372 $backend->setLoggedOutTimestamp(
'123' );
373 $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
377 $user = static::getTestSysop()->getUser();
380 ->setMethods( [
'canChangeUser' ] )->getMock();
381 $this->provider->expects( $this->
any() )->method(
'canChangeUser' )
382 ->will( $this->returnValue(
false ) );
384 $this->assertFalse( $backend->canSetUser() );
386 $backend->setUser(
$user );
387 $this->fail(
'Expected exception not thrown' );
388 }
catch ( \BadMethodCallException $ex ) {
390 'Cannot set user on this session; check $session->canSetUser() first',
394 $this->assertNotSame(
$user, $backend->getUser() );
396 $this->provider =
null;
398 $this->assertTrue( $backend->canSetUser() );
399 $this->assertNotSame(
$user, $backend->getUser(),
'sanity check' );
400 $backend->setUser(
$user );
401 $this->assertSame(
$user, $backend->getUser() );
406 $priv = TestingAccessWrapper::newFromObject( $backend );
407 $priv->dataDirty =
false;
409 $this->assertTrue( $priv->dataDirty );
414 $data = $backend->getData();
415 $this->assertSame( [], $data );
416 $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
417 $data[
'???'] =
'!!!';
418 $this->assertSame( [
'???' =>
'!!!' ], $data );
420 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
421 $this->
store->setSessionData( self::SESSIONID, $testData );
423 $this->assertSame( $testData, $backend->getData() );
424 $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
429 $priv = TestingAccessWrapper::newFromObject( $backend );
431 $priv->data = [
'foo' => 1 ];
432 $priv->dataDirty =
false;
433 $backend->addData( [
'foo' => 1 ] );
434 $this->assertSame( [
'foo' => 1 ], $priv->data );
435 $this->assertFalse( $priv->dataDirty );
437 $priv->data = [
'foo' => 1 ];
438 $priv->dataDirty =
false;
439 $backend->addData( [
'foo' =>
'1' ] );
440 $this->assertSame( [
'foo' =>
'1' ], $priv->data );
441 $this->assertTrue( $priv->dataDirty );
443 $priv->data = [
'foo' => 1 ];
444 $priv->dataDirty =
false;
445 $backend->addData( [
'bar' => 2 ] );
446 $this->assertSame( [
'foo' => 1,
'bar' => 2 ], $priv->data );
447 $this->assertTrue( $priv->dataDirty );
453 $priv = TestingAccessWrapper::newFromObject( $backend );
454 $priv->persist =
true;
457 $this->onSessionMetadataCalled =
false;
458 $priv->metaDirty =
true;
460 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
462 $this->onSessionMetadataCalled =
false;
463 $priv->metaDirty =
true;
465 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
467 $delay = $backend->delaySave();
470 $this->onSessionMetadataCalled =
false;
471 $priv->metaDirty =
true;
473 $this->assertFalse( $this->onSessionMetadataCalled );
477 $this->assertTrue( $this->onSessionMetadataCalled );
480 $this->onSessionMetadataCalled =
false;
481 $priv->metaDirty =
true;
482 \Wikimedia\ScopedCallback::consume( $delay );
483 $this->assertTrue( $this->onSessionMetadataCalled );
486 $delay1 = $backend->delaySave();
487 $delay2 = $backend->delaySave();
488 $delay3 = $backend->delaySave();
489 $this->onSessionMetadataCalled =
false;
490 $priv->metaDirty =
true;
492 $this->assertFalse( $this->onSessionMetadataCalled );
493 \Wikimedia\ScopedCallback::consume( $delay3 );
494 $this->assertFalse( $this->onSessionMetadataCalled );
495 \Wikimedia\ScopedCallback::consume( $delay1 );
496 $this->assertFalse( $this->onSessionMetadataCalled );
497 \Wikimedia\ScopedCallback::consume( $delay2 );
498 $this->assertTrue( $this->onSessionMetadataCalled );
502 $user = static::getTestSysop()->getUser();
504 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
506 $neverHook = $this->getMockBuilder( __CLASS__ )
507 ->setMethods( [
'onSessionMetadata' ] )->getMock();
508 $neverHook->expects( $this->never() )->method(
'onSessionMetadata' );
511 ->setMethods( [
'persistSession',
'unpersistSession' ] );
513 $neverProvider = $builder->getMock();
514 $neverProvider->expects( $this->never() )->method(
'persistSession' );
515 $neverProvider->expects( $this->never() )->method(
'unpersistSession' );
518 $this->provider = $neverProvider;
520 $this->
store->setSessionData( self::SESSIONID, $testData );
522 $this->
store->deleteSession( self::SESSIONID );
523 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
524 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
525 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
527 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
530 $this->provider = $builder->getMock();
531 $this->provider->expects( $this->never() )->method(
'persistSession' );
532 $this->provider->expects( $this->atLeastOnce() )->method(
'unpersistSession' );
534 $this->
store->setSessionData( self::SESSIONID, $testData );
536 $this->
store->deleteSession( self::SESSIONID );
537 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
538 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
539 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
540 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
541 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
543 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
546 $this->provider = $neverProvider;
548 $this->
store->setSessionData( self::SESSIONID, $testData );
550 TestingAccessWrapper::newFromObject( $backend )->requests[100]
552 $this->
store->deleteSession( self::SESSIONID );
553 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
554 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
555 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
556 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
557 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
559 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
562 $this->provider = $neverProvider;
563 $this->onSessionMetadataCalled =
false;
565 $this->
store->setSessionData( self::SESSIONID, $testData );
567 $this->
store->deleteSession( self::SESSIONID );
568 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
569 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
570 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
572 $this->assertTrue( $this->onSessionMetadataCalled );
573 $blob = $this->
store->getSession( self::SESSIONID );
574 $this->assertInternalType(
'array',
$blob );
575 $this->assertArrayHasKey(
'metadata',
$blob );
576 $metadata =
$blob[
'metadata'];
577 $this->assertInternalType(
'array', $metadata );
578 $this->assertArrayHasKey(
'???', $metadata );
579 $this->assertSame(
'!!!', $metadata[
'???'] );
580 $this->assertFalse( $this->
store->getSessionFromBackend( self::SESSIONID ),
581 'making sure it didn\'t save to backend' );
584 $this->provider = $neverProvider;
586 $this->
store->setSessionData( self::SESSIONID, $testData );
588 $this->
store->deleteSession( self::SESSIONID );
589 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
590 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
591 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
592 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
594 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
597 $this->provider = $builder->getMock();
598 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
599 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
601 $this->
store->setSessionData( self::SESSIONID, $testData );
603 $this->
store->deleteSession( self::SESSIONID );
604 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
605 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
606 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
607 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
608 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
610 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
613 $this->provider = $neverProvider;
614 $this->onSessionMetadataCalled =
false;
616 $this->
store->setSessionData( self::SESSIONID, $testData );
618 $this->
store->deleteSession( self::SESSIONID );
619 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
620 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
621 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
622 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
624 $this->assertTrue( $this->onSessionMetadataCalled );
625 $blob = $this->
store->getSession( self::SESSIONID );
626 $this->assertInternalType(
'array',
$blob );
627 $this->assertArrayHasKey(
'metadata',
$blob );
628 $metadata =
$blob[
'metadata'];
629 $this->assertInternalType(
'array', $metadata );
630 $this->assertArrayHasKey(
'???', $metadata );
631 $this->assertSame(
'!!!', $metadata[
'???'] );
632 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
633 'making sure it did save to backend' );
636 $this->provider = $builder->getMock();
637 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
638 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
639 $this->onSessionMetadataCalled =
false;
641 $this->
store->setSessionData( self::SESSIONID, $testData );
643 $this->
store->deleteSession( self::SESSIONID );
644 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
645 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
646 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
647 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
648 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
650 $this->assertTrue( $this->onSessionMetadataCalled );
651 $blob = $this->
store->getSession( self::SESSIONID );
652 $this->assertInternalType(
'array',
$blob );
653 $this->assertArrayHasKey(
'metadata',
$blob );
654 $metadata =
$blob[
'metadata'];
655 $this->assertInternalType(
'array', $metadata );
656 $this->assertArrayHasKey(
'???', $metadata );
657 $this->assertSame(
'!!!', $metadata[
'???'] );
658 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
659 'making sure it did save to backend' );
662 $this->provider = $builder->getMock();
663 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
664 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
665 $this->onSessionMetadataCalled =
false;
667 $this->
store->setSessionData( self::SESSIONID, $testData );
669 $this->
store->deleteSession( self::SESSIONID );
670 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
671 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
672 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
673 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
675 $this->assertTrue( $this->onSessionMetadataCalled );
676 $blob = $this->
store->getSession( self::SESSIONID );
677 $this->assertInternalType(
'array',
$blob );
678 $this->assertArrayHasKey(
'metadata',
$blob );
679 $metadata =
$blob[
'metadata'];
680 $this->assertInternalType(
'array', $metadata );
681 $this->assertArrayHasKey(
'???', $metadata );
682 $this->assertSame(
'!!!', $metadata[
'???'] );
683 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
684 'making sure it did save to backend' );
688 $this->provider = $neverProvider;
689 $this->onSessionMetadataCalled =
false;
691 $this->
store->setSessionData( self::SESSIONID, $testData );
693 $this->
store->deleteSession( self::SESSIONID );
694 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
695 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
696 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
697 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
698 TestingAccessWrapper::newFromObject( $backend )->dataHash =
'Doesn\'t match';
700 $this->assertTrue( $this->onSessionMetadataCalled );
701 $blob = $this->
store->getSession( self::SESSIONID );
702 $this->assertInternalType(
'array',
$blob );
703 $this->assertArrayHasKey(
'metadata',
$blob );
704 $metadata =
$blob[
'metadata'];
705 $this->assertInternalType(
'array', $metadata );
706 $this->assertArrayHasKey(
'???', $metadata );
707 $this->assertSame(
'!!!', $metadata[
'???'] );
708 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
709 'making sure it did save to backend' );
712 $this->provider =
null;
713 $mockHook = $this->getMockBuilder( __CLASS__ )
714 ->setMethods( [
'onSessionMetadata' ] )->getMock();
715 $mockHook->expects( $this->
any() )->method(
'onSessionMetadata' )
716 ->will( $this->returnCallback(
718 $metadata[
'userId']++;
722 $this->
store->setSessionData( self::SESSIONID, $testData );
727 $this->fail(
'Expected exception not thrown' );
728 }
catch ( \UnexpectedValueException $ex ) {
730 'SessionMetadata hook changed metadata key "userId"',
736 TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
737 $user->getName() =>
true,
739 $this->provider = $neverProvider;
741 $this->
store->setSessionData( self::SESSIONID, $testData );
743 $this->
store->deleteSession( self::SESSIONID );
744 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
745 $this->assertTrue( $backend->
isPersistent(),
'sanity check' );
746 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
747 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
749 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
753 $user = static::getTestSysop()->getUser();
755 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
759 ->setMethods( [
'persistSession' ] )->getMock();
760 $this->provider->expects( $this->never() )->method(
'persistSession' );
761 $this->onSessionMetadataCalled =
false;
763 $this->
store->setSessionData( self::SESSIONID, $testData );
765 $this->
store->deleteSession( self::SESSIONID );
766 $wrap = TestingAccessWrapper::newFromObject( $backend );
767 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
768 $wrap->metaDirty =
false;
769 $wrap->dataDirty =
false;
770 $wrap->forcePersist =
false;
773 $this->assertTrue( $this->onSessionMetadataCalled );
774 $blob = $this->
store->getSession( self::SESSIONID );
775 $this->assertInternalType(
'array',
$blob );
776 $this->assertArrayHasKey(
'metadata',
$blob );
777 $metadata =
$blob[
'metadata'];
778 $this->assertInternalType(
'array', $metadata );
779 $this->assertArrayHasKey(
'???', $metadata );
780 $this->assertSame(
'!!!', $metadata[
'???'] );
781 $this->assertNotEquals( 0, $wrap->expires );
785 ->setMethods( [
'persistSession' ] )->getMock();
786 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
787 $this->onSessionMetadataCalled =
false;
789 $this->
store->setSessionData( self::SESSIONID, $testData );
791 $this->
store->deleteSession( self::SESSIONID );
792 $wrap = TestingAccessWrapper::newFromObject( $backend );
793 $wrap->persist =
true;
794 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
795 $wrap->metaDirty =
false;
796 $wrap->dataDirty =
false;
797 $wrap->forcePersist =
false;
800 $this->assertTrue( $this->onSessionMetadataCalled );
801 $blob = $this->
store->getSession( self::SESSIONID );
802 $this->assertInternalType(
'array',
$blob );
803 $this->assertArrayHasKey(
'metadata',
$blob );
804 $metadata =
$blob[
'metadata'];
805 $this->assertInternalType(
'array', $metadata );
806 $this->assertArrayHasKey(
'???', $metadata );
807 $this->assertSame(
'!!!', $metadata[
'???'] );
808 $this->assertNotEquals( 0, $wrap->expires );
812 ->setMethods( [
'persistSession' ] )->getMock();
813 $this->provider->expects( $this->never() )->method(
'persistSession' );
814 $this->onSessionMetadataCalled =
false;
816 $this->
store->setSessionData( self::SESSIONID, $testData );
818 $this->
store->deleteSession( self::SESSIONID );
819 $wrap = TestingAccessWrapper::newFromObject( $backend );
820 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
821 $wrap->metaDirty =
false;
822 $wrap->dataDirty =
false;
823 $wrap->forcePersist =
false;
824 $expires = time() + $wrap->lifetime + 100;
825 $wrap->expires = $expires;
827 $this->assertFalse( $this->onSessionMetadataCalled );
828 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
829 $this->assertEquals( $expires, $wrap->expires );
833 $this->onSessionMetadataCalled =
true;
834 $metadata[
'???'] =
'!!!';
843 $rProp->setAccessible(
true );
844 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
845 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
846 session_write_close();
852 $backend = $this->
getBackend( static::getTestSysop()->getUser() );
853 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
857 $manager = TestingAccessWrapper::newFromObject( $this->manager );
863 TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
864 $this->assertSame( $backend->getId(), session_id() );
865 session_write_close();
870 TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling =
true;
873 TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
874 $this->assertSame(
'', session_id() );
883 $rProp->setAccessible(
true );
884 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
885 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
886 session_write_close();
893 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
897 $manager = TestingAccessWrapper::newFromObject( $this->manager );
902 session_id( self::SESSIONID );
903 \Wikimedia\quietCall(
'session_start' );
904 $_SESSION[
'foo'] = __METHOD__;
906 $this->assertNotEquals( self::SESSIONID, $backend->getId() );
907 $this->assertSame( $backend->getId(), session_id() );
908 $this->assertArrayHasKey(
'foo', $_SESSION );
909 $this->assertSame( __METHOD__, $_SESSION[
'foo'] );
910 session_write_close();
919 $rProp->setAccessible(
true );
920 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
921 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
922 session_write_close();
929 $wrap = TestingAccessWrapper::newFromObject( $backend );
930 $wrap->usePhpSessionHandling =
true;
931 $wrap->persist =
true;
935 $manager = TestingAccessWrapper::newFromObject( $this->manager );
940 session_id( self::SESSIONID .
'x' );
941 \Wikimedia\quietCall(
'session_start' );
942 $backend->unpersist();
943 $this->assertSame( self::SESSIONID .
'x', session_id() );
944 session_write_close();
946 session_id( self::SESSIONID );
947 $wrap->persist =
true;
948 $backend->unpersist();
949 $this->assertSame(
'', session_id() );
954 ->setMethods( [
'getAllowedUserRights' ] )
956 $this->provider->expects( $this->
any() )->method(
'getAllowedUserRights' )
957 ->will( $this->returnValue( [
'foo',
'bar' ] ) );
960 $this->assertSame( [
'foo',
'bar' ], $backend->getAllowedUserRights() );