mediawiki-skins-MinervaNeue/tests/phpunit/permissions/MinervaPagePermissionsTest.php

327 lines
10 KiB
PHP
Raw Normal View History

<?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,
array $actions = null,
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( [
'MinervaPageActions' => $actions,
'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() {
$perms = $this->buildPermissionsObject( Title::newMainPage() );
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::CONTENT_EDIT ) );
// 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' ), [] );
// By default, the "talk" and "watch" page actions are allowed but are now deemed invalid.
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::TALK ) );
$this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
}
/**
* @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' ), [] );
$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 ) );
}
}