getServiceContainer();
$this->blockActionInfo = $services->getBlockActionInfo();
$this->blockRestrictionStore = $services->getBlockRestrictionStore();
$this->blockTargetFactory = $services->getBlockTargetFactory();
$this->hideUserUtils = $services->getHideUserUtils();
$this->commentStore = $services->getCommentStore();
$this->linkBatchFactory = $services->getLinkBatchFactory();
$this->linkRenderer = $services->getLinkRenderer();
$this->dbProvider = $services->getConnectionProvider();
$this->rowCommentFormatter = $services->getRowCommentFormatter();
$this->specialPageFactory = $services->getSpecialPageFactory();
}
private function getBlockListPager() {
return new BlockListPager(
RequestContext::getMain(),
$this->blockActionInfo,
$this->blockRestrictionStore,
$this->blockTargetFactory,
$this->hideUserUtils,
$this->commentStore,
$this->linkBatchFactory,
$this->linkRenderer,
$this->dbProvider,
$this->rowCommentFormatter,
$this->specialPageFactory,
[]
);
}
/**
* @covers ::formatValue
* @dataProvider formatValueEmptyProvider
* @dataProvider formatValueDefaultProvider
*/
public function testFormatValue( $name, $expected, $row ) {
// Set the time to now so it does not get off during the test.
MWTimestamp::setFakeTime( '20230405060708' );
$value = $row->$name ?? null;
if ( $name === 'bl_timestamp' ) {
// Wrap the expected timestamp in a string with the timestamp in the format
// used by the BlockListPager.
$linkRenderer = $this->getServiceContainer()->getLinkRenderer();
$link = $linkRenderer->makeKnownLink(
$this->specialPageFactory->getTitleForAlias( 'BlockList' ),
MWTimestamp::getInstance( $value )->format( 'H:i, j F Y' ),
[],
[ 'wpTarget' => "#{$row->bl_id}" ],
);
$expected = $link;
}
$pager = $this->getBlockListPager();
$wrappedPager = TestingAccessWrapper::newFromObject( $pager );
$wrappedPager->mCurrentRow = $row;
$formatted = $pager->formatValue( $name, $value );
$this->assertStringMatchesFormat( $expected, $formatted );
}
/**
* Test empty values.
*/
public static function formatValueEmptyProvider() {
$row = (object)[
'bl_id' => 1,
];
return [
[ 'test', 'Unable to format test', $row ],
[ 'bl_timestamp', null, $row ],
[ 'bl_expiry', 'infinite
0 seconds left', $row ],
];
}
/**
* Test the default row values.
*/
public static function formatValueDefaultProvider() {
$row = (object)[
'bt_user' => 0,
'bt_user_text' => null,
'bt_address' => '127.0.0.1',
'bl_id' => 1,
'bl_by_text' => 'Admin',
'bt_auto' => 0,
'bl_anon_only' => 0,
'bl_create_account' => 1,
'bl_enable_autoblock' => 1,
'bl_deleted' => 0,
'bl_block_email' => 0,
'bl_allow_usertalk' => 0,
'bl_sitewide' => 1,
];
return [
[
'test',
'Unable to format test',
$row,
],
[
'bl_timestamp',
'20230405060708',
$row,
],
[
'bl_expiry',
'infinite
0 seconds left',
$row,
],
[
'bl_by',
'Admin%s',
$row,
],
[
'params',
'
- editing (sitewide)
' .
'- account creation disabled
- cannot edit own talk page
',
$row,
]
];
}
/**
* @covers ::formatValue
* @covers ::getRestrictionListHTML
*/
public function testFormatValueRestrictions() {
$this->overrideConfigValues( [
MainConfigNames::Script => '/w/index.php',
] );
$pager = $this->getBlockListPager();
$row = (object)[
'bl_id' => 0,
'bt_user' => 0,
'bl_anon_only' => 0,
'bl_enable_autoblock' => 0,
'bl_create_account' => 0,
'bl_block_email' => 0,
'bl_allow_usertalk' => 1,
'bl_sitewide' => 0,
'bl_deleted' => 0,
];
$wrappedPager = TestingAccessWrapper::newFromObject( $pager );
$wrappedPager->mCurrentRow = $row;
$pageName = 'Victor Frankenstein';
$page = $this->insertPage( $pageName );
$title = $page['title'];
$pageId = $page['id'];
$restrictions = [
( new PageRestriction( 0, $pageId ) )->setTitle( $title ),
new NamespaceRestriction( 0, NS_MAIN ),
// Deleted page.
new PageRestriction( 0, 999999 ),
];
$wrappedPager = TestingAccessWrapper::newFromObject( $pager );
$wrappedPager->restrictions = $restrictions;
$formatted = $pager->formatValue( 'params', '' );
$this->assertEquals( '- '
// FIXME: Expectation value should not be dynamic
// and must not depend on a localisation message.
// TODO: Mock the message or consider using qqx.
. wfMessage( 'blocklist-editing' )->text()
. '
- '
. wfMessage( 'blocklist-editing-page' )->text()
. '
- '
. wfMessage( 'blocklist-editing-ns' )->text()
. '
',
$formatted
);
}
/**
* @covers ::preprocessResults
*/
public function testPreprocessResults() {
// Test the Link Cache.
$linkCache = $this->getServiceContainer()->getLinkCache();
$wrappedlinkCache = TestingAccessWrapper::newFromObject( $linkCache );
$admin = $this->getTestSysop()->getUser();
$links = [
'User:127.0.0.1',
'User_talk:127.0.0.1',
$admin->getUserPage()->getPrefixedDBkey(),
$admin->getTalkPage()->getPrefixedDBkey(),
'Comment_link'
];
foreach ( $links as $link ) {
$this->assertNull( $wrappedlinkCache->entries->get( $link ) );
}
$row = (object)[
'bt_address' => '127.0.0.1',
'bt_user' => null,
'bt_user_text' => null,
'bl_by' => $admin->getId(),
'bl_by_text' => $admin->getName(),
'bl_sitewide' => 1,
'bl_timestamp' => $this->getDb()->timestamp( wfTimestamp( TS_MW ) ),
'bl_reason_text' => '[[Comment link]]',
'bl_reason_data' => null,
];
$pager = $this->getBlockListPager();
$pager->preprocessResults( new FakeResultWrapper( [ $row ] ) );
foreach ( $links as $link ) {
$this->assertTrue( $wrappedlinkCache->isBadLink( $link ), "Bad link [[$link]]" );
}
// Test sitewide blocks.
$row = (object)[
'bt_address' => '127.0.0.1',
'bt_user' => null,
'bt_user_text' => null,
'bl_by' => $admin->getId(),
'bl_by_text' => $admin->getName(),
'bl_sitewide' => 1,
'bl_reason_text' => '',
'bl_reason_data' => null,
];
$pager = $this->getBlockListPager();
$pager->preprocessResults( new FakeResultWrapper( [ $row ] ) );
$this->assertObjectNotHasProperty( 'bl_restrictions', $row );
$page = $this->getExistingTestPage( 'Victor Frankenstein' );
$title = $page->getTitle();
$target = '127.0.0.1';
// Test partial blocks.
$block = $this->getServiceContainer()->getDatabaseBlockStore()
->insertBlockWithParams( [
'address' => $target,
'by' => $this->getTestSysop()->getUser(),
'reason' => 'Parce que',
'expiry' => $this->getDb()->getInfinity(),
'sitewide' => false,
'restrictions' => [
new PageRestriction( 0, $page->getId() ),
]
] );
$pager = $this->getBlockListPager();
$result = $this->getDb()->newSelectQueryBuilder()
->queryInfo( $pager->getQueryInfo() )
->where( [ 'bl_id' => $block->getId() ] )
->caller( __METHOD__ )
->fetchResultSet();
$pager->preprocessResults( $result );
$wrappedPager = TestingAccessWrapper::newFromObject( $pager );
$restrictions = $wrappedPager->restrictions;
$this->assertIsArray( $restrictions );
$restriction = $restrictions[0];
$this->assertEquals( $page->getId(), $restriction->getValue() );
$this->assertEquals( $page->getId(), $restriction->getTitle()->getArticleID() );
$this->assertEquals( $title->getDBkey(), $restriction->getTitle()->getDBkey() );
$this->assertEquals( $title->getNamespace(), $restriction->getTitle()->getNamespace() );
}
/**
* T352310 regression test
* @coversNothing
*/
public function testOffset() {
if ( $this->getDb()->getType() === 'postgres' ) {
$this->markTestSkipped( "PostgreSQL fatals when the first part of " .
"the offset parameter has the wrong timestamp format" );
}
$request = new FauxRequest( [
'offset' => '20231115010645|7'
] );
RequestContext::getMain()->setRequest( $request );
$pager = $this->getBlockListPager();
$pager->getFullOutput();
$this->assertTrue( true );
}
/**
* T385765 regression test
* @coversNothing
*/
public function testAutoblockLeak() {
$sysop = $this->getTestSysop()->getUserIdentity();
$this->overrideConfigValue( MainConfigNames::UseCodexSpecialBlock, true );
// Enable block links
RequestContext::getMain()->setAuthority( new UltimateAuthority( $sysop ) );
// Don't localise
RequestContext::getMain()->setLanguage( 'qqx' );
// Create autoblock
$addr = '127.0.0.1';
$this->getServiceContainer()->getDatabaseBlockStore()
->insertBlockWithParams( [
'address' => $addr,
'auto' => true,
'by' => $sysop
] );
// Run the pager over all blocks (there should only be one)
$pager = $this->getBlockListPager();
$body = $pager->getBody();
// Check that we managed to generate a remove link
$this->assertStringContainsString( '(remove-blocklink)', $body );
// Check that we didn't leak the IP address into it
$this->assertStringNotContainsString( $addr, $body );
}
}