wiki.techinc.nl/tests/phpunit/includes/specials/SpecialRecentchangesTest.php
Petr Pchelko e50ccd0512 Fix order of joins in SpecialRecentChanges
After I4d6c175c637a2cb26c63e0b2b27d5ea8ce6b1e0d
some of the filter joins are applied to the query before
the RecentChange joins. Since filter joins depend on actor,
and RecentChange query is the one adding actor joins,
we need to reorder them.

Bug: T281981
Change-Id: Ifbdb24ff5b99b9ec12cb313c48227563696c48c9
2021-05-05 09:29:40 -07:00

169 lines
5.2 KiB
PHP

<?php
use MediaWiki\MediaWikiServices;
use MediaWiki\Tests\Unit\Permissions\MockAuthorityTrait;
use Wikimedia\TestingAccessWrapper;
/**
* Test class for SpecialRecentchanges class
*
* @group Database
*
* @covers SpecialRecentChanges
* @covers ChangesListSpecialPage
*/
class SpecialRecentchangesTest extends AbstractChangesListSpecialPageTestCase {
use MockAuthorityTrait;
protected function getPage(): SpecialRecentChanges {
return new SpecialRecentChanges(
$this->getServiceContainer()->getWatchedItemStore(),
$this->getServiceContainer()->getMessageCache(),
$this->getServiceContainer()->getDBLoadBalancer(),
$this->getServiceContainer()->getUserOptionsLookup()
);
}
/**
* @return TestingAccessWrapper
*/
protected function getPageAccessWrapper() {
return TestingAccessWrapper::newFromObject( $this->getPage() );
}
// Below providers should only be for features specific to
// RecentChanges. Otherwise, it should go in ChangesListSpecialPageTest
public function provideParseParameters() {
return [
[ 'limit=123', [ 'limit' => '123' ] ],
[ '234', [ 'limit' => '234' ] ],
[ 'days=3', [ 'days' => '3' ] ],
[ 'days=0.25', [ 'days' => '0.25' ] ],
[ 'namespace=5', [ 'namespace' => '5' ] ],
[ 'namespace=5|3', [ 'namespace' => '5|3' ] ],
[ 'tagfilter=foo', [ 'tagfilter' => 'foo' ] ],
[ 'tagfilter=foo;bar', [ 'tagfilter' => 'foo;bar' ] ],
];
}
public function validateOptionsProvider() {
return [
[
// hidebots=1 is default for Special:RecentChanges
[ 'hideanons' => 1, 'hideliu' => 1 ],
true,
[ 'hideliu' => 1 ],
false,
],
];
}
public function testAddWatchlistJoins() {
// Edit a test page so that it shows up in RC.
$testPage = $this->getExistingTestPage( 'Test page' );
$this->editPage( $testPage, 'Test content', '' );
// Set up RC.
$context = new RequestContext;
$context->setTitle( Title::newFromText( __METHOD__ ) );
$context->setUser( $this->getTestUser()->getUser() );
$context->setRequest( new FauxRequest );
// Confirm that the test page is in RC.
$rc1 = $this->getPage();
$rc1->setContext( $context );
$rc1->execute( null );
$this->assertStringContainsString( 'Test page', $rc1->getOutput()->getHTML() );
$this->assertStringContainsString( 'mw-changeslist-line-not-watched', $rc1->getOutput()->getHTML() );
// Watch the page, and check that it's now watched in RC.
$watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore();
$watchedItemStore->addWatch( $context->getUser(), $testPage );
$rc2 = $this->getPage();
$rc2->setContext( $context );
$rc2->execute( null );
$this->assertStringContainsString( 'Test page', $rc2->getOutput()->getHTML() );
$this->assertStringContainsString( 'mw-changeslist-line-watched', $rc2->getOutput()->getHTML() );
// Force a past expiry date on the watchlist item.
$db = wfGetDB( DB_PRIMARY );
$queryConds = [ 'wl_namespace' => $testPage->getNamespace(), 'wl_title' => $testPage->getDBkey() ];
$watchedItemId = $db->selectField( 'watchlist', 'wl_id', $queryConds, __METHOD__ );
$db->update(
'watchlist_expiry',
[ 'we_expiry' => $db->timestamp( '20200101000000' ) ],
[ 'we_item' => $watchedItemId ],
__METHOD__
);
// Check that the page is still in RC, but that it's no longer watched.
$rc3 = $this->getPage();
$rc3->setContext( $context );
$rc3->execute( null );
$this->assertStringContainsString( 'Test page', $rc3->getOutput()->getHTML() );
$this->assertStringContainsString( 'mw-changeslist-line-not-watched', $rc3->getOutput()->getHTML() );
}
public function testExperienceLevelFilter() {
// Edit a test page so that it shows up in RC.
$testPage = $this->getExistingTestPage( 'Experience page' );
$this->editPage( $testPage, 'Registered content',
'registered summary', NS_MAIN, $this->getTestUser()->getUser() );
$this->editPage( $testPage, 'Anon content',
'anon summary', NS_MAIN, $this->mockAnonUltimateAuthority() );
// Set up RC.
$context = new RequestContext;
$context->setTitle( Title::newFromText( __METHOD__ ) );
$context->setUser( $this->getTestUser()->getUser() );
$context->setRequest( new FauxRequest );
// Confirm that the test page is in RC.
[ $html ] = ( new SpecialPageExecutor() )->executeSpecialPage(
$this->getPage(),
'',
new FauxRequest()
);
$this->assertStringContainsString( 'Experience page', $html );
// newcomer
$req = new FauxRequest();
$req->setVal( 'userExpLevel', 'newcomer' );
[ $html ] = ( new SpecialPageExecutor() )->executeSpecialPage(
$this->getPage(),
'',
$req
);
$this->assertStringContainsString( 'registered summary', $html );
// anon
$req = new FauxRequest();
$req->setVal( 'userExpLevel', 'unregistered' );
[ $html ] = ( new SpecialPageExecutor() )->executeSpecialPage(
$this->getPage(),
'',
$req
);
$this->assertStringContainsString( 'anon summary', $html );
$this->assertStringNotContainsString( 'registered summary', $html );
// registered
$req = new FauxRequest();
$req->setVal( 'userExpLevel', 'registered' );
[ $html ] = ( new SpecialPageExecutor() )->executeSpecialPage(
$this->getPage(),
'',
$req
);
$this->assertStringContainsString( 'registered summary', $html );
$this->assertStringNotContainsString( 'anon summary', $html );
}
}