wiki.techinc.nl/tests/phpunit/includes/block/BlockErrorFormatterTest.php
daniel 3d55397207 Move creation of BlockErrorFormatter into FormatterFactory
The idea is that all formatters that need the user language or
other request specific context should be instantiated by
FormatterFactory.

Change-Id: I8334cc89dcf0f293298b82e004116be50a90f0d1
2024-01-26 13:03:44 -05:00

334 lines
7.6 KiB
PHP

<?php
use MediaWiki\Block\BlockErrorFormatter;
use MediaWiki\Block\CompositeBlock;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\SystemBlock;
use Wikimedia\Rdbms\IDatabase;
use Wikimedia\Rdbms\LBFactory;
/**
* @todo Can this be converted to unit tests?
*
* @group Blocking
* @covers \MediaWiki\Block\BlockErrorFormatter
*/
class BlockErrorFormatterTest extends MediaWikiIntegrationTestCase {
/**
* @return DerivativeContext
*/
private function getContext(): DerivativeContext {
$context = new DerivativeContext( RequestContext::getMain() );
$context->setLanguage(
$this->getServiceContainer()
->getLanguageFactory()->getLanguage( 'qqx' )
);
return $context;
}
private function getBlockErrorFormatter( IContextSource $context ): BlockErrorFormatter {
return $this->getServiceContainer()
->getFormatterFactory()->getBlockErrorFormatter( $context );
}
protected function setUp(): void {
parent::setUp();
$db = $this->createMock( IDatabase::class );
$db->method( 'getInfinity' )->willReturn( 'infinity' );
$db->method( 'decodeExpiry' )->willReturnArgument( 0 );
$lb = $this->createNoOpMock(
LoadBalancer::class,
[ 'getConnectionRef', 'getConnection' ]
);
$lb->method( 'getConnectionRef' )->willReturn( $db );
$lb->method( 'getConnection' )->willReturn( $db );
$lbFactory = $this->createNoOpMock(
LBFactory::class,
[ 'getReplicaDatabase', 'getPrimaryDatabase', 'getMainLB', ]
);
$lbFactory->method( 'getReplicaDatabase' )->willReturn( $db );
$lbFactory->method( 'getPrimaryDatabase' )->willReturn( $db );
$lbFactory->method( 'getMainLB' )->willReturn( $lb );
$this->setService( 'DBLoadBalancerFactory', $lbFactory );
}
/**
* @dataProvider provideTestGetMessage
*/
public function testGetMessage( $blockClass, $blockData, $expectedKey, $expectedParams ) {
$block = $this->makeBlock(
$blockClass,
$blockData
);
$context = $this->getContext();
$formatter = $this->getBlockErrorFormatter( $context );
$message = $formatter->getMessage(
$block,
$context->getUser(),
$context->getLanguage(),
'1.2.3.4'
);
$this->assertSame( $expectedKey, $message->getKey() );
$this->assertSame( $expectedParams, $message->getParams() );
}
public static function provideTestGetMessage() {
$timestamp = '20000101000000';
$expiry = '20010101000000';
$databaseBlock = [
'timestamp' => $timestamp,
'expiry' => $expiry,
'reason' => 'Test reason.',
];
$systemBlock = [
'timestamp' => $timestamp,
'systemBlock' => 'test',
'reason' => new Message( 'proxyblockreason' ),
];
$compositeBlock = [
'timestamp' => $timestamp,
'originalBlocks' => [
[ DatabaseBlock::class, $databaseBlock ],
[ SystemBlock::class, $systemBlock ]
]
];
return [
'Database block' => [
DatabaseBlock::class,
$databaseBlock,
'blockedtext',
[
'',
'Test reason.',
'1.2.3.4',
'',
null, // Block not inserted
'00:00, 1 (january) 2001',
'',
'00:00, 1 (january) 2000',
],
],
'Database block (autoblock)' => [
DatabaseBlock::class,
[
'timestamp' => $timestamp,
'expiry' => $expiry,
'auto' => true,
],
'autoblockedtext',
[
'',
'(blockednoreason)',
'1.2.3.4',
'',
null, // Block not inserted
'00:00, 1 (january) 2001',
'',
'00:00, 1 (january) 2000',
],
],
'Database block (partial block)' => [
DatabaseBlock::class,
[
'timestamp' => $timestamp,
'expiry' => $expiry,
'sitewide' => false,
],
'blockedtext-partial',
[
'',
'(blockednoreason)',
'1.2.3.4',
'',
null, // Block not inserted
'00:00, 1 (january) 2001',
'',
'00:00, 1 (january) 2000',
],
],
'System block (type \'test\')' => [
SystemBlock::class,
$systemBlock,
'systemblockedtext',
[
'',
'(proxyblockreason)',
'1.2.3.4',
'',
'test',
'(infiniteblock)',
'',
'00:00, 1 (january) 2000',
],
],
'System block (type \'test\') with reason parameters' => [
SystemBlock::class,
[
'timestamp' => $timestamp,
'systemBlock' => 'test',
'reason' => new Message( 'softblockrangesreason', [ '1.2.3.4' ] ),
],
'systemblockedtext',
[
'',
'(softblockrangesreason: 1.2.3.4)',
'1.2.3.4',
'',
'test',
'(infiniteblock)',
'',
'00:00, 1 (january) 2000',
],
],
'Composite block (original blocks not inserted)' => [
CompositeBlock::class,
$compositeBlock,
'blockedtext-composite',
[
'',
'(blockednoreason)',
'1.2.3.4',
'',
'(blockedtext-composite-no-ids)',
'(infiniteblock)',
'',
'00:00, 1 (january) 2000',
],
],
];
}
/**
* @dataProvider provideTestGetMessageCompositeBlocks
*/
public function testGetMessageCompositeBlocks( $ids, $expected ) {
$block = $this->getMockBuilder( CompositeBlock::class )
->onlyMethods( [ 'getIdentifier' ] )
->getMock();
$block->method( 'getIdentifier' )
->willReturn( $ids );
$context = RequestContext::getMain();
$formatter = $this->getBlockErrorFormatter( $context );
$this->assertContains(
$expected,
$formatter->getMessage(
$block,
$context->getUser(),
$context->getLanguage(),
$context->getRequest()->getIP()
)->getParams()
);
}
public static function provideTestGetMessageCompositeBlocks() {
return [
'All original blocks are system blocks' => [
[ 'test', 'test' ],
'Your IP address appears in multiple blocklists',
],
'One original block is a database block' => [
[ 100, 'test' ],
'Relevant block IDs: #100 (your IP address may also appear in a blocklist)',
],
'Several original blocks are database blocks' => [
[ 100, 101, 102 ],
'Relevant block IDs: #100, #101, #102 (your IP address may also appear in a blocklist)',
],
];
}
/**
* @dataProvider provideTestGetMessages
*/
public function testGetMessages( $blockClass, $blockData, $expectedKeys ) {
$block = $this->makeBlock(
$blockClass,
$blockData
);
$context = $this->getContext();
$formatter = $this->getBlockErrorFormatter( $context );
$messages = $formatter->getMessages(
$block,
$context->getUser(),
'1.2.3.4'
);
$this->assertSame( $expectedKeys, array_map( static function ( $message ) {
return $message->getKey();
}, $messages ) );
}
public static function provideTestGetMessages() {
$timestamp = '20000101000000';
$expiry = '20010101000000';
$databaseBlock = [
'timestamp' => $timestamp,
'expiry' => $expiry,
'reason' => 'Test reason.',
];
$systemBlock = [
'timestamp' => $timestamp,
'systemBlock' => 'test',
'reason' => new Message( 'proxyblockreason' ),
];
$compositeBlock = [
'timestamp' => $timestamp,
'originalBlocks' => [
[ DatabaseBlock::class, $databaseBlock ],
[ SystemBlock::class, $systemBlock ]
]
];
return [
'Database block' => [
DatabaseBlock::class,
$databaseBlock,
[ 'blockedtext' ],
],
'System block (type \'test\')' => [
SystemBlock::class,
$systemBlock,
[ 'systemblockedtext' ],
],
'Composite block (original blocks not inserted)' => [
CompositeBlock::class,
$compositeBlock,
[ 'blockedtext', 'systemblockedtext' ],
],
];
}
/**
* @param string $blockClass
* @param array $blockData
*
* @return mixed
*/
private function makeBlock( $blockClass, $blockData ) {
foreach ( $blockData['originalBlocks'] ?? [] as $key => $originalBlock ) {
$blockData['originalBlocks'][$key] = $this->makeBlock( ...$originalBlock );
}
return new $blockClass( $blockData );
}
}