Merge "filebackend: Clean up TempFSFile and fix IDEA errors"
[lhc/web/wiklou.git] / tests / phpunit / includes / session / SessionBackendTest.php
index 481b693..61be8e0 100644 (file)
@@ -36,11 +36,11 @@ class SessionBackendTest extends MediaWikiTestCase {
 
                $logger = new \Psr\Log\NullLogger();
                if ( !$this->manager ) {
-                       $this->manager = new SessionManager( array(
+                       $this->manager = new SessionManager( [
                                'store' => $this->store,
                                'logger' => $logger,
                                'config' => $this->config,
-                       ) );
+                       ] );
                }
 
                if ( !$this->provider ) {
@@ -50,25 +50,26 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->provider->setConfig( $this->config );
                $this->provider->setManager( $this->manager );
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'provider' => $this->provider,
                        'id' => self::SESSIONID,
                        'persisted' => true,
                        'userInfo' => UserInfo::newFromUser( $user ?: new User, true ),
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( $info->getId() );
 
                $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
                $priv = \TestingAccessWrapper::newFromObject( $backend );
                $priv->persist = false;
-               $priv->requests = array( 100 => new \FauxRequest() );
+               $priv->requests = [ 100 => new \FauxRequest() ];
+               $priv->requests[100]->setSessionId( $id );
                $priv->usePhpSessionHandling = false;
 
                $manager = \TestingAccessWrapper::newFromObject( $this->manager );
-               $manager->allSessionBackends = array( $backend->getId() => $backend );
-               $manager->allSessionIds = array( $backend->getId() => $id );
-               $manager->sessionProviders = array( (string)$this->provider => $this->provider );
+               $manager->allSessionBackends = [ $backend->getId() => $backend ];
+               $manager->allSessionIds = [ $backend->getId() => $id ];
+               $manager->sessionProviders = [ (string)$this->provider => $this->provider ];
 
                return $backend;
        }
@@ -77,13 +78,13 @@ class SessionBackendTest extends MediaWikiTestCase {
                // Set variables
                $this->getBackend();
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'provider' => $this->provider,
                        'id' => self::SESSIONID,
                        'persisted' => true,
                        'userInfo' => UserInfo::newFromName( 'UTSysop', false ),
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( $info->getId() );
                $logger = new \Psr\Log\NullLogger();
                try {
@@ -96,11 +97,11 @@ class SessionBackendTest extends MediaWikiTestCase {
                        );
                }
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'id' => self::SESSIONID,
                        'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( $info->getId() );
                try {
                        new SessionBackend( $id, $info, $this->store, $logger, 10 );
@@ -109,13 +110,13 @@ class SessionBackendTest extends MediaWikiTestCase {
                        $this->assertSame( 'Cannot create session without a provider', $ex->getMessage() );
                }
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'provider' => $this->provider,
                        'id' => self::SESSIONID,
                        'persisted' => true,
                        'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( '!' . $info->getId() );
                try {
                        new SessionBackend( $id, $info, $this->store, $logger, 10 );
@@ -127,13 +128,13 @@ class SessionBackendTest extends MediaWikiTestCase {
                        );
                }
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'provider' => $this->provider,
                        'id' => self::SESSIONID,
                        'persisted' => true,
                        'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( $info->getId() );
                $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
                $this->assertSame( self::SESSIONID, $backend->getId() );
@@ -146,16 +147,16 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
 
                $expire = time() + 100;
-               $this->store->setSessionMeta( self::SESSIONID, array( 'expires' => $expire ), 2 );
+               $this->store->setSessionMeta( self::SESSIONID, [ 'expires' => $expire ], 2 );
 
-               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'provider' => $this->provider,
                        'id' => self::SESSIONID,
                        'persisted' => true,
                        'forceHTTPS' => true,
-                       'metadata' => array( 'foo' ),
+                       'metadata' => [ 'foo' ],
                        'idIsSafe' => true,
-               ) );
+               ] );
                $id = new SessionId( $info->getId() );
                $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
                $this->assertSame( self::SESSIONID, $backend->getId() );
@@ -167,13 +168,13 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
                $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
                $this->assertSame( $expire, \TestingAccessWrapper::newFromObject( $backend )->expires );
-               $this->assertSame( array( 'foo' ), $backend->getProviderMetadata() );
+               $this->assertSame( [ 'foo' ], $backend->getProviderMetadata() );
        }
 
        public function testSessionStuff() {
                $backend = $this->getBackend();
                $priv = \TestingAccessWrapper::newFromObject( $backend );
-               $priv->requests = array(); // Remove dummy session
+               $priv->requests = []; // Remove dummy session
 
                $manager = \TestingAccessWrapper::newFromObject( $this->manager );
 
@@ -216,11 +217,47 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertArrayHasKey( $backend->getId(), $manager->allSessionIds );
        }
 
