3 use MediaWiki\Block\BlockManager
;
4 use MediaWiki\Block\DatabaseBlock
;
5 use MediaWiki\Block\SystemBlock
;
10 * @coversDefaultClass \MediaWiki\Block\BlockManager
12 class BlockManagerTest
extends MediaWikiTestCase
{
20 protected function setUp() {
23 $this->user
= $this->getTestUser()->getUser();
24 $this->sysopId
= $this->getTestSysop()->getUser()->getId();
25 $this->blockManagerConfig
= [
26 'wgApplyIpBlocksToXff' => true,
27 'wgCookieSetOnAutoblock' => true,
28 'wgCookieSetOnIpBlock' => true,
29 'wgDnsBlacklistUrls' => [],
30 'wgEnableDnsBlacklist' => true,
32 'wgProxyWhitelist' => [],
33 'wgSecretKey' => false,
34 'wgSoftBlockRanges' => [],
38 private function getBlockManager( $overrideConfig ) {
39 $blockManagerConfig = array_merge( $this->blockManagerConfig
, $overrideConfig );
40 return new BlockManager(
42 $this->user
->getRequest(),
43 ...array_values( $blockManagerConfig )
48 * @dataProvider provideGetBlockFromCookieValue
49 * @covers ::getBlockFromCookieValue
51 public function testGetBlockFromCookieValue( $options, $expected ) {
52 $blockManager = $this->getBlockManager( [
53 'wgCookieSetOnAutoblock' => true,
54 'wgCookieSetOnIpBlock' => true,
57 $block = new DatabaseBlock( array_merge( [
58 'address' => $options[ 'target' ] ?
: $this->user
,
59 'by' => $this->sysopId
,
60 ], $options[ 'blockOptions' ] ) );
63 $class = new ReflectionClass( BlockManager
::class );
64 $method = $class->getMethod( 'getBlockFromCookieValue' );
65 $method->setAccessible( true );
67 $user = $options[ 'loggedIn' ] ?
$this->user
: new User();
68 $user->getRequest()->setCookie( 'BlockID', $block->getCookieValue() );
70 $this->assertSame( $expected, (bool)$method->invoke(
79 public static function provideGetBlockFromCookieValue() {
81 'Autoblocking user block' => [
86 'enableAutoblock' => true
91 'Non-autoblocking user block' => [
99 'IP block for anonymous user' => [
101 'target' => '127.0.0.1',
103 'blockOptions' => [],
107 'IP block for logged in user' => [
109 'target' => '127.0.0.1',
111 'blockOptions' => [],
115 'IP range block for anonymous user' => [
117 'target' => '127.0.0.0/8',
119 'blockOptions' => [],
127 * @dataProvider provideIsLocallyBlockedProxy
128 * @covers ::isLocallyBlockedProxy
130 public function testIsLocallyBlockedProxy( $proxyList, $expected ) {
131 $class = new ReflectionClass( BlockManager
::class );
132 $method = $class->getMethod( 'isLocallyBlockedProxy' );
133 $method->setAccessible( true );
135 $blockManager = $this->getBlockManager( [
136 'wgProxyList' => $proxyList
140 $this->assertSame( $expected, $method->invoke( $blockManager, $ip ) );
143 public static function provideIsLocallyBlockedProxy() {
145 'Proxy list is empty' => [ [], false ],
146 'Proxy list contains IP' => [ [ '1.2.3.4' ], true ],
147 'Proxy list contains IP as value' => [ [ 'test' => '1.2.3.4' ], true ],
148 'Proxy list contains range that covers IP' => [ [ '1.2.3.0/16' ], true ],
153 * @covers ::isLocallyBlockedProxy
155 public function testIsLocallyBlockedProxyDeprecated() {
158 $this->hideDeprecated(
159 'IP addresses in the keys of $wgProxyList (found the following IP ' .
160 'addresses in keys: ' . $proxy . ', please move them to values)'
163 $class = new ReflectionClass( BlockManager
::class );
164 $method = $class->getMethod( 'isLocallyBlockedProxy' );
165 $method->setAccessible( true );
167 $blockManager = $this->getBlockManager( [
168 'wgProxyList' => [ $proxy => 'test' ]
172 $this->assertSame( true, $method->invoke( $blockManager, $ip ) );
176 * @dataProvider provideIsDnsBlacklisted
177 * @covers ::isDnsBlacklisted
178 * @covers ::inDnsBlacklist
180 public function testIsDnsBlacklisted( $options, $expected ) {
181 $blockManagerConfig = array_merge( $this->blockManagerConfig
, [
182 'wgEnableDnsBlacklist' => true,
183 'wgDnsBlacklistUrls' => $options['blacklist'],
184 'wgProxyWhitelist' => $options['whitelist'],
187 $blockManager = $this->getMockBuilder( BlockManager
::class )
188 ->setConstructorArgs(
191 $this->user
->getRequest(),
192 ], $blockManagerConfig ) )
193 ->setMethods( [ 'checkHost' ] )
196 $blockManager->expects( $this->any() )
197 ->method( 'checkHost' )
198 ->will( $this->returnValueMap( [ [
199 $options['dnsblQuery'],
200 $options['dnsblResponse'],
205 $blockManager->isDnsBlacklisted( $options['ip'], $options['checkWhitelist'] )
209 public static function provideIsDnsBlacklisted() {
210 $dnsblFound = [ '127.0.0.2' ];
211 $dnsblNotFound = false;
213 'IP is blacklisted' => [
215 'blacklist' => [ 'dnsbl.test' ],
217 'dnsblQuery' => '1.0.0.127.dnsbl.test',
218 'dnsblResponse' => $dnsblFound,
220 'checkWhitelist' => false,
224 'IP is blacklisted; blacklist has key' => [
226 'blacklist' => [ [ 'dnsbl.test', 'key' ] ],
228 'dnsblQuery' => 'key.1.0.0.127.dnsbl.test',
229 'dnsblResponse' => $dnsblFound,
231 'checkWhitelist' => false,
235 'IP is blacklisted; blacklist is array' => [
237 'blacklist' => [ [ 'dnsbl.test' ] ],
239 'dnsblQuery' => '1.0.0.127.dnsbl.test',
240 'dnsblResponse' => $dnsblFound,
242 'checkWhitelist' => false,
246 'IP is not blacklisted' => [
248 'blacklist' => [ 'dnsbl.test' ],
250 'dnsblQuery' => '4.3.2.1.dnsbl.test',
251 'dnsblResponse' => $dnsblNotFound,
253 'checkWhitelist' => false,
257 'Blacklist is empty' => [
261 'dnsblQuery' => '1.0.0.127.dnsbl.test',
262 'dnsblResponse' => $dnsblFound,
264 'checkWhitelist' => false,
268 'IP is blacklisted and whitelisted; whitelist is not checked' => [
270 'blacklist' => [ 'dnsbl.test' ],
272 'dnsblQuery' => '1.0.0.127.dnsbl.test',
273 'dnsblResponse' => $dnsblFound,
274 'whitelist' => [ '127.0.0.1' ],
275 'checkWhitelist' => false,
279 'IP is blacklisted and whitelisted; whitelist is checked' => [
281 'blacklist' => [ 'dnsbl.test' ],
283 'dnsblQuery' => '1.0.0.127.dnsbl.test',
284 'dnsblResponse' => $dnsblFound,
285 'whitelist' => [ '127.0.0.1' ],
286 'checkWhitelist' => true,
294 * @covers ::getUniqueBlocks
296 public function testGetUniqueBlocks() {
299 $class = new ReflectionClass( BlockManager
::class );
300 $method = $class->getMethod( 'getUniqueBlocks' );
301 $method->setAccessible( true );
303 $blockManager = $this->getBlockManager( [] );
305 $block = $this->getMockBuilder( DatabaseBlock
::class )
306 ->setMethods( [ 'getId' ] )
308 $block->expects( $this->any() )
310 ->willReturn( $blockId );
312 $autoblock = $this->getMockBuilder( DatabaseBlock
::class )
313 ->setMethods( [ 'getParentBlockId', 'getType' ] )
315 $autoblock->expects( $this->any() )
316 ->method( 'getParentBlockId' )
317 ->willReturn( $blockId );
318 $autoblock->expects( $this->any() )
319 ->method( 'getType' )
320 ->willReturn( DatabaseBlock
::TYPE_AUTO
);
322 $blocks = [ $block, $block, $autoblock, new SystemBlock() ];
324 $this->assertSame( 2, count( $method->invoke( $blockManager, $blocks ) ) );
328 * @covers ::trackBlockWithCookie
329 * @dataProvider provideTrackBlockWithCookie
330 * @param bool $expectCookieSet
331 * @param bool $hasCookie
332 * @param bool $isBlocked
334 public function testTrackBlockWithCookie( $expectCookieSet, $hasCookie, $isBlocked ) {
336 $this->setMwGlobals( 'wgCookiePrefix', '' );
338 $request = new FauxRequest();
340 $request->setCookie( 'BlockID', 'the value does not matter' );
344 $block = $this->getMockBuilder( DatabaseBlock
::class )
345 ->setMethods( [ 'getType', 'getId' ] )
347 $block->method( 'getType' )
348 ->willReturn( DatabaseBlock
::TYPE_IP
);
349 $block->method( 'getId' )
350 ->willReturn( $blockID );
355 $user = $this->getMockBuilder( User
::class )
356 ->setMethods( [ 'getBlock', 'getRequest' ] )
358 $user->method( 'getBlock' )
359 ->willReturn( $block );
360 $user->method( 'getRequest' )
361 ->willReturn( $request );
362 /** @var User $user */
364 // Although the block cookie is set via DeferredUpdates, in command line mode updates are
365 // processed immediately
366 $blockManager = $this->getBlockManager( [] );
367 $blockManager->trackBlockWithCookie( $user );
369 /** @var FauxResponse $response */
370 $response = $request->response();
371 $this->assertCount( $expectCookieSet ?
1 : 0, $response->getCookies() );
372 $this->assertEquals( $expectCookieSet ?
$blockID : null, $response->getCookie( 'BlockID' ) );
375 public function provideTrackBlockWithCookie() {
377 // $expectCookieSet, $hasCookie, $isBlocked
378 [ false, false, false ],
379 [ false, true, false ],
380 [ true, false, true ],
381 [ false, true, true ],