wiki.techinc.nl/tests/phpunit/includes/session/SessionProviderTest.php
Bartosz Dziewoński c045fa0291 Replace gettype() with get_debug_type() in exception messages
get_debug_type() does the same thing but better (spelling type names
in the same way as in type declarations, and including names of
object classes and resource types). It was added in PHP 8, but the
symfony/polyfill-php80 package provides it while we still support 7.4.

Also remove uses of get_class() and get_resource_type() where the new
method already provides the same information.

For reference:
https://www.php.net/manual/en/function.get-debug-type.php
https://www.php.net/manual/en/function.gettype.php

To keep this safe and simple to review, I'm only changing cases where
the type is immediately used in an exception message.

Change-Id: I325efcddcb58be63b1592b9c20ac0845393c15e2
2024-07-31 19:24:39 +02:00

237 lines
7.7 KiB
PHP

<?php
namespace MediaWiki\Tests\Session;
use BadMethodCallException;
use InvalidArgumentException;
use MediaWiki\Config\HashConfig;
use MediaWiki\MainConfigNames;
use MediaWiki\Request\FauxRequest;
use MediaWiki\Session\MetadataMergeException;
use MediaWiki\Session\SessionInfo;
use MediaWiki\Session\SessionManager;
use MediaWiki\Session\SessionProvider;
use MediaWiki\User\User;
use MediaWiki\User\UserNameUtils;
use MediaWikiIntegrationTestCase;
use TestLogger;
use Wikimedia\TestingAccessWrapper;
/**
* @group Session
* @group Database
* @covers \MediaWiki\Session\SessionProvider
*/
class SessionProviderTest extends MediaWikiIntegrationTestCase {
use SessionProviderTestTrait;
public function testBasics() {
$this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setConfig' );
$this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setLogger' );
$this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setManager' );
$this->hideDeprecated( 'MediaWiki\Session\SessionProvider::setHookContainer' );
$manager = new SessionManager();
$logger = new TestLogger();
$config = new HashConfig();
$hookContainer = $this->createHookContainer();
$userNameUtils = $this->createNoOpMock( UserNameUtils::class );
$provider = $this->getMockForAbstractClass( SessionProvider::class );
$priv = TestingAccessWrapper::newFromObject( $provider );
$this->initProvider( $provider, $logger, $config, $manager, $hookContainer, $userNameUtils );
$this->assertSame( $logger, $priv->logger );
$this->assertSame( $config, $priv->getConfig() );
$this->assertSame( $manager, $priv->manager );
$this->assertSame( $manager, $provider->getManager() );
$this->assertSame( $hookContainer, $priv->getHookContainer() );
$this->assertSame( $userNameUtils, $priv->userNameUtils );
$provider->setConfig( $config );
$this->assertSame( $config, $priv->getConfig() );
$provider->setLogger( $logger );
$this->assertSame( $logger, $priv->logger );
$provider->setManager( $manager );
$this->assertSame( $manager, $priv->manager );
$this->assertSame( $manager, $provider->getManager() );
$provider->setHookContainer( $hookContainer );
$this->assertSame( $hookContainer, $priv->getHookContainer() );
$provider->invalidateSessionsForUser( new User );
$this->assertSame( [], $provider->getVaryHeaders() );
$this->assertSame( [], $provider->getVaryCookies() );
$this->assertSame( null, $provider->suggestLoginUsername( new FauxRequest ) );
$this->assertSame( get_class( $provider ), (string)$provider );
$this->assertNull( $provider->getRememberUserDuration() );
$this->assertNull( $provider->whyNoSession() );
$this->assertFalse( $provider->safeAgainstCsrf() );
$info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'provider' => $provider,
] );
$metadata = [ 'foo' ];
$this->assertTrue( $provider->refreshSessionInfo( $info, new FauxRequest, $metadata ) );
$this->assertSame( [ 'foo' ], $metadata );
}
/**
* @dataProvider provideNewSessionInfo
* @param bool $persistId Return value for ->persistsSessionId()
* @param bool $persistUser Return value for ->persistsSessionUser()
* @param bool $ok Whether a SessionInfo is provided
*/
public function testNewSessionInfo( $persistId, $persistUser, $ok ) {
$manager = new SessionManager();
$provider = $this->getMockBuilder( SessionProvider::class )
->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
->getMockForAbstractClass();
$provider->method( 'persistsSessionId' )
->willReturn( $persistId );
$provider->method( 'canChangeUser' )
->willReturn( $persistUser );
$this->initProvider( $provider, null, null, $manager );
if ( $ok ) {
$info = $provider->newSessionInfo();
$this->assertNotNull( $info );
$this->assertFalse( $info->wasPersisted() );
$this->assertTrue( $info->isIdSafe() );
$id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$info = $provider->newSessionInfo( $id );
$this->assertNotNull( $info );
$this->assertSame( $id, $info->getId() );
$this->assertFalse( $info->wasPersisted() );
$this->assertTrue( $info->isIdSafe() );
} else {
$this->assertNull( $provider->newSessionInfo() );
}
}
public function testMergeMetadata() {
$provider = $this->getMockBuilder( SessionProvider::class )
->getMockForAbstractClass();
try {
$provider->mergeMetadata(
[ 'foo' => 1, 'baz' => 3 ],
[ 'bar' => 2, 'baz' => '3' ]
);
$this->fail( 'Expected exception not thrown' );
} catch ( MetadataMergeException $ex ) {
$this->assertSame( 'Key "baz" changed', $ex->getMessage() );
$this->assertSame(
[ 'old_value' => 3, 'new_value' => '3' ], $ex->getContext() );
}
$res = $provider->mergeMetadata(
[ 'foo' => 1, 'baz' => 3 ],
[ 'bar' => 2, 'baz' => 3 ]
);
$this->assertSame( [ 'bar' => 2, 'baz' => 3 ], $res );
}
public static function provideNewSessionInfo() {
return [
[ false, false, false ],
[ true, false, false ],
[ false, true, false ],
[ true, true, true ],
];
}
public function testImmutableSessions() {
$provider = $this->getMockBuilder( SessionProvider::class )
->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
->getMockForAbstractClass();
$provider->method( 'canChangeUser' )
->willReturn( true );
$provider->preventSessionsForUser( 'Foo' );
$provider = $this->getMockBuilder( SessionProvider::class )
->onlyMethods( [ 'canChangeUser', 'persistsSessionId' ] )
->getMockForAbstractClass();
$provider->method( 'canChangeUser' )
->willReturn( false );
try {
$provider->preventSessionsForUser( 'Foo' );
$this->fail( 'Expected exception not thrown' );
} catch ( BadMethodCallException $ex ) {
$this->assertSame(
'MediaWiki\\Session\\SessionProvider::preventSessionsForUser must be implemented ' .
'when canChangeUser() is false',
$ex->getMessage()
);
}
}
public function testHashToSessionId() {
$config = new HashConfig( [
MainConfigNames::SecretKey => 'Shhh!',
] );
$provider = $this->getMockForAbstractClass( SessionProvider::class,
[], 'MockSessionProvider' );
$this->initProvider( $provider, null, $config );
$priv = TestingAccessWrapper::newFromObject( $provider );
$this->assertSame( 'eoq8cb1mg7j30ui5qolafps4hg29k5bb', $priv->hashToSessionId( 'foobar' ) );
$this->assertSame( '4do8j7tfld1g8tte9jqp3csfgmulaun9',
$priv->hashToSessionId( 'foobar', 'secret' ) );
try {
$priv->hashToSessionId( [] );
$this->fail( 'Expected exception not thrown' );
} catch ( InvalidArgumentException $ex ) {
$this->assertSame(
'$data must be a string, array was passed',
$ex->getMessage()
);
}
try {
$priv->hashToSessionId( '', false );
$this->fail( 'Expected exception not thrown' );
} catch ( InvalidArgumentException $ex ) {
$this->assertSame(
'$key must be a string or null, bool was passed',
$ex->getMessage()
);
}
}
public function testDescribe() {
$provider = $this->getMockForAbstractClass( SessionProvider::class,
[], 'MockSessionProvider' );
$this->assertSame(
'MockSessionProvider sessions',
$provider->describe(
$this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' ) )
);
}
public function testGetAllowedUserRights() {
$provider = $this->getMockForAbstractClass( SessionProvider::class );
$backend = TestUtils::getDummySessionBackend();
try {
$provider->getAllowedUserRights( $backend );
$this->fail( 'Expected exception not thrown' );
} catch ( InvalidArgumentException $ex ) {
$this->assertSame(
'Backend\'s provider isn\'t $this',
$ex->getMessage()
);
}
TestingAccessWrapper::newFromObject( $backend )->provider = $provider;
$this->assertNull( $provider->getAllowedUserRights( $backend ) );
}
}