+ $blockId = 123;
+ return [
+ 'Block cookie is already set; there is a trackable block' => [
+ [
+ 'cookieSet' => true,
+ 'block' => $this->getTrackableBlock( $blockId ),
+ ],
+ null,
+ ],
+ 'Block cookie is already set; there is no block' => [
+ [
+ 'cookieSet' => true,
+ 'block' => null,
+ ],
+ null,
+ ],
+ 'Block cookie is not yet set; there is no block' => [
+ [
+ 'cookieSet' => false,
+ 'block' => null,
+ ],
+ null,
+ ],
+ 'Block cookie is not yet set; there is a trackable block' => [
+ [
+ 'cookieSet' => false,
+ 'block' => $this->getTrackableBlock( $blockId ),
+ ],
+ $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 ),
+ ]
+ ] ),
+ ],
+ $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(),
+ ]
+ ] ),
+ ],
+ 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->assertEquals(
+ $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() {