diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 73a7465..ef3b2ff 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -23,13 +23,13 @@ use MediaWiki\MediaWikiServices; use MediaWiki\Minerva\Menu\Definitions; use MediaWiki\Minerva\Menu\Main as MainMenu; use MediaWiki\Minerva\Menu\PageActions as PageActionsMenu; +use MediaWiki\Minerva\Permissions\IMinervaPagePermissions; +use MediaWiki\Minerva\Permissions\MinervaPagePermissions; +use MediaWiki\Minerva\Permissions\MinervaNoPagePermissions; use MediaWiki\Minerva\SkinOptions; use MediaWiki\Minerva\SkinUserPageHelper; return [ - 'Minerva.ContentHandler' => function () { - return ContentHandler::getForTitle( RequestContext::getMain()->getTitle() ); - }, 'Minerva.Menu.MainDirector' => function ( MediaWikiServices $services ) { $context = RequestContext::getMain(); /** @var SkinOptions $options */ @@ -51,14 +51,13 @@ return [ */ $skinOptions = $services->getService( 'Minerva.SkinOptions' ); $context = RequestContext::getMain(); - $skin = $context->getSkin(); $userPageHelper = $services->getService( 'Minerva.SkinUserPageHelper' ); $toolbarBuilder = new PageActionsMenu\ToolbarBuilder( - $skin, $context->getTitle(), $context->getUser(), $context, - $services->getPermissionManager() + $services->getPermissionManager(), + $services->getService( 'Minerva.Permissions' ) ); if ( $skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU ) ) { $overflowBuilder = $userPageHelper->isUserPage() ? @@ -85,5 +84,25 @@ return [ }, 'Minerva.SkinOptions' => function () { return new SkinOptions(); + }, + 'Minerva.Permissions' => function ( MediaWikiServices $services ): IMinervaPagePermissions { + $context = RequestContext::getMain(); + $title = $context->getTitle(); + + // Title may be undefined in certain contexts (T179833) + if ( $title ) { + $contentHandler = ContentHandler::getForTitle( $title ); + + return new MinervaPagePermissions( + $context->getTitle(), + $context->getConfig(), + $context->getUser(), + $context->getOutput(), + $services->getService( 'Minerva.SkinOptions' ), + $contentHandler + ); + } else { + return new MinervaNoPagePermissions(); + } } ]; diff --git a/includes/menu/PageActions/ToolbarBuilder.php b/includes/menu/PageActions/ToolbarBuilder.php index b1f22be..2e1bbeb 100644 --- a/includes/menu/PageActions/ToolbarBuilder.php +++ b/includes/menu/PageActions/ToolbarBuilder.php @@ -24,6 +24,7 @@ use ExtensionRegistry; use Hooks; use MediaWiki\Minerva\Menu\Group; use MediaWiki\Minerva\Menu\LanguageSelectorEntry; +use MediaWiki\Minerva\Permissions\IMinervaPagePermissions; use MediaWiki\Permissions\PermissionManager; use MessageLocalizer; use MinervaUI; @@ -44,16 +45,14 @@ class ToolbarBuilder { * @var Title Article title user is currently browsing */ private $title; - /** - * Temporary variable to access isAllowedPageAction() method. - * FIXME: Create MinervaAllowedPageActions service - * @var SkinMinerva user skin - */ - private $skin; /** * @var MessageLocalizer Message localizer to generate localized texts */ private $messageLocalizer; + /** + * @var IMinervaPagePermissions + */ + private $permissions; /** * @var PermissionManager @@ -61,19 +60,23 @@ class ToolbarBuilder { private $permissionsManager; /** * Build Group containing icons for toolbar - * @param SkinMinerva $skin User Skin * @param Title $title Article title user is currently browsing * @param User $user Currently logged in user * @param MessageLocalizer $msgLocalizer Message localizer to generate localized texts * @param PermissionManager $permissionManager Mediawiki Permissions Manager + * @param IMinervaPagePermissions $permissions Minerva permissions system */ - public function __construct( SkinMinerva $skin, Title $title, User $user, - MessageLocalizer $msgLocalizer, PermissionManager $permissionManager ) { - $this->skin = $skin; + public function __construct( + Title $title, + User $user, + MessageLocalizer $msgLocalizer, + PermissionManager $permissionManager, + IMinervaPagePermissions $permissions ) { $this->title = $title; $this->user = $user; $this->messageLocalizer = $msgLocalizer; $this->permissionsManager = $permissionManager; + $this->permissions = $permissions; } /** @@ -84,25 +87,25 @@ class ToolbarBuilder { */ public function getGroup( $doesPageHaveLanguages ) { $group = new Group(); + $permissions = $this->permissions; - if ( $this->skin->isAllowedPageAction( 'switch-language' ) ) { - $group->insertEntry( - new LanguageSelectorEntry( $this->title, $doesPageHaveLanguages, $this->messageLocalizer ) - ); + if ( $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) { + $group->insertEntry( new LanguageSelectorEntry( $this->title, $doesPageHaveLanguages, + $this->messageLocalizer ) ); } - if ( $this->skin->isAllowedPageAction( 'watch' ) ) { + if ( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) ) { $group->insertEntry( $this->createWatchPageAction() ); } - if ( $this->skin->isAllowedPageAction( 'history' ) ) { + if ( $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) { $group->insertEntry( $this->getHistoryPageAction() ); } Hooks::run( 'MobileMenu', [ 'pageactions.toolbar', &$group ] ); // We want the edit icon/action always to be the last element on the toolbar list - if ( $this->skin->isAllowedPageAction( 'edit' ) ) { + if ( $permissions->isAllowed( IMinervaPagePermissions::EDIT ) ) { $group->insertEntry( $this->createEditPageAction() ); } return $group; diff --git a/includes/permissions/IMinervaPagePermissions.php b/includes/permissions/IMinervaPagePermissions.php new file mode 100644 index 0000000..751f116 --- /dev/null +++ b/includes/permissions/IMinervaPagePermissions.php @@ -0,0 +1,48 @@ +title = $title; + $this->config = $config; + $this->user = $user; + $this->output = $output; + $this->skinOptions = $skinOptions; + $this->contentHandler = $contentHandler; + } + + /** + * Gets whether or not the action is allowed. + * + * Actions isn't allowed when: + *
MinervaPageActions
+ * configuration variable; or
+ * $wgMinervaAlwaysShowLanguageButton
is truthy.
+ *
+ * @inheritDoc
+ * @throws ConfigException
+ */
+ public function isAllowed( $action ) {
+ // T206406: Enable "Talk" or "Discussion" button on Main page, also, not forgetting
+ // the "switch-language" button. But disable "edit" and "watch" actions.
+ if ( $this->title->isMainPage() ) {
+ return ( in_array( $action, $this->config->get( 'MinervaPageActions' ) )
+ && ( $action === self::TALK || $action === self::SWITCH_LANGUAGE ) );
+ }
+
+ if ( $action === self::HISTORY && $this->title->exists() ) {
+ return $this->skinOptions->get( SkinOptions::OPTIONS_HISTORY_PAGE_ACTIONS );
+ }
+
+ if ( $action === SkinOptions::OPTION_OVERFLOW_SUBMENU ) {
+ return $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU );
+ }
+
+ if ( !in_array( $action, $this->config->get( 'MinervaPageActions' ) ) ) {
+ return false;
+ }
+
+ if ( $action === self::EDIT ) {
+ return $this->isCurrentPageContentModelEditable();
+ }
+
+ if ( $action === self::WATCH ) {
+ return $this->title->isWatchable()
+ ? $this->user->isAllowedAll( 'viewmywatchlist', 'editmywatchlist' )
+ : false;
+ }
+
+ if ( $action === self::SWITCH_LANGUAGE ) {
+ $hasVariants = $this->title->getPageLanguage()->hasVariants();
+ $hasLanguages = count( $this->output->getLanguageLinks() );
+
+ return $hasVariants || $hasLanguages ||
+ $this->config->get( 'MinervaAlwaysShowLanguageButton' );
+ }
+ return true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function isTalkAllowed() {
+ return $this->isAllowed( self::TALK ) &&
+ ( $this->title->isTalkPage() || $this->title->canHaveTalkPage() ) &&
+ $this->user->isLoggedIn();
+ }
+
+ /**
+ * Checks whether the editor can handle the existing content handler type.
+ *
+ * @return bool
+ */
+ protected function isCurrentPageContentModelEditable() {
+ return $this->contentHandler->supportsDirectEditing()
+ && $this->contentHandler->supportsDirectApiEditing();
+ }
+
+}
diff --git a/includes/skins/SkinMinerva.php b/includes/skins/SkinMinerva.php
index d52e94e..7f036a5 100644
--- a/includes/skins/SkinMinerva.php
+++ b/includes/skins/SkinMinerva.php
@@ -20,6 +20,7 @@
use MediaWiki\MediaWikiServices;
use MediaWiki\Minerva\Menu\Main\Director as MainMenuDirector;
+use MediaWiki\Minerva\Permissions\IMinervaPagePermissions;
use MediaWiki\Minerva\SkinOptions;
use MediaWiki\Minerva\SkinUserPageHelper;
@@ -44,6 +45,13 @@ class SkinMinerva extends SkinTemplate {
/** @var SkinOptions */
private $skinOptions;
+ /**
+ * This variable is lazy loaded, please use getPermissions() getter
+ * @see SkinMinerva::getPermissions()
+ * @var IMinervaPagePermissions
+ */
+ private $permissions;
+
/**
* Initialize Minerva Skin
*/
@@ -52,6 +60,20 @@ class SkinMinerva extends SkinTemplate {
$this->skinOptions = MediaWikiServices::getInstance()->getService( 'Minerva.SkinOptions' );
}
+ /**
+ * Lazy load the permissions object. We don't want to initialize it as it requires many
+ * dependencies, sometimes some of those dependencies cannot be fulfilled (like missing Title
+ * object)
+ * @return IMinervaPagePermissions
+ */
+ private function getPermissions() {
+ if ( $this->permissions === null ) {
+ $this->permissions = MediaWikiServices::getInstance()
+ ->getService( 'Minerva.Permissions' );
+ }
+ return $this->permissions;
+ }
+
/**
* Initalized main menu. Please use getter.
* @return MainMenuDirector
@@ -189,70 +211,6 @@ class SkinMinerva extends SkinTemplate {
}
}
- /**
- * Gets whether or not the page action is allowed.
- *
- * Page actions isn't allowed when:
- * MinervaPageActions
- * configuration variable; or
- * $wgMinervaAlwaysShowLanguageButton
- * is truthy.
- *
- * @param string $action
- * @return bool
- */
- public function isAllowedPageAction( $action ) {
- $title = $this->getTitle();
- $config = $this->getConfig();
- // Title may be undefined in certain contexts (T179833)
- if ( !$title ) {
- return false;
- }
-
- // T206406: Enable "Talk" or "Discussion" button on Main page, also, not forgetting
- // the "switch-language" button. But disable "edit" and "watch" actions.
- if ( $title->isMainPage() ) {
- return ( in_array( $action, $config->get( 'MinervaPageActions' ) )
- && ( $action === 'talk' || $action === 'switch-language' ) );
- }
-
- if ( $action === 'history' && $title->exists() ) {
- return $this->skinOptions->get( SkinOptions::OPTIONS_HISTORY_PAGE_ACTIONS );
- }
-
- if ( $action === SkinOptions::OPTION_OVERFLOW_SUBMENU ) {
- return $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU );
- }
-
- if ( !in_array( $action, $config->get( 'MinervaPageActions' ) ) ) {
- return false;
- }
-
- if ( $action === 'edit' ) {
- return $this->isCurrentPageContentModelEditable();
- }
-
- if ( $action === 'watch' ) {
- return $this->getUser()->isAllowedAll( 'viewmywatchlist', 'editmywatchlist' );
- }
-
- if ( $action === 'switch-language' ) {
- return $this->doesPageHaveLanguages || $config->get( 'MinervaAlwaysShowLanguageButton' );
- }
-
- return true;
- }
-
/**
* Overrides Skin::doEditSectionLink
* @param Title $nt
@@ -262,7 +220,8 @@ class SkinMinerva extends SkinTemplate {
* @return string
*/
public function doEditSectionLink( Title $nt, $section, $tooltip, Language $lang ) {
- if ( $this->isAllowedPageAction( 'edit' ) && !$nt->isMainPage() ) {
+ if ( $this->getPermissions()->isAllowed( IMinervaPagePermissions::EDIT ) &&
+ !$nt->isMainPage() ) {
$message = $this->msg( 'mobile-frontend-editor-edit' )->inLanguage( $lang )->text();
$html = Html::openElement( 'span', [ 'class' => 'mw-editsection' ] );
$html .= Html::element( 'a', [
@@ -790,7 +749,7 @@ class SkinMinerva extends SkinTemplate {
$subjectPage->isMainPage();
$namespaces = $tpl->data['content_navigation']['namespaces'];
if ( !$this->getUserPageHelper()->isUserPage()
- && $this->isTalkAllowed() && $talkAtBottom
+ && $this->getPermissions()->isTalkAllowed() && $talkAtBottom
) {
// FIXME [core]: This seems unnecessary..
$subjectId = $title->getNamespaceKey( '' );
@@ -852,19 +811,6 @@ class SkinMinerva extends SkinTemplate {
return [];
}
- /**
- * Checks whether the editor can handle the existing content handler type.
- *
- * @return bool
- */
- protected function isCurrentPageContentModelEditable() {
- $contentHandler = MediaWikiServices::getInstance()
- ->getService( 'Minerva.ContentHandler' );
-
- return $contentHandler->supportsDirectEditing()
- && $contentHandler->supportsDirectApiEditing();
- }
-
/**
* Returns array of config variables that should be added only to this skin
* for use in JavaScript.
@@ -880,17 +826,6 @@ class SkinMinerva extends SkinTemplate {
return $vars;
}
- /**
- * Returns true, if the page can have a talk page and user is logged in.
- * @return bool
- */
- protected function isTalkAllowed() {
- $title = $this->getTitle();
- return $this->isAllowedPageAction( 'talk' ) &&
- ( $title->isTalkPage() || $title->canHaveTalkPage() ) &&
- $this->getUser()->isLoggedIn();
- }
-
/**
* Returns true, if the talk page of this page is wikitext-based.
* @return bool
@@ -912,7 +847,7 @@ class SkinMinerva extends SkinTemplate {
$user = $this->getUser();
$title = $this->getTitle();
- if ( !$title->isSpecialPage() && $this->isAllowedPageAction( 'watch' ) ) {
+ if ( $this->getPermissions()->isAllowed( IMinervaPagePermissions::WATCH ) ) {
// Explicitly add the mobile watchstar code.
$modules[] = 'skins.minerva.watchstar';
}
@@ -924,7 +859,7 @@ class SkinMinerva extends SkinTemplate {
// TalkOverlay feature
if (
$this->getUserPageHelper()->isUserPage() ||
- ( $this->isTalkAllowed() || $title->isTalkPage() ) &&
+ ( $this->getPermissions()->isTalkAllowed() || $title->isTalkPage() ) &&
$this->isWikiTextTalkPage()
) {
$modules[] = 'skins.minerva.talk';
diff --git a/skin.json b/skin.json
index 62a5768..c5317b3 100644
--- a/skin.json
+++ b/skin.json
@@ -73,7 +73,8 @@
"minerva": "MinervaNeue"
},
"AutoloadNamespaces": {
- "MediaWiki\\Minerva\\Menu\\": "includes/menu/"
+ "MediaWiki\\Minerva\\Menu\\": "includes/menu/",
+ "MediaWiki\\Minerva\\Permissions\\": "includes/permissions/"
},
"AutoloadClasses": {
"MinervaUI": "includes/MinervaUI.php",
diff --git a/tests/phpunit/permissions/MinervaPagePermissionsTest.php b/tests/phpunit/permissions/MinervaPagePermissionsTest.php
new file mode 100644
index 0000000..0e7c072
--- /dev/null
+++ b/tests/phpunit/permissions/MinervaPagePermissionsTest.php
@@ -0,0 +1,237 @@
+getOutput();
+
+ $user = $user ?? $this->getTestUser()->getUser();
+ $actions = $actions ?? [
+ IMinervaPagePermissions::EDIT,
+ IMinervaPagePermissions::WATCH,
+ IMinervaPagePermissions::TALK,
+ IMinervaPagePermissions::SWITCH_LANGUAGE,
+ ];
+
+ $contentHandler = $contentHandler ??
+ $this->getMockForAbstractClass( ContentHandler::class, [], '', false );
+ $skinOptions = new SkinOptions();
+ if ( $options ) {
+ $skinOptions->setMultiple( $options );
+ }
+
+ return new MinervaPagePermissions(
+ $title,
+ new \HashConfig( [
+ 'MinervaPageActions' => $actions,
+ 'MinervaAlwaysShowLanguageButton' => $alwaysShowLanguageButton
+ ] ),
+ $user,
+ $outputPage,
+ $skinOptions,
+ $contentHandler
+ );
+ }
+
+ /**
+ * @covers ::isAllowed
+ */
+ public function testWatchAndEditNotAllowedOnMainPage() {
+ $perms = $this->buildPermissionsObject( Title::newMainPage() );
+
+ $this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::WATCH ) );
+ $this->assertFalse( $perms->isAllowed( IMinervaPagePermissions::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' )
+ ->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::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, true, false, true ],
+ [ false, false, true, true ],
+ [ false, false, false, false ],
+ [ true, false, false, true ],
+ ];
+ }
+
+ /**
+ * 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 $wgMinervaAlwaysShowLanguageButton
+ * configuration variable is set to truthy.
+ *
+ * @dataProvider switchLanguagePageActionProvider
+ * @covers ::isAllowed
+ */
+ public function testSwitchLanguagePageAction(
+ $hasLanguages,
+ $hasVariants,
+ $minervaAlwaysShowLanguageButton,
+ $expected
+ ) {
+ $out = RequestContext::getMain()->getOutput();
+ $out->setLanguageLinks( $hasLanguages ? [ 'pl:StronaTestowa', 'en:TestPage' ] : [] );
+
+ $languageMock = $this->getMock( \Language::class, [ 'hasVariants' ], [], '', false );
+ $languageMock->expects( $this->once() )
+ ->method( 'hasVariants' )
+ ->willReturn( $hasVariants );
+ $title = $this->getMock( Title::class, [ 'isMainPage', 'getPageLanguage' ] );
+ $title->expects( $this->once() )
+ ->method( 'isMainPage' )
+ ->willReturn( false );
+ $title->expects( $this->once() )
+ ->method( 'getPageLanguage' )
+ ->willReturn( $languageMock );
+
+ $permissions = $this->buildPermissionsObject(
+ $title,
+ null,
+ [],
+ null,
+ null,
+ $out,
+ $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' )
+ ->disableOriginalConstructor()
+ ->setMethods( [ '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->getMock( Title::class, [ 'isMainPage', 'isWatchable' ] );
+ $title->expects( $this->once() )
+ ->method( 'isMainPage' )
+ ->willReturn( false );
+ $title->expects( $this->once() )
+ ->method( 'isWatchable' )
+ ->willReturn( false );
+
+ $permissions = $this->buildPermissionsObject( $title );
+ $this->assertEquals( false, $permissions->isAllowed( IMinervaPagePermissions::WATCH ) );
+ }
+
+}
diff --git a/tests/phpunit/skins/SkinMinervaPageActionsTest.php b/tests/phpunit/skins/SkinMinervaPageActionsTest.php
deleted file mode 100644
index 3c2db8d..0000000
--- a/tests/phpunit/skins/SkinMinervaPageActionsTest.php
+++ /dev/null
@@ -1,222 +0,0 @@
-doesPageHaveLanguages = $doesPageHaveLanguages;
- }
-
-}
-
-/**
- * @group MinervaNeue
- */
-class SkinMinervaPageActionsTest extends MediaWikiTestCase {
-
- /**
- * @var TestSkinMinerva
- */
- private $skin;
-
- protected function setUp() {
- parent::setUp();
-
- $this->skin = $this->getSkin( Title::newFromText( 'SkinMinervaPageActionsTest' ) );
- }
-
- /**
- * @param Title $title
- * @return TestSkinMinerva
- */
- private function getSkin( Title $title ) {
- $requestContext = RequestContext::getMain();
- $requestContext->setTitle( $title );
-
- $result = new TestSkinMinerva();
- $result->setContext( $requestContext );
-
- return $result;
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testPageActionsArentAllowedWhenOnTheMainPage() {
- $skin = $this->getSkin( Title::newMainPage() );
-
- $this->assertFalse( $skin->isAllowedPageAction( 'watch' ) );
- $this->assertFalse( $skin->isAllowedPageAction( 'edit' ) );
-
- // Check to make sure 'talk' and 'switch-language' are enabled on the Main page.
- $this->assertTrue( $skin->isAllowedPageAction( 'talk' ) );
- $this->assertTrue( $skin->isAllowedPageAction( 'switch-language' ) );
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testInvalidPageActionsArentAllowed() {
- $this->setMwGlobals( 'wgMinervaPageActions', [] );
-
- // By default, the "talk" and "watch" page actions are allowed but are now deemed invalid.
- $this->assertFalse( $this->skin->isAllowedPageAction( 'talk' ) );
- $this->assertFalse( $this->skin->isAllowedPageAction( 'watch' ) );
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testValidPageActionsAreAllowed() {
- $this->assertTrue( $this->skin->isAllowedPageAction( 'talk' ) );
- $this->assertTrue( $this->skin->isAllowedPageAction( '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 SkinMinerva::isAllowedPageAction
- */
- public function testEditPageAction(
- $supportsDirectEditing,
- $supportsDirectApiEditing,
- $expected
- ) {
- $contentHandler = $this->getMockBuilder( 'ContentHandler' )
- ->disableOriginalConstructor()
- ->getMock();
-
- $contentHandler->method( 'supportsDirectEditing' )
- ->will( $this->returnValue( $supportsDirectEditing ) );
-
- $contentHandler->method( 'supportsDirectApiEditing' )
- ->will( $this->returnValue( $supportsDirectApiEditing ) );
-
- $this->setService( 'Minerva.ContentHandler', $contentHandler );
-
- $this->assertEquals( $expected, $this->skin->isAllowedPageAction( 'edit' ) );
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testPageActionsWhenOnUserPage() {
- $userPageHelper = $this->getMockBuilder( SkinUserPageHelper::class )
- ->disableOriginalConstructor()
- ->getMock();
-
- $skin = $this->getSkin( Title::newFromText( 'User:Admin' ) );
-
- $this->setService( 'Minerva.SkinUserPageHelper', $userPageHelper );
-
- $this->assertTrue( $skin->isAllowedPageAction( 'talk' ) );
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testPageActionsWhenNotOnUserPage() {
- $userPageHelper = $this->getMockBuilder( SkinUserPageHelper::class )
- ->disableOriginalConstructor()
- ->getMock();
-
- $skin = $this->getSkin( Title::newFromText( 'A_test_page' ) );
- $this->setService( 'Minerva.SkinUserPageHelper', $userPageHelper );
-
- $this->assertTrue( $skin->isAllowedPageAction( 'talk' ) );
- }
-
- /**
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testPageActionsWhenOnAnonUserPage() {
- $userPageHelper = $this->getMockBuilder( SkinUserPageHelper::class )
- ->disableOriginalConstructor()
- ->getMock();
-
- $skin = $this->getSkin( Title::newFromText( 'User:1.1.1.1' ) );
- $this->setService( 'Minerva.SkinUserPageHelper', $userPageHelper );
-
- $this->assertTrue( $skin->isAllowedPageAction( 'talk' ) );
- }
-
- public static function switchLanguagePageActionProvider() {
- return [
- [ true, false, true ],
- [ false, true, true ],
- [ false, false, false ],
- [ true, false, true ],
- ];
- }
-
- /**
- * 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 $wgMinervaAlwaysShowLanguageButton
- * configuration variable is set to truthy.
- *
- * @dataProvider switchLanguagePageActionProvider
- * @covers SkinMinerva::isAllowedPageAction
- */
- public function testSwitchLanguagePageAction(
- $doesPageHaveLanguages,
- $minervaAlwaysShowLanguageButton,
- $expected
- ) {
- $this->skin->setDoesPageHaveLanguages( $doesPageHaveLanguages );
- $this->setMwGlobals( [
- 'wgMinervaAlwaysShowLanguageButton' => $minervaAlwaysShowLanguageButton,
- ] );
-
- $this->assertEquals( $expected, $this->skin->isAllowedPageAction( 'switch-language' ) );
- }
-
- /**
- * 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 SkinMinerva::isAllowedPageAction
- */
- public function testWatchIsAllowedOnlyWhenWatchlistPermissionsAreGranted() {
- $title = Title::newFromText( 'test_watchstar_permissions' );
- $requestContext = RequestContext::getMain();
- $requestContext->setTitle( $title );
- $userMock = $this->getMockBuilder( 'User' )
- ->disableOriginalConstructor()
- ->setMethods( [ 'isAllowedAll' ] )
- ->getMock();
- $userMock->expects( $this->once() )
- ->method( 'isAllowedAll' )
- ->with( 'viewmywatchlist', 'editmywatchlist' )
- ->willReturn( false );
- $requestContext->setUser( $userMock );
-
- $result = new TestSkinMinerva();
- $result->setContext( $requestContext );
-
- $this->assertTrue( $this->skin->isAllowedPageAction( 'talk' ) );
- $this->assertFalse( $this->skin->isAllowedPageAction( 'watch' ) );
- }
-}