+       public function testSetProviderMetadata() {
+               $backend = $this->getBackend();
+               $priv = \TestingAccessWrapper::newFromObject( $backend );
+               $priv->providerMetadata = [ 'dummy' ];
+
+               try {
+                       $backend->setProviderMetadata( 'foo' );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( \InvalidArgumentException $ex ) {
+                       $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
+               }
+
+               try {
+                       $backend->setProviderMetadata( (object)[] );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( \InvalidArgumentException $ex ) {
+                       $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
+               }
+
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
+               $backend->setProviderMetadata( [ 'dummy' ] );
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
+
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
+               $backend->setProviderMetadata( [ 'test' ] );
+               $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
+               $this->assertSame( [ 'test' ], $backend->getProviderMetadata() );
+               $this->store->deleteSession( self::SESSIONID );
+
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
+               $backend->setProviderMetadata( null );
+               $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
+               $this->assertSame( null, $backend->getProviderMetadata() );
+               $this->store->deleteSession( self::SESSIONID );
+       }
+
        public function testResetId() {
                $id = session_id();
 
                $builder = $this->getMockBuilder( 'DummySessionProvider' )
-                       ->setMethods( array( 'persistsSessionId', 'sessionIdWasReset' ) );
+                       ->setMethods( [ 'persistsSessionId', 'sessionIdWasReset' ] );
 
                $this->provider = $builder->getMock();
                $this->provider->expects( $this->any() )->method( 'persistsSessionId' )
@@ -255,7 +292,7 @@ class SessionBackendTest extends MediaWikiTestCase {
        }
 
        public function testPersist() {
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'persistSession' ] );
                $this->provider->expects( $this->once() )->method( 'persistSession' );
                $backend = $this->getBackend();
                $this->assertFalse( $backend->isPersistent(), 'sanity check' );
@@ -273,6 +310,25 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertNotEquals( 0, $wrap->expires );
        }
 
+       public function testUnpersist() {
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'unpersistSession' ] );
+               $this->provider->expects( $this->once() )->method( 'unpersistSession' );
+               $backend = $this->getBackend();
+               $wrap = \TestingAccessWrapper::newFromObject( $backend );
+               $wrap->store = new \CachedBagOStuff( $this->store );
+               $wrap->persist = true;
+               $wrap->dataDirty = true;
+
+               $backend->save(); // This one shouldn't call $provider->persistSession(), but should save
+               $this->assertTrue( $backend->isPersistent(), 'sanity check' );
+               $this->assertNotFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
+
+               $backend->unpersist();
+               $this->assertFalse( $backend->isPersistent() );
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
+               $this->assertNotFalse( $wrap->store->get( wfMemcKey( 'MWSession', self::SESSIONID ) ) );
+       }
+
        public function testRememberUser() {
                $backend = $this->getBackend();
 
@@ -305,7 +361,7 @@ class SessionBackendTest extends MediaWikiTestCase {
        public function testSetUser() {
                $user = User::newFromName( 'UTSysop' );
 
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'canChangeUser' ) );
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'canChangeUser' ] );
                $this->provider->expects( $this->any() )->method( 'canChangeUser' )
                        ->will( $this->returnValue( false ) );
                $backend = $this->getBackend();
