3 use MediaWiki\Block\BlockErrorFormatter
;
4 use MediaWiki\Block\CompositeBlock
;
5 use MediaWiki\Block\DatabaseBlock
;
6 use MediaWiki\Block\SystemBlock
;
7 use MediaWiki\Context\DerivativeContext
;
8 use MediaWiki\Context\IContextSource
;
9 use MediaWiki\Context\RequestContext
;
10 use MediaWiki\Message\Message
;
11 use Wikimedia\Rdbms\IDatabase
;
12 use Wikimedia\Rdbms\LBFactory
;
13 use Wikimedia\Rdbms\LoadBalancer
;
16 * @todo Can this be converted to unit tests?
19 * @covers \MediaWiki\Block\BlockErrorFormatter
21 class BlockErrorFormatterTest
extends MediaWikiIntegrationTestCase
{
24 * @return DerivativeContext
26 private function getContext(): DerivativeContext
{
27 $context = new DerivativeContext( RequestContext
::getMain() );
29 $context->setLanguage(
30 $this->getServiceContainer()
31 ->getLanguageFactory()->getLanguage( 'qqx' )
37 private function getBlockErrorFormatter( IContextSource
$context ): BlockErrorFormatter
{
38 return $this->getServiceContainer()
39 ->getFormatterFactory()->getBlockErrorFormatter( $context );
42 protected function setUp(): void
{
45 $db = $this->createMock( IDatabase
::class );
46 $db->method( 'getInfinity' )->willReturn( 'infinity' );
47 $db->method( 'decodeExpiry' )->willReturnArgument( 0 );
49 $lb = $this->createNoOpMock(
53 $lb->method( 'getConnection' )->willReturn( $db );
55 $lbFactory = $this->createNoOpMock(
57 [ 'getReplicaDatabase', 'getPrimaryDatabase', 'getMainLB', ]
59 $lbFactory->method( 'getReplicaDatabase' )->willReturn( $db );
60 $lbFactory->method( 'getPrimaryDatabase' )->willReturn( $db );
61 $lbFactory->method( 'getMainLB' )->willReturn( $lb );
62 $this->setService( 'DBLoadBalancerFactory', $lbFactory );
66 * @dataProvider provideTestGetMessage
68 public function testGetMessage( $blockClass, $blockData, $expectedKey, $expectedParams ) {
69 $block = $this->makeBlock(
73 $context = $this->getContext();
75 $formatter = $this->getBlockErrorFormatter( $context );
76 $message = $formatter->getMessage(
79 $context->getLanguage(),
83 $this->assertSame( $expectedKey, $message->getKey() );
84 $this->assertSame( $expectedParams, $message->getParams() );
87 public static function provideTestGetMessage() {
88 $timestamp = '20000101000000';
89 $expiry = '20010101000000';
92 'timestamp' => $timestamp,
94 'reason' => 'Test reason.',
98 'timestamp' => $timestamp,
99 'systemBlock' => 'test',
100 'reason' => new Message( 'proxyblockreason' ),
104 'timestamp' => $timestamp,
105 'originalBlocks' => [
106 [ DatabaseBlock
::class, $databaseBlock ],
107 [ SystemBlock
::class, $systemBlock ]
112 'Database block' => [
113 DatabaseBlock
::class,
121 null, // Block not inserted
122 '00:00, 1 (january) 2001',
124 '00:00, 1 (january) 2000',
127 'Database block (autoblock)' => [
128 DatabaseBlock
::class,
130 'timestamp' => $timestamp,
140 null, // Block not inserted
141 '00:00, 1 (january) 2001',
143 '00:00, 1 (january) 2000',
146 'Database block (partial block)' => [
147 DatabaseBlock
::class,
149 'timestamp' => $timestamp,
153 'blockedtext-partial',
159 null, // Block not inserted
160 '00:00, 1 (january) 2001',
162 '00:00, 1 (january) 2000',
165 'System block (type \'test\')' => [
171 '(proxyblockreason)',
177 '00:00, 1 (january) 2000',
180 'System block (type \'test\') with reason parameters' => [
183 'timestamp' => $timestamp,
184 'systemBlock' => 'test',
185 'reason' => new Message( 'softblockrangesreason', [ '1.2.3.4' ] ),
190 '(softblockrangesreason: 1.2.3.4)',
196 '00:00, 1 (january) 2000',
199 'Composite block (original blocks not inserted)' => [
200 CompositeBlock
::class,
202 'blockedtext-composite',
208 '(blockedtext-composite-no-ids)',
211 '00:00, 1 (january) 2000',
218 * @dataProvider provideTestGetMessageCompositeBlocks
220 public function testGetMessageCompositeBlocks( $ids, $expected ) {
221 $block = $this->getMockBuilder( CompositeBlock
::class )
222 ->onlyMethods( [ 'getIdentifier' ] )
224 $block->method( 'getIdentifier' )
225 ->willReturn( $ids );
227 $context = RequestContext
::getMain();
229 $formatter = $this->getBlockErrorFormatter( $context );
230 $this->assertContains(
232 $formatter->getMessage(
235 $context->getLanguage(),
236 $context->getRequest()->getIP()
241 public static function provideTestGetMessageCompositeBlocks() {
243 'All original blocks are system blocks' => [
245 'Your IP address appears in multiple blocklists',
247 'One original block is a database block' => [
249 'Relevant block IDs: #100 (your IP address may also appear in a blocklist)',
251 'Several original blocks are database blocks' => [
253 'Relevant block IDs: #100, #101, #102 (your IP address may also appear in a blocklist)',
259 * @dataProvider provideTestGetMessages
261 public function testGetMessages( $blockClass, $blockData, $expectedKeys ) {
262 $block = $this->makeBlock(
267 $context = $this->getContext();
269 $formatter = $this->getBlockErrorFormatter( $context );
270 $messages = $formatter->getMessages(
276 $this->assertSame( $expectedKeys, array_map( static function ( $message ) {
277 return $message->getKey();
281 public static function provideTestGetMessages() {
282 $timestamp = '20000101000000';
283 $expiry = '20010101000000';
286 'timestamp' => $timestamp,
288 'reason' => 'Test reason.',
292 'timestamp' => $timestamp,
293 'systemBlock' => 'test',
294 'reason' => new Message( 'proxyblockreason' ),
298 'timestamp' => $timestamp,
299 'originalBlocks' => [
300 [ DatabaseBlock
::class, $databaseBlock ],
301 [ SystemBlock
::class, $systemBlock ]
306 'Database block' => [
307 DatabaseBlock
::class,
312 'System block (type \'test\')' => [
315 [ 'systemblockedtext' ],
317 'Composite block (original blocks not inserted)' => [
318 CompositeBlock
::class,
320 [ 'blockedtext', 'systemblockedtext' ],
326 * @param string $blockClass
327 * @param array $blockData
331 private function makeBlock( $blockClass, $blockData ) {
332 foreach ( $blockData['originalBlocks'] ??
[] as $key => $originalBlock ) {
333 $blockData['originalBlocks'][$key] = $this->makeBlock( ...$originalBlock );
336 return new $blockClass( $blockData );