From: jenkins-bot Date: Thu, 22 Feb 2018 19:19:29 +0000 (+0000) Subject: Merge "Title: Refactor JS/CSS page handling to be more sane" X-Git-Tag: 1.31.0-rc.0~537 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=8624538de243da3779db5eb3362bedf78d2e2931;hp=07c38641b23c1ecf7c75c8ae5935686501032b75 Merge "Title: Refactor JS/CSS page handling to be more sane" --- diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31 index f49a5822e1..131a3b959a 100644 --- a/RELEASE-NOTES-1.31 +++ b/RELEASE-NOTES-1.31 @@ -238,6 +238,12 @@ changes to languages because of Phabricator reports. * CommentStore::getCommentLegacy * CommentStore::insert * CommentStore::insertWithTemplate +* The following methods in Title have been renamed, and the old ones are deprecated: + * Title::getSkinFromCssJsSubpage – use ::getSkinFromConfigSubpage + * Title::isCssOrJsPage – use ::isSiteConfigPage + * Title::isCssJsSubpage – use ::isUserConfigPage + * Title::isCssSubpage – use ::isUserCssConfigPage + * Title::isJsSubpage – use ::isUserJsConfigPage * The method ResourceLoaderModule::getPosition(), deprecated in 1.29, has been removed. * The DeferredStringifier class is deprecated, use Message::listParam() instead. * The type string for the parameter $lang of DateFormatter::getInstance is diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index ae5cef5e1d..35b821cfa0 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -5813,6 +5813,7 @@ $wgGrantPermissions['editpage']['changetags'] = true; $wgGrantPermissions['editprotected'] = $wgGrantPermissions['editpage']; $wgGrantPermissions['editprotected']['editprotected'] = true; +// FIXME: Rename editmycssjs to editmyconfig $wgGrantPermissions['editmycssjs'] = $wgGrantPermissions['editpage']; $wgGrantPermissions['editmycssjs']['editmyusercss'] = true; $wgGrantPermissions['editmycssjs']['editmyuserjs'] = true; diff --git a/includes/EditPage.php b/includes/EditPage.php index f9c7fb29e8..ddb4971db7 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -239,19 +239,19 @@ class EditPage { public $isConflict = false; /** - * @deprecated since 1.30 use Title::isCssJsSubpage() + * @deprecated since 1.30 use Title::isUserConfigPage() * @var bool */ public $isCssJsSubpage = false; /** - * @deprecated since 1.30 use Title::isCssSubpage() + * @deprecated since 1.30 use Title::isUserCssConfigPage() * @var bool */ public $isCssSubpage = false; /** - * @deprecated since 1.30 use Title::isJsSubpage() + * @deprecated since 1.30 use Title::isUserJsConfigPage() * @var bool */ public $isJsSubpage = false; @@ -663,10 +663,10 @@ class EditPage { // css / js subpages of user pages get a special treatment // The following member variables are deprecated since 1.30, // the functions should be used instead. - $this->isCssJsSubpage = $this->mTitle->isCssJsSubpage(); - $this->isCssSubpage = $this->mTitle->isCssSubpage(); - $this->isJsSubpage = $this->mTitle->isJsSubpage(); - $this->isWrongCaseCssJsPage = $this->isWrongCaseCssJsPage(); + $this->isCssJsSubpage = $this->mTitle->isUserConfigPage(); + $this->isCssSubpage = $this->mTitle->isUserCssConfigPage(); + $this->isJsSubpage = $this->mTitle->isUserJsConfigPage(); + $this->isWrongCaseCssJsPage = $this->isWrongCaseUserConfigPage(); # Show applicable editing introductions if ( $this->formtype == 'initial' || $this->firsttime ) { @@ -877,9 +877,9 @@ class EditPage { * * @return bool */ - protected function isWrongCaseCssJsPage() { - if ( $this->mTitle->isCssJsSubpage() ) { - $name = $this->mTitle->getSkinFromCssJsSubpage(); + protected function isWrongCaseUserConfigPage() { + if ( $this->mTitle->isUserConfigPage() ) { + $name = $this->mTitle->getSkinFromConfigSubpage(); $skins = array_merge( array_keys( Skin::getSkinNames() ), [ 'common' ] @@ -2879,7 +2879,7 @@ ERROR; $out->addHTML( $editConflictHelper->getEditFormHtmlBeforeContent() ); } - if ( !$this->mTitle->isCssJsSubpage() && $showToolbar && $user->getOption( 'showtoolbar' ) ) { + if ( !$this->mTitle->isUserConfigPage() && $showToolbar && $user->getOption( 'showtoolbar' ) ) { $out->addHTML( self::getEditToolbar( $this->mTitle ) ); } @@ -3116,22 +3116,26 @@ ERROR; ); } } else { - if ( $this->mTitle->isCssJsSubpage() ) { + if ( $this->mTitle->isUserConfigPage() ) { # Check the skin exists - if ( $this->isWrongCaseCssJsPage() ) { + if ( $this->isWrongCaseUserConfigPage() ) { $out->wrapWikiMsg( - "
\n$1\n
", - [ 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ] + "
\n$1\n
", + [ 'userinvalidconfigtitle', $this->mTitle->getSkinFromConfigSubpage() ] ); } if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) { - $isCssSubpage = $this->mTitle->isCssSubpage(); - $out->wrapWikiMsg( '
$1
', - $isCssSubpage ? 'usercssispublic' : 'userjsispublic' - ); + $isUserCssConfig = $this->mTitle->isUserCssConfigPage(); + + $warning = $isUserCssConfig + ? 'usercssispublic' + : 'userjsispublic'; + + $out->wrapWikiMsg( '
$1
', $warning ); + if ( $this->formtype !== 'preview' ) { $config = $this->context->getConfig(); - if ( $isCssSubpage && $config->get( 'AllowUserCss' ) ) { + if ( $isUserCssConfig && $config->get( 'AllowUserCss' ) ) { $out->wrapWikiMsg( "
\n$1\n
", [ 'usercssyoucanpreview' ] @@ -3913,10 +3917,10 @@ ERROR; } # don't parse non-wikitext pages, show message about preview - if ( $this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage() ) { - if ( $this->mTitle->isCssJsSubpage() ) { + if ( $this->mTitle->isUserConfigPage() || $this->mTitle->isSiteConfigPage() ) { + if ( $this->mTitle->isUserConfigPage() ) { $level = 'user'; - } elseif ( $this->mTitle->isCssOrJsPage() ) { + } elseif ( $this->mTitle->isSiteConfigPage() ) { $level = 'site'; } else { $level = false; diff --git a/includes/OutputPage.php b/includes/OutputPage.php index f95327a72b..4d6db4c35c 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2945,14 +2945,14 @@ class OutputPage extends ContextSource { private function isUserJsPreview() { return $this->getConfig()->get( 'AllowUserJs' ) && $this->getTitle() - && $this->getTitle()->isJsSubpage() + && $this->getTitle()->isUserJsConfigPage() && $this->userCanPreview(); } protected function isUserCssPreview() { return $this->getConfig()->get( 'AllowUserCss' ) && $this->getTitle() - && $this->getTitle()->isCssSubpage() + && $this->getTitle()->isUserCssConfigPage() && $this->userCanPreview(); } @@ -3204,7 +3204,10 @@ class OutputPage extends ContextSource { } $title = $this->getTitle(); - if ( !$title->isJsSubpage() && !$title->isCssSubpage() ) { + if ( + !$title->isUserJsConfigPage() + && !$title->isUserCssConfigPage() + ) { return false; } if ( !$title->isSubpageOf( $user->getUserPage() ) ) { diff --git a/includes/Title.php b/includes/Title.php index 1be986376f..82d9fd9ae6 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1303,22 +1303,52 @@ class Title implements LinkTarget { * show "inactive" CSS or JS. * * @return bool - * @todo FIXME: Rename to isSiteConfigPage() and remove deprecated hook + * @since 1.31 + */ + public function isSiteConfigPage() { + return ( + NS_MEDIAWIKI == $this->mNamespace + && ( + $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ) + ); + } + + /** + * @return bool + * @deprecated Since 1.31; use ::isSiteConfigPage() instead */ public function isCssOrJsPage() { - $isCssOrJsPage = NS_MEDIAWIKI == $this->mNamespace - && ( $this->hasContentModel( CONTENT_MODEL_CSS ) - || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ); + // wfDeprecated( __METHOD__, '1.31' ); + return ( NS_MEDIAWIKI == $this->mNamespace + && ( $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) ); + } - return $isCssOrJsPage; + /** + * Is this a "config" (.css or .js) sub-page of a user page? + * + * @return bool + * @since 1.31 + */ + public function isUserConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && ( + $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ) + ); } /** - * Is this a .css or .js subpage of a user page? * @return bool - * @todo FIXME: Rename to isUserConfigPage() + * @deprecated Since 1.31; use ::isUserConfigPage() instead */ public function isCssJsSubpage() { + // wfDeprecated( __METHOD__, '1.31' ); return ( NS_USER == $this->mNamespace && $this->isSubpage() && ( $this->hasContentModel( CONTENT_MODEL_CSS ) || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) ); @@ -1328,8 +1358,9 @@ class Title implements LinkTarget { * Trim down a .css or .js subpage title to get the corresponding skin name * * @return string Containing skin name from .css or .js subpage title + * @since 1.31 */ - public function getSkinFromCssJsSubpage() { + public function getSkinFromConfigSubpage() { $subpage = explode( '/', $this->mTextform ); $subpage = $subpage[count( $subpage ) - 1]; $lastdot = strrpos( $subpage, '.' ); @@ -1340,23 +1371,58 @@ class Title implements LinkTarget { } /** - * Is this a .css subpage of a user page? + * @deprecated Since 1.31; use ::getSkinFromConfigSubpage() instead + * @return string Containing skin name from .css or .js subpage title + */ + public function getSkinFromCssJsSubpage() { + wfDeprecated( __METHOD__, '1.31' ); + return $this->getSkinFromConfigSubpage(); + } + + /** + * Is this a CSS "config" sub-page of a user page? * * @return bool + * @since 1.31 + */ + public function isUserCssConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && $this->hasContentModel( CONTENT_MODEL_CSS ) + ); + } + + /** + * @deprecated Since 1.31; use ::isUserCssConfigPage() + * @return bool */ public function isCssSubpage() { - return ( NS_USER == $this->mNamespace && $this->isSubpage() - && $this->hasContentModel( CONTENT_MODEL_CSS ) ); + // wfDeprecated( __METHOD__, '1.31' ); + return $this->isUserCssConfigPage(); } /** * Is this a .js subpage of a user page? * * @return bool + * @since 1.31 + */ + public function isUserJsConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ); + } + + /** + * @deprecated Since 1.31; use ::isUserCssConfigPage() + * @return bool */ public function isJsSubpage() { - return ( NS_USER == $this->mNamespace && $this->isSubpage() - && $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ); + // wfDeprecated( __METHOD__, '1.31' ); + return $this->isUserJsConfigPage(); } /** @@ -2260,20 +2326,33 @@ class Title implements LinkTarget { * * @return array List of errors */ - private function checkCSSandJSPermissions( $action, $user, $errors, $rigor, $short ) { + private function checkUserConfigPermissions( $action, $user, $errors, $rigor, $short ) { # Protect css/js subpages of user pages # XXX: this might be better using restrictions + if ( $action != 'patrol' ) { if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $this->mTextform ) ) { - if ( $this->isCssSubpage() && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) { + if ( + $this->isUserCssConfigPage() + && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) + ) { $errors[] = [ 'mycustomcssprotected', $action ]; - } elseif ( $this->isJsSubpage() && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) ) { + } elseif ( + $this->isUserJsConfigPage() + && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) + ) { $errors[] = [ 'mycustomjsprotected', $action ]; } } else { - if ( $this->isCssSubpage() && !$user->isAllowed( 'editusercss' ) ) { + if ( + $this->isUserCssConfigPage() + && !$user->isAllowed( 'editusercss' ) + ) { $errors[] = [ 'customcssprotected', $action ]; - } elseif ( $this->isJsSubpage() && !$user->isAllowed( 'edituserjs' ) ) { + } elseif ( + $this->isUserJsConfigPage() + && !$user->isAllowed( 'edituserjs' ) + ) { $errors[] = [ 'customjsprotected', $action ]; } } @@ -2330,7 +2409,7 @@ class Title implements LinkTarget { * @return array List of errors */ private function checkCascadingSourcesRestrictions( $action, $user, $errors, $rigor, $short ) { - if ( $rigor !== 'quick' && !$this->isCssJsSubpage() ) { + if ( $rigor !== 'quick' && !$this->isUserConfigPage() ) { # We /could/ use the protection level on the source page, but it's # fairly ugly as we have to establish a precedence hierarchy for pages # included by multiple cascade-protected pages. So just restrict @@ -2611,7 +2690,7 @@ class Title implements LinkTarget { 'checkReadPermissions', 'checkUserBlock', // for wgBlockDisablesLogin ]; - # Don't call checkSpecialsAndNSPermissions or checkCSSandJSPermissions + # Don't call checkSpecialsAndNSPermissions or checkUserConfigPermissions # here as it will lead to duplicate error messages. This is okay to do # since anywhere that checks for create will also check for edit, and # those checks are called for edit. @@ -2629,7 +2708,7 @@ class Title implements LinkTarget { 'checkQuickPermissions', 'checkPermissionHooks', 'checkSpecialsAndNSPermissions', - 'checkCSSandJSPermissions', + 'checkUserConfigPermissions', 'checkPageRestrictions', 'checkCascadingSourcesRestrictions', 'checkActionPermissions', @@ -3743,9 +3822,9 @@ class Title implements LinkTarget { } // If we are looking at a css/js user subpage, purge the action=raw. - if ( $this->isJsSubpage() ) { + if ( $this->isUserJsConfigPage() ) { $urls[] = $this->getInternalURL( 'action=raw&ctype=text/javascript' ); - } elseif ( $this->isCssSubpage() ) { + } elseif ( $this->isUserCssConfigPage() ) { $urls[] = $this->getInternalURL( 'action=raw&ctype=text/css' ); } diff --git a/includes/preferences/DefaultPreferencesFactory.php b/includes/preferences/DefaultPreferencesFactory.php index c1e9a59cec..478f373ab4 100644 --- a/includes/preferences/DefaultPreferencesFactory.php +++ b/includes/preferences/DefaultPreferencesFactory.php @@ -705,7 +705,7 @@ class DefaultPreferencesFactory implements PreferencesFactory { 'type' => 'info', 'raw' => true, 'default' => $context->getLanguage()->pipeList( $linkTools ), - 'label-message' => 'prefs-common-css-js', + 'label-message' => 'prefs-common-config', 'section' => 'rendering/skin', ]; } diff --git a/includes/resourceloader/ResourceLoaderWikiModule.php b/includes/resourceloader/ResourceLoaderWikiModule.php index 6eddfc0923..5b512af7b9 100644 --- a/includes/resourceloader/ResourceLoaderWikiModule.php +++ b/includes/resourceloader/ResourceLoaderWikiModule.php @@ -29,8 +29,8 @@ use Wikimedia\Rdbms\IDatabase; * Abstraction for ResourceLoader modules which pull from wiki pages * * This can only be used for wiki pages in the MediaWiki and User namespaces, - * because of its dependence on the functionality of Title::isCssJsSubpage - * and Title::isCssOrJsPage(). + * because of its dependence on the functionality of Title::isUserConfigPage() + * and Title::isSiteConfigPage(). * * This module supports being used as a placeholder for a module on a remote wiki. * To do so, getDB() must be overloaded to return a foreign database object that @@ -450,7 +450,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule { } elseif ( $new && in_array( $new->getContentFormat(), $formats ) ) { $purge = true; } else { - $purge = ( $title->isCssOrJsPage() || $title->isCssJsSubpage() ); + $purge = ( $title->isSiteConfigPage() || $title->isUserConfigPage() ); } if ( $purge ) { diff --git a/languages/i18n/en.json b/languages/i18n/en.json index bcf0ec5704..d0ee41c27f 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -684,7 +684,7 @@ "userjspreview": "Remember that you are only testing/previewing your user JavaScript.\nIt has not yet been saved!", "sitecsspreview": "Remember that you are only previewing this CSS.\nIt has not yet been saved!", "sitejspreview": "Remember that you are only previewing this JavaScript code.\nIt has not yet been saved!", - "userinvalidcssjstitle": "Warning: There is no skin \"$1\".\nCustom .css and .js pages use a lowercase title, e.g. {{ns:user}}:Foo/vector.css as opposed to {{ns:user}}:Foo/Vector.css.", + "userinvalidconfigtitle": "Warning: There is no skin \"$1\".\nCustom .css and .js pages use a lowercase title, e.g. {{ns:user}}:Foo/vector.css as opposed to {{ns:user}}:Foo/Vector.css.", "updated": "(Updated)", "note": "Note:", "previewnote": "Remember that this is only a preview.\nYour changes have not yet been saved!", @@ -1073,7 +1073,7 @@ "prefs-files": "Files", "prefs-custom-css": "Custom CSS", "prefs-custom-js": "Custom JavaScript", - "prefs-common-css-js": "Shared CSS/JavaScript for all skins:", + "prefs-common-config": "Shared CSS/JavaScript for all skins:", "prefs-reset-intro": "You can use this page to reset your preferences to the site defaults.\nThis cannot be undone.", "prefs-emailconfirm-label": "Email confirmation:", "youremail": "Email:", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index f75d9bd79b..ec41d37cc1 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -881,7 +881,7 @@ "userjspreview": "Text displayed on preview of every user .js subpage", "sitecsspreview": "Text displayed on preview of .css pages in MediaWiki namespace.\n\nSee also:\n* {{msg-mw|Usercsspreview}}", "sitejspreview": "Text displayed on preview of .js pages in MediaWiki namespace", - "userinvalidcssjstitle": "Parameters:\n* $1 - skin name", + "userinvalidconfigtitle": "Parameters:\n* $1 - skin name", "updated": "{{Identical|Updated}}", "note": "{{Identical|Note}}", "previewnote": "Note displayed when clicking on Show preview", @@ -1270,7 +1270,7 @@ "prefs-files": "Title of a tab in [[Special:Preferences]].\n{{Identical|File}}", "prefs-custom-css": "visible on [[Special:Preferences]] -[Skins].\n{{Identical|Custom CSS}}", "prefs-custom-js": "visible on [[Special:Preferences]] -[Skins].\n{{Identical|Custom JavaScript}}", - "prefs-common-css-js": "Used as label in [[Special:Preferences#mw-prefsection-rendering|preferences]], tab \"Appearance\", section \"Skin\".\n\nSee also:\n* {{msg-mw|Globalcssjs-custom-css-js}}", + "prefs-common-config": "Used as label in [[Special:Preferences#mw-prefsection-rendering|preferences]], tab \"Appearance\", section \"Skin\".\n\nSee also:\n* {{msg-mw|Globalcssjs-custom-css-js}}", "prefs-reset-intro": "Used in [[Special:Preferences/reset]].", "prefs-emailconfirm-label": "Sub-heading in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.", "youremail": "Label of the e-mail text box of the \"E-mail options\" section of [[Special:Preferences]].\nAlso used on create account form.\n\n{{Identical|E-mail}}", diff --git a/tests/phpunit/includes/TitleMethodsTest.php b/tests/phpunit/includes/TitleMethodsTest.php index f4eb6bf5d3..9ae84d920b 100644 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ b/tests/phpunit/includes/TitleMethodsTest.php @@ -164,7 +164,7 @@ class TitleMethodsTest extends MediaWikiLangTestCase { $this->assertTrue( $title->hasContentModel( $expectedModelId ) ); } - public static function provideIsCssOrJsPage() { + public static function provideIsSiteConfigPage() { return [ [ 'Help:Foo', false ], [ 'Help:Foo.js', false ], @@ -173,6 +173,8 @@ class TitleMethodsTest extends MediaWikiLangTestCase { [ 'User:Foo.js', false ], [ 'User:Foo/bar.js', false ], [ 'User:Foo/bar.css', false ], + [ 'User:Foo/bar.JS', false ], + [ 'User:Foo/bar.CSS', false ], [ 'User talk:Foo/bar.css', false ], [ 'User:Foo/bar.js.xxx', false ], [ 'User:Foo/bar.xxx', false ], @@ -180,6 +182,7 @@ class TitleMethodsTest extends MediaWikiLangTestCase { [ 'MediaWiki:Foo.css', true ], [ 'MediaWiki:Foo.JS', false ], [ 'MediaWiki:Foo.CSS', false ], + [ 'MediaWiki:Foo/bar.css', true ], [ 'MediaWiki:Foo.css.xxx', false ], [ 'TEST-JS:Foo', false ], [ 'TEST-JS:Foo.js', false ], @@ -187,15 +190,15 @@ class TitleMethodsTest extends MediaWikiLangTestCase { } /** - * @dataProvider provideIsCssOrJsPage - * @covers Title::isCssOrJsPage + * @dataProvider provideIsSiteConfigPage + * @covers Title::isSiteConfigPage */ - public function testIsCssOrJsPage( $title, $expectedBool ) { + public function testSiteConfigPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssOrJsPage() ); + $this->assertEquals( $expectedBool, $title->isSiteConfigPage() ); } - public static function provideIsCssJsSubpage() { + public static function provideIsUserConfigPage() { return [ [ 'Help:Foo', false ], [ 'Help:Foo.js', false ], @@ -203,28 +206,32 @@ class TitleMethodsTest extends MediaWikiLangTestCase { [ 'User:Foo', false ], [ 'User:Foo.js', false ], [ 'User:Foo/bar.js', true ], + [ 'User:Foo/bar.JS', false ], [ 'User:Foo/bar.css', true ], + [ 'User:Foo/bar.CSS', false ], [ 'User talk:Foo/bar.css', false ], [ 'User:Foo/bar.js.xxx', false ], [ 'User:Foo/bar.xxx', false ], [ 'MediaWiki:Foo.js', false ], - [ 'User:Foo/bar.JS', false ], - [ 'User:Foo/bar.CSS', false ], + [ 'MediaWiki:Foo.css', false ], + [ 'MediaWiki:Foo.JS', false ], + [ 'MediaWiki:Foo.CSS', false ], + [ 'MediaWiki:Foo.css.xxx', false ], [ 'TEST-JS:Foo', false ], [ 'TEST-JS:Foo.js', false ], ]; } /** - * @dataProvider provideIsCssJsSubpage - * @covers Title::isCssJsSubpage + * @dataProvider provideIsUserConfigPage + * @covers Title::isUserConfigPage */ - public function testIsCssJsSubpage( $title, $expectedBool ) { + public function testIsUserConfigPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssJsSubpage() ); + $this->assertEquals( $expectedBool, $title->isUserConfigPage() ); } - public static function provideIsCssSubpage() { + public static function provideIsUserCssConfigPage() { return [ [ 'Help:Foo', false ], [ 'Help:Foo.css', false ], @@ -237,33 +244,35 @@ class TitleMethodsTest extends MediaWikiLangTestCase { } /** - * @dataProvider provideIsCssSubpage - * @covers Title::isCssSubpage + * @dataProvider provideIsUserCssConfigPage + * @covers Title::isUserCssConfigPage */ - public function testIsCssSubpage( $title, $expectedBool ) { + public function testIsUserCssConfigPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssSubpage() ); + $this->assertEquals( $expectedBool, $title->isUserCssConfigPage() ); } - public static function provideIsJsSubpage() { + public static function provideIsUserJsConfigPage() { return [ [ 'Help:Foo', false ], [ 'Help:Foo.css', false ], [ 'User:Foo', false ], [ 'User:Foo.js', false ], + [ 'User:Foo.json', false ], [ 'User:Foo.css', false ], [ 'User:Foo/bar.js', true ], + [ 'User:Foo/bar.json', false ], [ 'User:Foo/bar.css', false ], ]; } /** - * @dataProvider provideIsJsSubpage - * @covers Title::isJsSubpage + * @dataProvider provideIsUserJsConfigPage + * @covers Title::isUserJsConfigPage */ - public function testIsJsSubpage( $title, $expectedBool ) { + public function testIsUserJsConfigPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isJsSubpage() ); + $this->assertEquals( $expectedBool, $title->isUserJsConfigPage() ); } public static function provideIsWikitextPage() { @@ -279,13 +288,14 @@ class TitleMethodsTest extends MediaWikiLangTestCase { [ 'User:Foo/bar.js.xxx', true ], [ 'User:Foo/bar.xxx', true ], [ 'MediaWiki:Foo.js', false ], - [ 'MediaWiki:Foo.css', false ], - [ 'MediaWiki:Foo/bar.css', false ], [ 'User:Foo/bar.JS', true ], [ 'User:Foo/bar.CSS', true ], + [ 'MediaWiki:Foo.css', false ], + [ 'MediaWiki:Foo.JS', true ], + [ 'MediaWiki:Foo.CSS', true ], + [ 'MediaWiki:Foo.css.xxx', true ], [ 'TEST-JS:Foo', false ], [ 'TEST-JS:Foo.js', false ], - [ 'TEST-JS_TALK:Foo.js', true ], ]; } diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index e20cc7b12f..7dfb7357f5 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -96,6 +96,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { /** * @todo This test method should be split up into separate test methods and * data providers + * @covers Title::checkQuickPermissions */ public function testQuickPermissions() { global $wgContLang; @@ -386,6 +387,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { /** * @todo This test method should be split up into separate test methods and * data providers + * @covers Title::checkSpecialsAndNSPermissions */ public function testSpecialsAndNSPermissions() { global $wgNamespaceProtection; @@ -442,91 +444,139 @@ class TitlePermissionTest extends MediaWikiLangTestCase { /** * @todo This test method should be split up into separate test methods and * data providers + * @covers Title::checkUserConfigPermissions */ - public function testCssAndJavascriptPermissions() { + public function testJsConfigEditPermissions() { $this->setUser( $this->userName ); $this->setTitle( NS_USER, $this->userName . '/test.js' ); - $this->runCSSandJSPermissions( + $this->runConfigEditPermissions( [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ], [ [ 'badaccess-group0' ] ], + [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ], [ [ 'badaccess-group0' ] ] ); + } + + /** + * @todo This test method should be split up into separate test methods and + * data providers + * @covers Title::checkUserConfigPermissions + */ + public function testCssConfigEditPermissions() { + $this->setUser( $this->userName ); $this->setTitle( NS_USER, $this->userName . '/test.css' ); - $this->runCSSandJSPermissions( + $this->runConfigEditPermissions( [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ] ], [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ] ], [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ] ); + } + + /** + * @todo This test method should be split up into separate test methods and + * data providers + * @covers Title::checkUserConfigPermissions + */ + public function testOtherJsConfigEditPermissions() { + $this->setUser( $this->userName ); $this->setTitle( NS_USER, $this->altUserName . '/test.js' ); - $this->runCSSandJSPermissions( + $this->runConfigEditPermissions( [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ], [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ], [ [ 'badaccess-group0' ] ] ); + } + + /** + * @todo This test method should be split up into separate test methods and + * data providers + * @covers Title::checkUserConfigPermissions + */ + public function testOtherCssConfigEditPermissions() { + $this->setUser( $this->userName ); $this->setTitle( NS_USER, $this->altUserName . '/test.css' ); - $this->runCSSandJSPermissions( + $this->runConfigEditPermissions( [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ], [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ], + [ [ 'badaccess-group0' ] ], [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ] ); + } + + /** + * @todo This test method should be split up into separate test methods and + * data providers + * @covers Title::checkUserConfigPermissions + */ + public function testOtherNonConfigEditPermissions() { + $this->setUser( $this->userName ); $this->setTitle( NS_USER, $this->altUserName . '/tempo' ); - $this->runCSSandJSPermissions( + $this->runConfigEditPermissions( [ [ 'badaccess-group0' ] ], + [ [ 'badaccess-group0' ] ], [ [ 'badaccess-group0' ] ], + [ [ 'badaccess-group0' ] ], [ [ 'badaccess-group0' ] ] ); } - protected function runCSSandJSPermissions( $result0, $result1, $result2, $result3, $result4 ) { + protected function runConfigEditPermissions( + $resultNone, + $resultMyCss, + $resultMyJs, + $resultUserCss, + $resultUserJs + ) { $this->setUserPerm( '' ); - $this->assertEquals( $result0, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( $resultNone, $result ); $this->setUserPerm( 'editmyusercss' ); - $this->assertEquals( $result1, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( $resultMyCss, $result ); $this->setUserPerm( 'editmyuserjs' ); - $this->assertEquals( $result2, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( $resultMyJs, $result ); $this->setUserPerm( 'editusercss' ); - $this->assertEquals( $result3, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( $resultUserCss, $result ); $this->setUserPerm( 'edituserjs' ); - $this->assertEquals( $result4, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( $resultUserJs, $result ); $this->setUserPerm( [ 'edituserjs', 'editusercss' ] ); - $this->assertEquals( [ [ 'badaccess-group0' ] ], - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); + $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); + $this->assertEquals( [ [ 'badaccess-group0' ] ], $result ); } /** * @todo This test method should be split up into separate test methods and * data providers + * @covers Title::checkPageRestrictions */ public function testPageRestrictions() { global $wgContLang; @@ -619,6 +669,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); } + /** + * @covers Title::checkCascadingSourcesRestrictions + */ public function testCascadingSourcesRestrictions() { $this->setTitle( NS_MAIN, "test page" ); $this->setUserPerm( [ "edit", "bogus" ] ); @@ -648,6 +701,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { /** * @todo This test method should be split up into separate test methods and * data providers + * @covers Title::checkActionPermissions */ public function testActionPermissions() { $this->setUserPerm( [ "createpage" ] ); @@ -720,6 +774,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'move-target', $this->user ) ); } + /** + * @covers Title::checkUserBlock + */ public function testUserBlock() { global $wgEmailConfirmToEdit, $wgEmailAuthentication; $wgEmailConfirmToEdit = true;