mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/MinervaNeue
synced 2024-12-04 18:48:15 +00:00
5a7a9c9c31
Remove code per spike outcome (T226490#7438685) - This configuration option is never used in Wikimedia production - isTalkAllowed content body is merged into isAllowed. Resulting code is more readable. - isAllowed('talk') still returns false on main page for anonymous users which is the current behavior. Even on sv.m.wikipedia.org where talk pages are shown to anonymous users, we do not show the talk page on the main page. Add a comment pointing to the associated phabricator ticket Bug: T226490 Change-Id: I9f34817c5ad654a6a66fe6156850a3e3fee881a7
334 lines
10 KiB
PHP
334 lines
10 KiB
PHP
<?php
|
|
|
|
namespace Tests\MediaWiki\Minerva;
|
|
|
|
use ContentHandler;
|
|
use MediaWiki\Content\IContentHandlerFactory;
|
|
use MediaWiki\Minerva\LanguagesHelper;
|
|
use MediaWiki\Minerva\Permissions\IMinervaPagePermissions;
|
|
use MediaWiki\Minerva\Permissions\MinervaPagePermissions;
|
|
use MediaWiki\Minerva\SkinOptions;
|
|
use MediaWiki\Permissions\PermissionManager;
|
|
use MediaWiki\Watchlist\WatchlistManager;
|
|
use MediaWikiIntegrationTestCase;
|
|
use RequestContext;
|
|
use Title;
|
|
use User;
|
|
|
|
/**
|
|
* @group MinervaNeue
|
|
* @coversDefaultClass \MediaWiki\Minerva\Permissions\MinervaPagePermissions
|
|
*/
|
|
class MinervaPagePermissionsTest extends MediaWikiIntegrationTestCase {
|
|
|
|
private function buildPermissionsObject(
|
|
Title $title,
|
|
$actions = null, /* unused */
|
|
array $options = [],
|
|
ContentHandler $contentHandler = null,
|
|
User $user = null,
|
|
$hasOtherLanguagesOrVariants = false,
|
|
$alwaysShowLanguageButton = true,
|
|
$isSuperUser = false
|
|
) {
|
|
$languageHelper = $this->createMock( LanguagesHelper::class );
|
|
$languageHelper->expects( $this->any() )
|
|
->method( 'doesTitleHasLanguagesOrVariants' )
|
|
->willReturn( $hasOtherLanguagesOrVariants );
|
|
|
|
$user = $user ?? $this->getTestUser()->getUser();
|
|
$actions = $actions ?? [
|
|
IMinervaPagePermissions::CONTENT_EDIT,
|
|
IMinervaPagePermissions::WATCH,
|
|
IMinervaPagePermissions::TALK,
|
|
IMinervaPagePermissions::SWITCH_LANGUAGE,
|
|
IMinervaPagePermissions::MOVE,
|
|
IMinervaPagePermissions::DELETE,
|
|
IMinervaPagePermissions::PROTECT,
|
|
];
|
|
$contentHandler = $contentHandler ??
|
|
$this->getMockForAbstractClass( ContentHandler::class, [], '', false );
|
|
$skinOptions = new SkinOptions();
|
|
if ( $options ) {
|
|
$skinOptions->setMultiple( $options );
|
|
}
|
|
|
|
$context = new RequestContext();
|
|
$context->setTitle( $title );
|
|
$context->setConfig( new \HashConfig( [
|
|
'MinervaAlwaysShowLanguageButton' => $alwaysShowLanguageButton
|
|
] ) );
|
|
$context->setUser( $user );
|
|
|
|
$permissionManager = $this->getMockBuilder( PermissionManager::class )
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$permissionManager->expects( $this->any() )
|
|
->method( 'quickUserCan' )
|
|
->willReturn( $isSuperUser );
|
|
|
|
$contentHandlerFactory = $this->createMock( IContentHandlerFactory::class );
|
|
|
|
$contentHandlerFactory->expects( $this->any() )
|
|
->method( 'getContentHandler' )
|
|
->willReturn( $contentHandler );
|
|
|
|
return ( new MinervaPagePermissions(
|
|
$skinOptions,
|
|
$languageHelper,
|
|
$permissionManager,
|
|
$contentHandlerFactory
|
|
) )->setContext( $context );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testWatchAndEditNotAllowedOnMainPage() {
|
|
$userMock = $this->getMockBuilder( User::class )
|
|
->disableOriginalConstructor()
|
|
->onlyMethods( [ 'isRegistered' ] )
|
|
->getMock();
|
|
$userMock->expects( $this->once() )
|
|
->method( 'isRegistered' )
|
|
->willReturn( false );
|
|
$permsAnon = $this->buildPermissionsObject( Title::newMainPage(), null, [], null, $userMock );
|
|
$perms = $this->buildPermissionsObject( Title::newMainPage() );
|
|
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::CONTENT_EDIT ) );
|
|
$this->assertFalse( $permsAnon->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
|
|
// Check to make sure 'talk' and 'switch-language' are enabled on the Main page.
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testInvalidPageActionsArentAllowed() {
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'test' ), [] );
|
|
|
|
$this->assertFalse( $perms->isAllowed( 'blah' ) );
|
|
$this->assertFalse( $perms->isAllowed( 'wah' ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testValidPageActionsAreAllowed() {
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'test' ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
|
|
}
|
|
|
|
public static function editPageActionProvider() {
|
|
return [
|
|
[ false, false, false ],
|
|
[ true, false, false ],
|
|
[ true, true, true ]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* The "edit" page action is allowed when the page doesn't support direct editing via the API.
|
|
*
|
|
* @dataProvider editPageActionProvider
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testEditPageAction(
|
|
$supportsDirectEditing,
|
|
$supportsDirectApiEditing,
|
|
$expected
|
|
) {
|
|
$contentHandler = $this->getMockBuilder( ContentHandler::class )
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$contentHandler->method( 'supportsDirectEditing' )
|
|
->will( $this->returnValue( $supportsDirectEditing ) );
|
|
|
|
$contentHandler->method( 'supportsDirectApiEditing' )
|
|
->will( $this->returnValue( $supportsDirectApiEditing ) );
|
|
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'test' ), null, [],
|
|
$contentHandler );
|
|
|
|
$this->assertEquals( $expected, $perms->isAllowed( IMinervaPagePermissions::CONTENT_EDIT ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testPageActionsWhenOnUserPage() {
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'User:Admin' ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testPageActionsWhenOnAnonUserPage() {
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'User:1.1.1.1' ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
}
|
|
|
|
public static function switchLanguagePageActionProvider() {
|
|
return [
|
|
[ true, false, true ],
|
|
[ false, true, true ],
|
|
[ false, false, false ],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* MediaWiki defines wgHideInterlanguageLinks which is default set to false, but some wikis
|
|
* can set this config to true. Minerva page permissions must respect that
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testGlobalHideLanguageLinksTakesPrecedenceOnMainPage() {
|
|
$this->setMwGlobals( [ 'wgHideInterlanguageLinks' => true ] );
|
|
$perms = $this->buildPermissionsObject( Title::newMainPage() );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) );
|
|
}
|
|
|
|
/**
|
|
* MediaWiki defines wgHideInterlanguageLinks which is default set to false, but some wikis
|
|
* can set this config to true. Minerva page permissions must respect that
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testGlobalHideLanguageLinksTakesPrecedence() {
|
|
$this->setMwGlobals( [ 'wgHideInterlanguageLinks' => true ] );
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'test' ) );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) );
|
|
}
|
|
|
|
/**
|
|
* The "switch-language" page action is allowed when: v2 of the page action bar is enabled and
|
|
* if the page has interlanguage links or if the <code>$wgMinervaAlwaysShowLanguageButton</code>
|
|
* configuration variable is set to truthy.
|
|
*
|
|
* @dataProvider switchLanguagePageActionProvider
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testSwitchLanguagePageAction(
|
|
$hasLanguagesOrVariants,
|
|
$minervaAlwaysShowLanguageButton,
|
|
$expected
|
|
) {
|
|
$title = $this->createMock( Title::class );
|
|
$title->expects( $this->once() )
|
|
->method( 'isMainPage' )
|
|
->willReturn( false );
|
|
$title->expects( $this->any() )
|
|
->method( 'getContentModel' )
|
|
->willReturn( CONTENT_MODEL_WIKITEXT );
|
|
|
|
$permissions = $this->buildPermissionsObject(
|
|
$title,
|
|
null,
|
|
[],
|
|
null,
|
|
null,
|
|
$hasLanguagesOrVariants,
|
|
$minervaAlwaysShowLanguageButton
|
|
);
|
|
|
|
$actual = $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE );
|
|
$this->assertEquals( $expected, $actual );
|
|
}
|
|
|
|
/**
|
|
* Watch action requires 'viewmywatchlist' and 'editmywatchlist' permissions
|
|
* to be grated. Verify that isAllowedAction('watch') returns false when user
|
|
* do not have those permissions granted
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testWatchIsAllowedOnlyWhenWatchlistPermissionsAreGranted() {
|
|
$title = Title::newFromText( 'test_watchstar_permissions' );
|
|
|
|
$userMock = $this->getMockBuilder( User::class )
|
|
->disableOriginalConstructor()
|
|
->onlyMethods( [ 'isAllowedAll' ] )
|
|
->getMock();
|
|
$userMock->expects( $this->once() )
|
|
->method( 'isAllowedAll' )
|
|
->with( 'viewmywatchlist', 'editmywatchlist' )
|
|
->willReturn( false );
|
|
|
|
$perms = $this->buildPermissionsObject( $title, null, [], null, $userMock );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
|
|
}
|
|
|
|
/**
|
|
* If Title is not watchable, it cannot be watched
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testCannotWatchNotWatchableTitle() {
|
|
$title = $this->createMock( Title::class );
|
|
$title->expects( $this->once() )
|
|
->method( 'isMainPage' )
|
|
->willReturn( false );
|
|
$title->expects( $this->any() )
|
|
->method( 'getContentModel' )
|
|
->willReturn( CONTENT_MODEL_UNKNOWN );
|
|
|
|
$watchlistManager = $this->createMock( WatchlistManager::class );
|
|
$watchlistManager->expects( $this->once() )
|
|
->method( 'isWatchable' )
|
|
->willReturn( false );
|
|
$this->setService( 'WatchlistManager', $watchlistManager );
|
|
|
|
$permissions = $this->buildPermissionsObject( $title );
|
|
$this->assertFalse( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testMoveAndDeleteAndProtectNotAllowedByDefault() {
|
|
$perms = $this->buildPermissionsObject( Title::newFromText( 'test' ), null );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::MOVE ) );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::DELETE ) );
|
|
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::PROTECT ) );
|
|
}
|
|
|
|
/**
|
|
* @covers ::isAllowed
|
|
*/
|
|
public function testMoveAndDeleteAndProtectAllowedForUserWithPermissions() {
|
|
$title = $this->createMock( Title::class );
|
|
$title->expects( $this->any() )
|
|
->method( 'exists' )
|
|
->willReturn( true );
|
|
$title->expects( $this->any() )
|
|
->method( 'getContentModel' )
|
|
->willReturn( CONTENT_MODEL_WIKITEXT );
|
|
|
|
$perms = $this->buildPermissionsObject(
|
|
$title,
|
|
[
|
|
IMinervaPagePermissions::CONTENT_EDIT,
|
|
IMinervaPagePermissions::WATCH,
|
|
IMinervaPagePermissions::TALK,
|
|
IMinervaPagePermissions::SWITCH_LANGUAGE,
|
|
IMinervaPagePermissions::MOVE,
|
|
IMinervaPagePermissions::DELETE,
|
|
IMinervaPagePermissions::PROTECT,
|
|
],
|
|
[],
|
|
null,
|
|
$this->getTestUser()->getUser(),
|
|
false,
|
|
true,
|
|
true
|
|
);
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::MOVE ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::DELETE ) );
|
|
$this->assertTrue( $perms->isAllowed( IMinervaPagePermissions::PROTECT ) );
|
|
}
|
|
}
|