@@ -340,12 +396,12 @@ class SessionBackendTest extends MediaWikiTestCase {
        public function testGetData() {
                $backend = $this->getBackend();
                $data = $backend->getData();
-               $this->assertSame( array(), $data );
+               $this->assertSame( [], $data );
                $this->assertTrue( \TestingAccessWrapper::newFromObject( $backend )->dataDirty );
                $data['???'] = '!!!';
-               $this->assertSame( array( '???' => '!!!' ), $data );
+               $this->assertSame( [ '???' => '!!!' ], $data );
 
-               $testData = array( 'foo' => 'foo!', 'bar', array( 'baz', null ) );
+               $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend();
                $this->assertSame( $testData, $backend->getData() );
@@ -356,27 +412,27 @@ class SessionBackendTest extends MediaWikiTestCase {
                $backend = $this->getBackend();
                $priv = \TestingAccessWrapper::newFromObject( $backend );
 
-               $priv->data = array( 'foo' => 1 );
+               $priv->data = [ 'foo' => 1 ];
                $priv->dataDirty = false;
-               $backend->addData( array( 'foo' => 1 ) );
-               $this->assertSame( array( 'foo' => 1 ), $priv->data );
+               $backend->addData( [ 'foo' => 1 ] );
+               $this->assertSame( [ 'foo' => 1 ], $priv->data );
                $this->assertFalse( $priv->dataDirty );
 
-               $priv->data = array( 'foo' => 1 );
+               $priv->data = [ 'foo' => 1 ];
                $priv->dataDirty = false;
-               $backend->addData( array( 'foo' => '1' ) );
-               $this->assertSame( array( 'foo' => '1' ), $priv->data );
+               $backend->addData( [ 'foo' => '1' ] );
+               $this->assertSame( [ 'foo' => '1' ], $priv->data );
                $this->assertTrue( $priv->dataDirty );
 
-               $priv->data = array( 'foo' => 1 );
+               $priv->data = [ 'foo' => 1 ];
                $priv->dataDirty = false;
-               $backend->addData( array( 'bar' => 2 ) );
-               $this->assertSame( array( 'foo' => 1, 'bar' => 2 ), $priv->data );
+               $backend->addData( [ 'bar' => 2 ] );
+               $this->assertSame( [ 'foo' => 1, 'bar' => 2 ], $priv->data );
                $this->assertTrue( $priv->dataDirty );
        }
 
        public function testDelaySave() {
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $backend = $this->getBackend();
                $priv = \TestingAccessWrapper::newFromObject( $backend );
                $priv->persist = true;
@@ -429,20 +485,56 @@ class SessionBackendTest extends MediaWikiTestCase {
        public function testSave() {
                $user = User::newFromName( 'UTSysop' );
                $this->store = new TestBagOStuff();
-               $testData = array( 'foo' => 'foo!', 'bar', array( 'baz', null ) );
+               $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
 
-               $neverHook = $this->getMock( __CLASS__, array( 'onSessionMetadata' ) );
+               $neverHook = $this->getMock( __CLASS__, [ 'onSessionMetadata' ] );
                $neverHook->expects( $this->never() )->method( 'onSessionMetadata' );
 
-               $neverProvider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               $builder = $this->getMockBuilder( 'DummySessionProvider' )
+                       ->setMethods( [ 'persistSession', 'unpersistSession' ] );
+
+               $neverProvider = $builder->getMock();
                $neverProvider->expects( $this->never() )->method( 'persistSession' );
+               $neverProvider->expects( $this->never() )->method( 'unpersistSession' );
 
                // Not persistent or dirty
                $this->provider = $neverProvider;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $neverHook ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
+               $this->store->setSessionData( self::SESSIONID, $testData );
+               $backend = $this->getBackend( $user );
+               $this->store->deleteSession( self::SESSIONID );
+               $this->assertFalse( $backend->isPersistent(), 'sanity check' );
+               \TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
+               \TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
+               $backend->save();
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
+
+               // (but does unpersist if forced)
+               $this->provider = $builder->getMock();
+               $this->provider->expects( $this->never() )->method( 'persistSession' );
+               $this->provider->expects( $this->atLeastOnce() )->method( 'unpersistSession' );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
+               \TestingAccessWrapper::newFromObject( $backend )->persist = false;
+               \TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
+               $this->assertFalse( $backend->isPersistent(), 'sanity check' );
+               \TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
+               \TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
+               $backend->save();
+               $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
+
+               // (but not to a WebRequest associated with a different session)
+               $this->provider = $neverProvider;
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
+               $this->store->setSessionData( self::SESSIONID, $testData );
+               $backend = $this->getBackend( $user );
+               \TestingAccessWrapper::newFromObject( $backend )->requests[100]
+                       ->setSessionId( new SessionId( 'x' ) );
+               $this->store->deleteSession( self::SESSIONID );
+               \TestingAccessWrapper::newFromObject( $backend )->persist = false;
+               \TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
                $this->assertFalse( $backend->isPersistent(), 'sanity check' );
                \TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
                \TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
@@ -452,7 +544,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                // Not persistent, but dirty
                $this->provider = $neverProvider;
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -473,7 +565,7 @@ class SessionBackendTest extends MediaWikiTestCase {
 
                // Persistent, not dirty
                $this->provider = $neverProvider;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $neverHook ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -484,9 +576,11 @@ class SessionBackendTest extends MediaWikiTestCase {
                $backend->save();
                $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
 
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               // (but will persist if forced)
+               $this->provider = $builder->getMock();
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $neverHook ) ) );
+               $this->provider->expects( $this->never() )->method( 'unpersistSession' );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -501,7 +595,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                // Persistent and dirty
                $this->provider = $neverProvider;
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -521,10 +615,12 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
                        'making sure it did save to backend' );
 
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               // (also persists if forced)
+               $this->provider = $builder->getMock();
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
+               $this->provider->expects( $this->never() )->method( 'unpersistSession' );
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -545,10 +641,12 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
                        'making sure it did save to backend' );
 
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               // (also persists if metadata dirty)
+               $this->provider = $builder->getMock();
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
+               $this->provider->expects( $this->never() )->method( 'unpersistSession' );
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -572,7 +670,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                // (e.g. indirect modification from ArrayAccess::offsetGet)
                $this->provider = $neverProvider;
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -595,14 +693,14 @@ class SessionBackendTest extends MediaWikiTestCase {
 
                // Bad hook
                $this->provider = null;
-               $mockHook = $this->getMock( __CLASS__, array( 'onSessionMetadata' ) );
+               $mockHook = $this->getMock( __CLASS__, [ 'onSessionMetadata' ] );
                $mockHook->expects( $this->any() )->method( 'onSessionMetadata' )
                        ->will( $this->returnCallback(
                                function ( SessionBackend $backend, array &$metadata, array $requests ) {
                                        $metadata['userId']++;
                                }
                        ) );
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $mockHook ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $mockHook ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $backend->dirty();
@@ -617,11 +715,11 @@ class SessionBackendTest extends MediaWikiTestCase {
                }
 
                // SessionManager::preventSessionsForUser
-               \TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = array(
+               \TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
                        $user->getName() => true,
-               );
+               ];
                $this->provider = $neverProvider;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $neverHook ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -636,13 +734,13 @@ class SessionBackendTest extends MediaWikiTestCase {
        public function testRenew() {
                $user = User::newFromName( 'UTSysop' );
                $this->store = new TestBagOStuff();
-               $testData = array( 'foo' => 'foo!', 'bar', array( 'baz', null ) );
+               $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
 
                // Not persistent
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'persistSession' ] );
                $this->provider->expects( $this->never() )->method( 'persistSession' );
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -664,10 +762,10 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertNotEquals( 0, $wrap->expires );
 
                // Persistent
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'persistSession' ] );
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -690,10 +788,10 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertNotEquals( 0, $wrap->expires );
 
                // Not persistent, not expiring
