wiki.techinc.nl/tests/phpunit/includes/block/BlockManagerTest.php

756 lines
19 KiB
PHP
Raw Normal View History

<?php
use MediaWiki\Block\BlockManager;
use MediaWiki\Block\CompositeBlock;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\SystemBlock;
use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerInterface;
use Wikimedia\TestingAccessWrapper;
/**
* @group Blocking
* @group Database
* @coversDefaultClass \MediaWiki\Block\BlockManager
*/
class BlockManagerTest extends MediaWikiTestCase {
use TestAllServiceOptionsUsed;
/** @var User */
protected $user;
/** @var int */
protected $sysopId;
protected function setUp() : void {
parent::setUp();
$this->user = $this->getTestUser()->getUser();
$this->sysopId = $this->getTestSysop()->getUser()->getId();
$this->blockManagerConfig = [
'wgApplyIpBlocksToXff' => true,
'wgCookieSetOnAutoblock' => true,
'wgCookieSetOnIpBlock' => true,
'wgDnsBlacklistUrls' => [],
'wgEnableDnsBlacklist' => true,
'wgProxyList' => [],
'wgProxyWhitelist' => [],
'wgSecretKey' => false,
'wgSoftBlockRanges' => [],
];
}
private function getBlockManager( $overrideConfig ) {
return new BlockManager(
...$this->getBlockManagerConstructorArgs( $overrideConfig )
);
}
private function getBlockManagerConstructorArgs( $overrideConfig ) {
$blockManagerConfig = array_merge( $this->blockManagerConfig, $overrideConfig );
$this->setMwGlobals( $blockManagerConfig );
$logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
return [
new LoggedServiceOptions(
self::$serviceOptionsAccessLog,
BlockManager::CONSTRUCTOR_OPTIONS,
MediaWikiServices::getInstance()->getMainConfig()
),
MediaWikiServices::getInstance()->getPermissionManager(),
Hooks::run() call site migration Migrate all callers of Hooks::run() to use the new HookContainer/HookRunner system. General principles: * Use DI if it is already used. We're not changing the way state is managed in this patch. * HookContainer is always injected, not HookRunner. HookContainer is a service, it's a more generic interface, it is the only thing that provides isRegistered() which is needed in some cases, and a HookRunner can be efficiently constructed from it (confirmed by benchmark). Because HookContainer is needed for object construction, it is also needed by all factories. * "Ask your friendly local base class". Big hierarchies like SpecialPage and ApiBase have getHookContainer() and getHookRunner() methods in the base class, and classes that extend that base class are not expected to know or care where the base class gets its HookContainer from. * ProtectedHookAccessorTrait provides protected getHookContainer() and getHookRunner() methods, getting them from the global service container. The point of this is to ease migration to DI by ensuring that call sites ask their local friendly base class rather than getting a HookRunner from the service container directly. * Private $this->hookRunner. In some smaller classes where accessor methods did not seem warranted, there is a private HookRunner property which is accessed directly. Very rarely (two cases), there is a protected property, for consistency with code that conventionally assumes protected=private, but in cases where the class might actually be overridden, a protected accessor is preferred over a protected property. * The last resort: Hooks::runner(). Mostly for static, file-scope and global code. In a few cases it was used for objects with broken construction schemes, out of horror or laziness. Constructors with new required arguments: * AuthManager * BadFileLookup * BlockManager * ClassicInterwikiLookup * ContentHandlerFactory * ContentSecurityPolicy * DefaultOptionsManager * DerivedPageDataUpdater * FullSearchResultWidget * HtmlCacheUpdater * LanguageFactory * LanguageNameUtils * LinkRenderer * LinkRendererFactory * LocalisationCache * MagicWordFactory * MessageCache * NamespaceInfo * PageEditStash * PageHandlerFactory * PageUpdater * ParserFactory * PermissionManager * RevisionStore * RevisionStoreFactory * SearchEngineConfig * SearchEngineFactory * SearchFormWidget * SearchNearMatcher * SessionBackend * SpecialPageFactory * UserNameUtils * UserOptionsManager * WatchedItemQueryService * WatchedItemStore Constructors with new optional arguments: * DefaultPreferencesFactory * Language * LinkHolderArray * MovePage * Parser * ParserCache * PasswordReset * Router setHookContainer() now required after construction: * AuthenticationProvider * ResourceLoaderModule * SearchEngine Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
$logger,
MediaWikiServices::getInstance()->getHookContainer()
];
}
/**
* @dataProvider provideBlocksForShouldApplyCookieBlock
* @covers ::getBlockFromCookieValue
* @covers ::shouldApplyCookieBlock
*/
public function testGetBlockFromCookieValue( $options, $expected ) {
$blockManager = TestingAccessWrapper::newFromObject(
$this->getBlockManager( [
'wgCookieSetOnAutoblock' => true,
'wgCookieSetOnIpBlock' => true,
] )
);
$block = new DatabaseBlock( array_merge( [
'address' => $options['target'] ?: $this->user,
'by' => $this->sysopId,
], $options['blockOptions'] ) );
$block->insert();
$user = $options['loggedIn'] ? $this->user : new User();
$user->getRequest()->setCookie( 'BlockID', $blockManager->getCookieValue( $block ) );
$this->assertSame( $expected, (bool)$blockManager->getBlockFromCookieValue(
$user,
$user->getRequest()
) );
$block->delete();
}
/**
* @dataProvider provideBlocksForShouldApplyCookieBlock
* @covers ::trackBlockWithCookie
* @covers ::shouldApplyCookieBlock
*/
public function testTrackBlockWithCookieRemovesBlocks( $options, $expectKeepCookie ) {
$blockManager = TestingAccessWrapper::newFromObject(
$this->getBlockManager( [
'wgCookieSetOnAutoblock' => true,
'wgCookieSetOnIpBlock' => true,
] )
);
$block = new DatabaseBlock( array_merge( [
'address' => $options['target'] ?: $this->user,
'by' => $this->sysopId,
], $options['blockOptions'] ) );
$block->insert();
$user = $options['loggedIn'] ? $this->user : new User();
$user->getRequest()->setCookie( 'BlockID', $blockManager->getCookieValue( $block ) );
$blockManager->trackBlockWithCookie(
$user,
$user->getRequest()->response()
);
$this->assertCount(
$expectKeepCookie ? 0 : 1,
$user->getRequest()->response()->getCookies()
);
$block->delete();
}
public static function provideBlocksForShouldApplyCookieBlock() {
return [
'Autoblocking user block' => [
[
'target' => '',
'loggedIn' => true,
'blockOptions' => [
'enableAutoblock' => true
],
],
true,
],
'Autoblocking user block for anonymous user' => [
[
'target' => '',
'loggedIn' => false,
'blockOptions' => [
'enableAutoblock' => true
],
],
true,
],
'Non-autoblocking user block' => [
[
'target' => '',
'loggedIn' => true,
'blockOptions' => [],
],
false,
],
'IP block for anonymous user' => [
[
'target' => '127.0.0.1',
'loggedIn' => false,
'blockOptions' => [],
],
true,
],
'IP block for logged in user' => [
[
'target' => '127.0.0.1',
'loggedIn' => true,
'blockOptions' => [],
],
false,
],
'IP range block for anonymous user' => [
[
'target' => '127.0.0.0/8',
'loggedIn' => false,
'blockOptions' => [],
],
true,
],
];
}
/**
* @dataProvider provideIsLocallyBlockedProxy
* @covers ::isLocallyBlockedProxy
*/
public function testIsLocallyBlockedProxy( $proxyList, $expected ) {
$blockManager = TestingAccessWrapper::newFromObject(
$this->getBlockManager( [
'wgProxyList' => $proxyList
] )
);
$ip = '1.2.3.4';
$this->assertSame( $expected, $blockManager->isLocallyBlockedProxy( $ip ) );
}
public static function provideIsLocallyBlockedProxy() {
return [
'Proxy list is empty' => [ [], false ],
'Proxy list contains IP' => [ [ '1.2.3.4' ], true ],
'Proxy list contains IP as value' => [ [ 'test' => '1.2.3.4' ], true ],
'Proxy list contains range that covers IP' => [ [ '1.2.3.0/16' ], true ],
];
}
/**
* @dataProvider provideIsDnsBlacklisted
* @covers ::isDnsBlacklisted
* @covers ::inDnsBlacklist
*/
public function testIsDnsBlacklisted( $options, $expected ) {
$blockManagerConfig = [
'wgEnableDnsBlacklist' => true,
'wgDnsBlacklistUrls' => $options['blacklist'],
'wgProxyWhitelist' => $options['whitelist'],
];
$blockManager = $this->getMockBuilder( BlockManager::class )
->setConstructorArgs( $this->getBlockManagerConstructorArgs( $blockManagerConfig ) )
->setMethods( [ 'checkHost' ] )
->getMock();
$blockManager->method( 'checkHost' )
->will( $this->returnValueMap( [ [
$options['dnsblQuery'],
$options['dnsblResponse'],
] ] ) );
$this->assertSame(
$expected,
$blockManager->isDnsBlacklisted( $options['ip'], $options['checkWhitelist'] )
);
}
public static function provideIsDnsBlacklisted() {
$dnsblFound = [ '127.0.0.2' ];
$dnsblNotFound = false;
return [
'IP is blacklisted' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted; blacklist has key' => [
[
'blacklist' => [ [ 'dnsbl.test', 'key' ] ],
'ip' => '127.0.0.1',
'dnsblQuery' => 'key.1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted; blacklist is array' => [
[
'blacklist' => [ [ 'dnsbl.test' ] ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is not blacklisted' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '1.2.3.4',
'dnsblQuery' => '4.3.2.1.dnsbl.test',
'dnsblResponse' => $dnsblNotFound,
'whitelist' => [],
'checkWhitelist' => false,
],
false,
],
'Blacklist is empty' => [
[
'blacklist' => [],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
false,
],
'IP is blacklisted and whitelisted; whitelist is not checked' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [ '127.0.0.1' ],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted and whitelisted; whitelist is checked' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [ '127.0.0.1' ],
'checkWhitelist' => true,
],
false,
],
];
}
/**
* @covers ::getUniqueBlocks
*/
public function testGetUniqueBlocks() {
$blockId = 100;
$blockManager = TestingAccessWrapper::newFromObject( $this->getBlockManager( [] ) );
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getId' ] )
->getMock();
$block->method( 'getId' )
->willReturn( $blockId );
$autoblock = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getParentBlockId', 'getType' ] )
->getMock();
$autoblock->method( 'getParentBlockId' )
->willReturn( $blockId );
$autoblock->method( 'getType' )
->willReturn( DatabaseBlock::TYPE_AUTO );
$blocks = [ $block, $block, $autoblock, new SystemBlock() ];
$this->assertCount( 2, $blockManager->getUniqueBlocks( $blocks ) );
}
/**
* @dataProvider provideTrackBlockWithCookie
* @covers ::trackBlockWithCookie
*/
public function testTrackBlockWithCookie( $options, $expected ) {
$this->setMwGlobals( 'wgCookiePrefix', '' );
$request = new FauxRequest();
if ( $options['cookieSet'] ) {
$request->setCookie( 'BlockID', 'the value does not matter' );
}
block: Allow cookie-block tracking from any uncached web request This was previously hardcoded from three places: 1) Upon viewing EditPage, 2) Upon viewing SpecialCreateAccount, 3) For any url if the user is logged-in (User::loadFromSession/isLoggedIn). == User::loadFromSession Performing cookie blocks from here created a circular dependency because Block may need the user language for localisation, which is determined by asking the User object. This was previously worked around by using a DeferredUpdate (T180050, T226777). Moving this logic explicitly to the end of the pre-send cycle in MediaWiki::preOutputCommit breaks the cycle. This is also where other request-specific handling resides already. == Limited effect on unregistered users When an unregistered user performs an edit, and gets blocked, the cookie block is not applied until they open built-in editor or CreateAccount page. This makes it more likely for a user's IP to change meanwhile. Either intentionally, or simply due to IPs varying naturally (e.g. between mobile locations, or when going on/off WiFi). By applying it throughout sessioned page views for unregistered users, it is more likely to get set. Similar to what was already done for logged-in users. This commit also makes the intent of not caching EditPage and SpecialCreateAccount explicit. This was previously implicit through nothing having called setCdnMaxage() and/or due to Session::persist being checked for by OutputPage::sendCacheControl. Bug: T233594 Change-Id: Icf5a00f9b41d31bb6d4742c049feca0039d0c9d9
2019-09-07 23:44:46 +00:00
/** @var FauxResponse $response */
$response = $request->response();
$user = $this->getMockBuilder( User::class )
->setMethods( [ 'getBlock', 'getRequest' ] )
->getMock();
$user->method( 'getBlock' )
->willReturn( $options['block'] );
$user->method( 'getRequest' )
->willReturn( $request );
// Although the block cookie is set via DeferredUpdates, in command line mode updates are
// processed immediately
$blockManager = $this->getBlockManager( [
'wgSecretKey' => '',
'wgCookieSetOnIpBlock' => true,
] );
block: Allow cookie-block tracking from any uncached web request This was previously hardcoded from three places: 1) Upon viewing EditPage, 2) Upon viewing SpecialCreateAccount, 3) For any url if the user is logged-in (User::loadFromSession/isLoggedIn). == User::loadFromSession Performing cookie blocks from here created a circular dependency because Block may need the user language for localisation, which is determined by asking the User object. This was previously worked around by using a DeferredUpdate (T180050, T226777). Moving this logic explicitly to the end of the pre-send cycle in MediaWiki::preOutputCommit breaks the cycle. This is also where other request-specific handling resides already. == Limited effect on unregistered users When an unregistered user performs an edit, and gets blocked, the cookie block is not applied until they open built-in editor or CreateAccount page. This makes it more likely for a user's IP to change meanwhile. Either intentionally, or simply due to IPs varying naturally (e.g. between mobile locations, or when going on/off WiFi). By applying it throughout sessioned page views for unregistered users, it is more likely to get set. Similar to what was already done for logged-in users. This commit also makes the intent of not caching EditPage and SpecialCreateAccount explicit. This was previously implicit through nothing having called setCdnMaxage() and/or due to Session::persist being checked for by OutputPage::sendCacheControl. Bug: T233594 Change-Id: Icf5a00f9b41d31bb6d4742c049feca0039d0c9d9
2019-09-07 23:44:46 +00:00
$blockManager->trackBlockWithCookie( $user, $response );
$this->assertCount( $expected['count'], $response->getCookies() );
$this->assertEquals( $expected['value'], $response->getCookie( 'BlockID' ) );
}
public function provideTrackBlockWithCookie() {
$blockId = 123;
return [
'Block cookie is already set; there is a trackable block' => [
[
'cookieSet' => true,
'block' => $this->getTrackableBlock( $blockId ),
],
[
'count' => 1,
'value' => $blockId,
]
],
'Block cookie is already set; there is no block' => [
[
'cookieSet' => true,
'block' => null,
],
[
// Cookie is cleared by setting it to empty value
'count' => 1,
'value' => '',
]
],
'Block cookie is not yet set; there is no block' => [
[
'cookieSet' => false,
'block' => null,
],
[
'count' => 0,
'value' => null,
]
],
'Block cookie is not yet set; there is a trackable block' => [
[
'cookieSet' => false,
'block' => $this->getTrackableBlock( $blockId ),
],
[
'count' => 1,
'value' => $blockId,
]
],
'Block cookie is not yet set; there is a composite block with a trackable block' => [
[
'cookieSet' => false,
'block' => new CompositeBlock( [
'originalBlocks' => [
new SystemBlock(),
$this->getTrackableBlock( $blockId ),
]
] ),
],
[
'count' => 1,
'value' => $blockId,
]
],
'Block cookie is not yet set; there is a composite block but no trackable block' => [
[
'cookieSet' => false,
'block' => new CompositeBlock( [
'originalBlocks' => [
new SystemBlock(),
new SystemBlock(),
]
] ),
],
[
'count' => 0,
'value' => null,
]
],
];
}
private function getTrackableBlock( $blockId ) {
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getType', 'getId' ] )
->getMock();
$block->method( 'getType' )
->willReturn( DatabaseBlock::TYPE_IP );
$block->method( 'getId' )
->willReturn( $blockId );
return $block;
}
/**
* @dataProvider provideSetBlockCookie
* @covers ::setBlockCookie
*/
public function testSetBlockCookie( $expiryDelta, $expectedExpiryDelta ) {
$this->setMwGlobals( [
'wgCookiePrefix' => '',
] );
$request = new FauxRequest();
$response = $request->response();
$blockManager = $this->getBlockManager( [
'wgSecretKey' => '',
'wgCookieSetOnIpBlock' => true,
] );
$now = wfTimestamp();
$block = new DatabaseBlock( [
'expiry' => $expiryDelta === '' ? '' : $now + $expiryDelta
] );
$blockManager->setBlockCookie( $block, $response );
$cookies = $response->getCookies();
$this->assertEqualsWithDelta(
$now + $expectedExpiryDelta,
$cookies['BlockID']['expire'],
60 // Allow actual to be up to 60 seconds later than expected
);
}
public static function provideSetBlockCookie() {
// Maximum length of a block cookie, defined in BlockManager::setBlockCookie
$maxExpiryDelta = ( 24 * 60 * 60 );
$longExpiryDelta = ( 48 * 60 * 60 );
$shortExpiryDelta = ( 12 * 60 * 60 );
return [
'Block has indefinite expiry' => [
'',
$maxExpiryDelta,
],
'Block expiry is later than maximum cookie block expiry' => [
$longExpiryDelta,
$maxExpiryDelta,
],
'Block expiry is sooner than maximum cookie block expiry' => [
$shortExpiryDelta,
$shortExpiryDelta,
],
];
}
/**
* @covers ::shouldTrackBlockWithCookie
*/
public function testShouldTrackBlockWithCookieSystemBlock() {
$blockManager = TestingAccessWrapper::newFromObject( $this->getBlockManager( [] ) );
$this->assertFalse( $blockManager->shouldTrackBlockWithCookie(
new SystemBlock(),
true
) );
}
/**
* @dataProvider provideShouldTrackBlockWithCookie
* @covers ::shouldTrackBlockWithCookie
*/
public function testShouldTrackBlockWithCookie( $options, $expected ) {
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getType', 'isAutoblocking' ] )
->getMock();
$block->method( 'getType' )
->willReturn( $options['type'] );
if ( isset( $options['autoblocking'] ) ) {
$block->method( 'isAutoblocking' )
->willReturn( $options['autoblocking'] );
}
$blockManager = TestingAccessWrapper::newFromObject(
$this->getBlockManager( $options['blockManagerConfig'] )
);
$this->assertSame(
$expected,
$blockManager->shouldTrackBlockWithCookie( $block, $options['isAnon'] )
);
}
public static function provideShouldTrackBlockWithCookie() {
return [
'IP block, anonymous user, IP block cookies enabled' => [
[
'type' => DatabaseBlock::TYPE_IP,
'isAnon' => true,
'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
],
true
],
'IP range block, anonymous user, IP block cookies enabled' => [
[
'type' => DatabaseBlock::TYPE_RANGE,
'isAnon' => true,
'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
],
true
],
'IP block, anonymous user, IP block cookies disabled' => [
[
'type' => DatabaseBlock::TYPE_IP,
'isAnon' => true,
'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => false ],
],
false
],
'IP block, logged in user, IP block cookies enabled' => [
[
'type' => DatabaseBlock::TYPE_IP,
'isAnon' => false,
'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
],
false
],
'User block, anonymous, autoblock cookies enabled, block is autoblocking' => [
[
'type' => DatabaseBlock::TYPE_USER,
'isAnon' => true,
'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
'autoblocking' => true,
],
false
],
'User block, logged in, autoblock cookies enabled, block is autoblocking' => [
[
'type' => DatabaseBlock::TYPE_USER,
'isAnon' => false,
'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
'autoblocking' => true,
],
true
],
'User block, logged in, autoblock cookies disabled, block is autoblocking' => [
[
'type' => DatabaseBlock::TYPE_USER,
'isAnon' => false,
'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => false ],
'autoblocking' => true,
],
false
],
'User block, logged in, autoblock cookies enabled, block is not autoblocking' => [
[
'type' => DatabaseBlock::TYPE_USER,
'isAnon' => false,
'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
'autoblocking' => false,
],
false
],
'Block type is autoblock' => [
[
'type' => DatabaseBlock::TYPE_AUTO,
'isAnon' => true,
'blockManagerConfig' => [],
],
false
]
];
}
/**
* @covers ::clearBlockCookie
*/
public function testClearBlockCookie() {
$this->setMwGlobals( [
'wgCookiePrefix' => '',
] );
$request = new FauxRequest();
$response = $request->response();
$response->setCookie( 'BlockID', '100' );
$this->assertSame( '100', $response->getCookie( 'BlockID' ) );
BlockManager::clearBlockCookie( $response );
$this->assertSame( '', $response->getCookie( 'BlockID' ) );
}
/**
* @dataProvider provideGetIdFromCookieValue
* @covers ::getIdFromCookieValue
*/
public function testGetIdFromCookieValue( $options, $expected ) {
$blockManager = $this->getBlockManager( [
'wgSecretKey' => $options['secretKey']
] );
$this->assertEquals(
$expected,
$blockManager->getIdFromCookieValue( $options['cookieValue'] )
);
}
public static function provideGetIdFromCookieValue() {
$blockId = 100;
$secretKey = '123';
$hmac = MWCryptHash::hmac( $blockId, $secretKey, false );
return [
'No secret key is set' => [
[
'secretKey' => '',
'cookieValue' => $blockId,
'calculatedHmac' => MWCryptHash::hmac( $blockId, '', false ),
],
$blockId,
],
'Secret key is set and stored hmac is correct' => [
[
'secretKey' => $secretKey,
'cookieValue' => $blockId . '!' . $hmac,
'calculatedHmac' => $hmac,
],
$blockId,
],
'Secret key is set and stored hmac is incorrect' => [
[
'secretKey' => $secretKey,
'cookieValue' => $blockId . '!xyz',
'calculatedHmac' => $hmac,
],
null,
],
];
}
/**
* @dataProvider provideGetCookieValue
* @covers ::getCookieValue
*/
public function testGetCookieValue( $options, $expected ) {
$blockManager = $this->getBlockManager( [
'wgSecretKey' => $options['secretKey']
] );
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getId' ] )
->getMock();
$block->method( 'getId' )
->willReturn( $options['blockId'] );
$this->assertEquals(
$expected,
$blockManager->getCookieValue( $block )
);
}
public static function provideGetCookieValue() {
$blockId = 100;
return [
'Secret key not set' => [
[
'secretKey' => '',
'blockId' => $blockId,
'hmac' => MWCryptHash::hmac( $blockId, '', false ),
],
$blockId,
],
'Secret key set' => [
[
'secretKey' => '123',
'blockId' => $blockId,
'hmac' => MWCryptHash::hmac( $blockId, '123', false ),
],
$blockId . '!' . MWCryptHash::hmac( $blockId, '123', false ) ],
];
}
/**
* @coversNothing
*/
public function testAllServiceOptionsUsed() {
$this->assertAllServiceOptionsUsed( [ 'ApplyIpBlocksToXff', 'SoftBlockRanges' ] );
}
}