Changes to the use statements and some additions are done automatically via script This also updates @covers tag for the namespaced classes Change-Id: I859ba6d05018c99710b744e2becab432410d3bca
195 lines
5.9 KiB
PHP
195 lines
5.9 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Cache\LinkBatchFactory;
|
|
use MediaWiki\CommentFormatter\CommentFormatter;
|
|
use MediaWiki\Context\RequestContext;
|
|
use MediaWiki\HookContainer\HookContainer;
|
|
use MediaWiki\Linker\LinkRenderer;
|
|
use MediaWiki\Pager\DeletedContribsPager;
|
|
use MediaWiki\Revision\RevisionRecord;
|
|
use MediaWiki\Revision\RevisionStore;
|
|
use MediaWiki\Title\NamespaceInfo;
|
|
use MediaWiki\Title\Title;
|
|
use MediaWiki\User\User;
|
|
use MediaWiki\User\UserFactory;
|
|
use MediaWiki\User\UserIdentityValue;
|
|
use Wikimedia\Rdbms\IConnectionProvider;
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
/**
|
|
* @group Database
|
|
* @covers \MediaWiki\Pager\DeletedContribsPager
|
|
*/
|
|
class DeletedContribsPagerTest extends MediaWikiIntegrationTestCase {
|
|
private static User $user;
|
|
|
|
/** @var DeletedContribsPager */
|
|
private $pager;
|
|
|
|
/** @var HookContainer */
|
|
private $hookContainer;
|
|
|
|
/** @var LinkRenderer */
|
|
private $linkRenderer;
|
|
|
|
/** @var IConnectionProvider */
|
|
private $dbProvider;
|
|
|
|
/** @var RevisionStore */
|
|
private $revisionStore;
|
|
|
|
/** @var NamespaceInfo */
|
|
private $namespaceInfo;
|
|
|
|
/** @var CommentFormatter */
|
|
private $commentFormatter;
|
|
|
|
/** @var LinkBatchFactory */
|
|
private $linkBatchFactory;
|
|
|
|
/** @var UserFactory */
|
|
private $userFactory;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$services = $this->getServiceContainer();
|
|
$this->hookContainer = $services->getHookContainer();
|
|
$this->linkRenderer = $services->getLinkRenderer();
|
|
$this->dbProvider = $services->getConnectionProvider();
|
|
$this->revisionStore = $services->getRevisionStore();
|
|
$this->namespaceInfo = $services->getNamespaceInfo();
|
|
$this->commentFormatter = $services->getCommentFormatter();
|
|
$this->linkBatchFactory = $services->getLinkBatchFactory();
|
|
$this->userFactory = $services->getUserFactory();
|
|
$this->pager = $this->getDeletedContribsPager();
|
|
}
|
|
|
|
private function getDeletedContribsPager( $target = 'Some test user', $namespace = 0 ) {
|
|
$target = UserIdentityValue::newAnonymous( $target );
|
|
|
|
return new DeletedContribsPager(
|
|
$this->hookContainer,
|
|
$this->linkRenderer,
|
|
$this->dbProvider,
|
|
$this->revisionStore,
|
|
$this->namespaceInfo,
|
|
$this->commentFormatter,
|
|
$this->linkBatchFactory,
|
|
$this->userFactory,
|
|
RequestContext::getMain(),
|
|
[ 'namespace' => $namespace ],
|
|
$target
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Flow uses DeletedContribsPager::reallyDoQuery hook to provide something other then
|
|
* stdClass as a row, and then manually formats its own row in ContributionsLineEnding.
|
|
* Emulate this behaviour and check that it works.
|
|
*/
|
|
public function testDeletedContribProvidedByHook() {
|
|
$this->setTemporaryHook( 'DeletedContribsPager::reallyDoQuery', static function ( &$data ) {
|
|
$data = [ [ new class() {
|
|
public $ar_timestamp = 12345;
|
|
public $testing = 'TESTING';
|
|
public $ar_namespace = NS_MAIN;
|
|
public $ar_title = 'Test';
|
|
public $ar_rev_id = null;
|
|
} ] ];
|
|
} );
|
|
$this->setTemporaryHook( 'DeletedContributionsLineEnding', function ( $pager, &$ret, $row ) {
|
|
$this->assertSame( 'TESTING', $row->testing );
|
|
$ret .= 'FROM_HOOK!';
|
|
} );
|
|
$pager = $this->getDeletedContribsPager();
|
|
$this->assertStringContainsString( 'FROM_HOOK!', $pager->getBody() );
|
|
}
|
|
|
|
public static function provideEmptyResultIntegration() {
|
|
$cases = [
|
|
[ 'target' => '', 'namespace' => '' ],
|
|
[ 'target' => '127.0.0.1', 'namespace' => '' ],
|
|
[ 'target' => 'UserWithNoEdits', 'namespace' => 1 ],
|
|
];
|
|
foreach ( $cases as $case ) {
|
|
yield [ $case ];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Confirm that the query is valid for various filter options.
|
|
*
|
|
* @dataProvider provideEmptyResultIntegration
|
|
*/
|
|
public function testEmptyResultIntegration( $options ) {
|
|
$pager = $this->getDeletedContribsPager(
|
|
$options['target'],
|
|
$options['namespace'],
|
|
);
|
|
$this->assertIsString( $pager->getBody() );
|
|
$this->assertSame( 0, $pager->getNumRows() );
|
|
}
|
|
|
|
public function testPopulatedIntegrationNoPermissions() {
|
|
$pager = $this->getDeletedContribsPager( self::$user->getName() );
|
|
|
|
$this->assertIsString( $pager->getBody() );
|
|
$this->assertSame( 1, $pager->getNumRows() );
|
|
}
|
|
|
|
public function testPopulatedIntegrationWithPermissions() {
|
|
$this->setGroupPermissions( [ '*' => [
|
|
'deletedhistory' => true,
|
|
'deletedtext' => true,
|
|
'undelete' => true,
|
|
] ] );
|
|
|
|
$pager = $this->getDeletedContribsPager( self::$user->getName() );
|
|
$this->assertIsString( $pager->getBody() );
|
|
$this->assertSame( 2, $pager->getNumRows() );
|
|
$this->assertStringContainsString( '>+9<', $pager->getBody() );
|
|
}
|
|
|
|
public function testParentRevisionSizePreloading() {
|
|
$this->setGroupPermissions( [ '*' => [
|
|
'deletedhistory' => true,
|
|
'deletedtext' => true,
|
|
'undelete' => true,
|
|
] ] );
|
|
|
|
$pager = $this->getDeletedContribsPager( self::$user->getName() );
|
|
// Make sure the query leaves (at least) one row unselected
|
|
// so that we can test loading from parent revision ids
|
|
TestingAccessWrapper::newFromObject( $pager )->deletedOnly = true;
|
|
$this->assertIsString( $pager->getBody() );
|
|
$this->assertSame( 1, $pager->getNumRows() );
|
|
$this->assertStringContainsString( '>+9<', $pager->getBody() );
|
|
}
|
|
|
|
public function addDBDataOnce() {
|
|
self::$user = $this->getTestUser()->getUser();
|
|
$title = Title::makeTitle( NS_MAIN, 'DeletedContribsPagerTest' );
|
|
|
|
// Make two edits (one will be revdel'd)
|
|
$this->editPage( $title, 'Test', '', NS_MAIN, self::$user );
|
|
$status = $this->editPage( $title, 'Test content.', '', NS_MAIN, self::$user );
|
|
|
|
// Delete the page where the edits were made
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
|
$this->deletePage( $page );
|
|
|
|
// Suppress the second edit
|
|
$this->getDb()->newUpdateQueryBuilder()
|
|
->update( 'archive' )
|
|
->set( [
|
|
'ar_deleted' => RevisionRecord::DELETED_USER | RevisionRecord::DELETED_TEXT,
|
|
// This is to ensure the minor edits path doesn't encounter an error
|
|
'ar_minor_edit' => 1,
|
|
] )
|
|
->where( [
|
|
'ar_rev_id' => $status->getNewRevision()->getId()
|
|
] )
|
|
->execute();
|
|
}
|
|
}
|