-               $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
+               $this->provider = $this->getMock( 'DummySessionProvider', [ 'persistSession' ] );
                $this->provider->expects( $this->never() )->method( 'persistSession' );
                $this->onSessionMetadataCalled = false;
-               $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'SessionMetadata' => array( $this ) ) );
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
                $this->store->setSessionData( self::SESSIONID, $testData );
                $backend = $this->getBackend( $user );
                $this->store->deleteSession( self::SESSIONID );
@@ -754,15 +852,53 @@ class SessionBackendTest extends MediaWikiTestCase {
                session_write_close();
        }
 
+       public function testUnpersistOfGlobalSession() {
+               if ( !PHPSessionHandler::isInstalled() ) {
+                       PHPSessionHandler::install( SessionManager::singleton() );
+               }
+               if ( !PHPSessionHandler::isEnabled() ) {
+                       $rProp = new \ReflectionProperty( 'MediaWiki\\Session\\PHPSessionHandler', 'instance' );
+                       $rProp->setAccessible( true );
+                       $handler = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
+                       $resetHandler = new \ScopedCallback( function () use ( $handler ) {
+                               session_write_close();
+                               $handler->enable = false;
+                       } );
+                       $handler->enable = true;
+               }
+
+               $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
+               $wrap = \TestingAccessWrapper::newFromObject( $backend );
+               $wrap->usePhpSessionHandling = true;
+               $wrap->persist = true;
+
+               TestUtils::setSessionManagerSingleton( $this->manager );
+
+               $manager = \TestingAccessWrapper::newFromObject( $this->manager );
+               $request = \RequestContext::getMain()->getRequest();
+               $manager->globalSession = $backend->getSession( $request );
+               $manager->globalSessionRequest = $request;
+
+               session_id( self::SESSIONID . 'x' );
+               \MediaWiki\quietCall( 'session_start' );
+               $backend->unpersist();
+               $this->assertSame( self::SESSIONID . 'x', session_id() );
+
+               session_id( self::SESSIONID );
+               $wrap->persist = true;
+               $backend->unpersist();
+               $this->assertSame( '', session_id() );
+       }
+
        public function testGetAllowedUserRights() {
                $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
-                       ->setMethods( array( 'getAllowedUserRights' ) )
+                       ->setMethods( [ 'getAllowedUserRights' ] )
                        ->getMock();
                $this->provider->expects( $this->any() )->method( 'getAllowedUserRights' )
-                       ->will( $this->returnValue( array( 'foo', 'bar' ) ) );
+                       ->will( $this->returnValue( [ 'foo', 'bar' ] ) );
 
                $backend = $this->getBackend();
-               $this->assertSame( array( 'foo', 'bar' ), $backend->getAllowedUserRights() );
+               $this->assertSame( [ 'foo', 'bar' ], $backend->getAllowedUserRights() );
        }
 
 }