jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/342294 )
Change subject: Port Wikidata filter to new RCFilters system
......................................................................
Port Wikidata filter to new RCFilters system
Update tests, including fixing a small pre-existing
problem with the page names.
Add WBREPONAME to jQueryMsg and re-factor magic
word hook handlers to support that without code
duplication.
Bug: T156427
Bug: T159787
Depends-On: Ie82a147ff32ccda3f757108474f5cbab71d45ace
Change-Id: I0b910d273a434b5bcbc38deb0fb04f6a2cd8ac8c
---
M client/WikibaseClient.hooks.php
M client/WikibaseClient.php
M client/i18n/en.json
M client/i18n/qqq.json
M client/includes/Hooks/ChangesListSpecialPageHookHandlers.php
A client/includes/Hooks/MagicWordHookHandlers.php
M client/includes/Modules/SiteModule.php
M client/tests/phpunit/includes/Hooks/ChangesListSpecialPageHookHandlersTest.php
A client/tests/phpunit/includes/Hooks/MagicWordHookHandlersTest.php
M client/tests/phpunit/includes/Modules/SiteModuleTest.php
10 files changed, 559 insertions(+), 218 deletions(-)
Approvals:
Catrope: Looks good to me, approved
jenkins-bot: Verified
diff --git a/client/WikibaseClient.hooks.php b/client/WikibaseClient.hooks.php
index 11528de..6611903 100644
--- a/client/WikibaseClient.hooks.php
+++ b/client/WikibaseClient.hooks.php
@@ -342,52 +342,6 @@
}
/**
- * Register the magic word.
- *
- * @param string[] &$aCustomVariableIds
- *
- * @return bool
- */
- public static function onMagicWordwgVariableIDs( &$aCustomVariableIds )
{
- $aCustomVariableIds[] = 'noexternallanglinks';
- $aCustomVariableIds[] = 'wbreponame';
-
- return true;
- }
-
- /**
- * Apply the magic word.
- *
- * @param Parser &$parser
- * @param array &$cache
- * @param string &$magicWordId
- * @param string &$ret
- *
- * @return bool
- */
- public static function onParserGetVariableValueSwitch( Parser &$parser,
&$cache, &$magicWordId, &$ret ) {
- if ( $magicWordId === 'noexternallanglinks' ) {
- NoLangLinkHandler::handle( $parser, '*' );
- } elseif ( $magicWordId === 'wbreponame' ) {
- // @todo factor out, with tests
- $wikibaseClient = WikibaseClient::getDefaultInstance();
- $settings = $wikibaseClient->getSettings();
- $repoSiteName = $settings->getSetting( 'repoSiteName' );
-
- $message = new Message( $repoSiteName );
-
- if ( $message->exists() ) {
- $lang = $parser->getTargetLanguage();
- $ret = $message->inLanguage( $lang )->parse();
- } else {
- $ret = $repoSiteName;
- }
- }
-
- return true;
- }
-
- /**
* Adds the Entity ID of the corresponding Wikidata item in action=info
*
* @param IContextSource $context
@@ -496,16 +450,28 @@
}
/**
- * These hooks should only be run if we use the Echo extension
+ * Do special hook registrations. These are affected by ordering
issues and/or
+ * conditional on another extension being registered.
*
* @see
https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExtensionFunctions
*/
public static function onExtensionLoad() {
global $wgHooks;
+
+ // These hooks should only be run if we use the Echo extension
if ( class_exists( EchoEvent::class ) ) {
$wgHooks['UserGetDefaultOptions'][] =
EchoNotificationsHandlers::class . '::onUserGetDefaultOptions';
$wgHooks['WikibaseHandleChange'][] =
EchoNotificationsHandlers::class . '::onWikibaseHandleChange';
}
+
+ // This is in onExtensionLoad to ensure we register our
+ // ChangesListSpecialPageStructuredFilters after ORES's.
+ //
+ // However, ORES is not required.
+ //
+ // recent changes / watchlist hooks
+ $wgHooks['ChangesListSpecialPageStructuredFilters'][] =
+
'\Wikibase\Client\Hooks\ChangesListSpecialPageHookHandlers::onChangesListSpecialPageStructuredFilters';
}
}
diff --git a/client/WikibaseClient.php b/client/WikibaseClient.php
index 07df902..efeeeda 100644
--- a/client/WikibaseClient.php
+++ b/client/WikibaseClient.php
@@ -119,8 +119,6 @@
$wgHooks['SidebarBeforeOutput'][] =
'\Wikibase\Client\Hooks\SidebarHookHandlers::onSidebarBeforeOutput';
$wgHooks['ParserFirstCallInit'][] =
'\Wikibase\ClientHooks::onParserFirstCallInit';
- $wgHooks['MagicWordwgVariableIDs'][] =
'\Wikibase\ClientHooks::onMagicWordwgVariableIDs';
- $wgHooks['ParserGetVariableValueSwitch'][] =
'\Wikibase\ClientHooks::onParserGetVariableValueSwitch';
$wgHooks['SkinTemplateOutputPageBeforeExec'][] =
'\Wikibase\Client\Hooks\SkinTemplateOutputPageBeforeExecHandler::onSkinTemplateOutputPageBeforeExec';
$wgHooks['SpecialMovepageAfterMove'][] =
'\Wikibase\Client\Hooks\MovePageNotice::onSpecialMovepageAfterMove';
@@ -162,9 +160,13 @@
}
// recent changes / watchlist hooks
- $wgHooks['ChangesListSpecialPageFilters'][] =
'\Wikibase\Client\Hooks\ChangesListSpecialPageHookHandlers::onChangesListSpecialPageFilters';
$wgHooks['ChangesListSpecialPageQuery'][] =
'\Wikibase\Client\Hooks\ChangesListSpecialPageHookHandlers::onChangesListSpecialPageQuery';
+ // magic words
+ $wgHooks['MagicWordwgVariableIDs'][] =
'\Wikibase\Client\Hooks\MagicWordHookHandlers::onMagicWordwgVariableIDs';
+ $wgHooks['ParserGetVariableValueSwitch'][] =
'\Wikibase\Client\Hooks\MagicWordHookHandlers::onParserGetVariableValueSwitch';
+ $wgHooks['ResourceLoaderJqueryMsgModuleMagicWords'][] =
'\Wikibase\Client\Hooks\MagicWordHookHandlers::onResourceLoaderJqueryMsgModuleMagicWords';
+
// update hooks
$wgHooks['LoadExtensionSchemaUpdates'][] =
'\Wikibase\Client\Usage\Sql\SqlUsageTrackerSchemaUpdater::onSchemaUpdate';
diff --git a/client/i18n/en.json b/client/i18n/en.json
index 5c7c152..565b5ae 100644
--- a/client/i18n/en.json
+++ b/client/i18n/en.json
@@ -75,6 +75,12 @@
"wikibase-rc-show-wikidata-pref": "Show {{WBREPONAME}} edits in recent
changes",
"wikibase-rc-wikibase-edit-letter": "D",
"wikibase-rc-wikibase-edit-title": "{{WBREPONAME}} edit",
+ "wikibase-rcfilters-hide-wikibase-label": "{{WBREPONAME}} edits",
+ "wikibase-rcfilters-hide-wikibase-description": "Edits that originate
on {{WBREPONAME}}.",
+ "wikibase-rcfilters-hide-wikibase-conflicts-ores": "This filter
conflicts with one or more Contribution Quality or User Intent filters. Quality
and Intent predictions are not available for {{WBREPONAME}} edits.",
+ "wikibase-rcfilters-hide-wikibase-conflicts-ores-global": "The
\"{{WBREPONAME}} edits\" filter is conflicting with one or more Contribution
Quality or User Intent filters. Quality and Intent predictions are not
available for {{WBREPONAME}} edits. The conflicting filters are marked in the
Active Filters area, above.",
+ "wikibase-rcfilters-damaging-conflicts-hide-wikibase": "Contribution
Quality predictions are not available for certain types of change, so this
filter conflicts with the following Type of Change
{{PLURAL:$2|filter|filters}}: $1",
+ "wikibase-rcfilters-goodfaith-conflicts-hide-wikibase": "User Intent
predictions are not available for certain types of change, so this filter
conflicts with the following Type of Change {{PLURAL:$2|filter|filters}}: $1",
"wikibase-replicationnote": "Please notice that it can take several
minutes until the changes are visible on all wikis.",
"wikibase-watchlist-show-changes-pref": "Show {{WBREPONAME}} edits in
your watchlist",
"wikibase-error-deserialize-error": "Failed to deserialize data.",
diff --git a/client/i18n/qqq.json b/client/i18n/qqq.json
index 5c7d7a7..91f05e2 100644
--- a/client/i18n/qqq.json
+++ b/client/i18n/qqq.json
@@ -86,6 +86,12 @@
"wikibase-rc-show-wikidata-pref": "Option in the recent changes section
of preferences to show wikibase changes by default in recent changes.",
"wikibase-rc-wikibase-edit-letter": "Very short form of \"'''wikidata
edit'''\". Used in [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nSee
also:\n* {{msg-mw|Newpageletter}}\n* {{msg-mw|Minoreditletter}}\n*
{{msg-mw|Boteditletter}}\n* {{msg-mw|Unpatrolledletter}}",
"wikibase-rc-wikibase-edit-title": "Tooltip for
{{msg-mw|wikibase-rc-wikibase-edit-letter}}.\n\nSee also:\n*
{{msg-mw|Recentchanges-label-newpage}}\n*
{{msg-mw|Recentchanges-label-minor}}\n* {{msg-mw|Recentchanges-label-bot}}\n*
{{msg-mw|Recentchanges-label-unpatrolled}}\n{{Identical|Edit}}",
+ "wikibase-rcfilters-hide-wikibase-label": "Label for 'Wikidata edits'
filter on ChangesList pages (such as RecentChanges)",
+ "wikibase-rcfilters-hide-wikibase-description": "Description for
'Wikidata edits' filter on ChangesList pages (such as RecentChanges)",
+ "wikibase-rcfilters-hide-wikibase-conflicts-ores": "Tooltip shown when
hovering over a 'Wikidata edits' filter tag, when a ORES filter is also
selected.\n* 'Contribution quality' is based on
{{msg-mw|Ores-rcfilters-damaging-title}}.\n* 'User intent' is based on
{{msg-mw|Ores-rcfilters-goodfaith-title}}.",
+ "wikibase-rcfilters-hide-wikibase-conflicts-ores-global": "Message
shown in the result area when both an ORES filter and the 'Wikidata edits'
filter are selected. This indicates that no results will be shown because
propagated Wikidata edits do not have ORES scores available.\n\n* \"Wikidata
edits\" is {{msg-mw|wikibase-rcfilters-hide-wikibase-label}}.\n* \"Contribution
quality\" is based on {{msg-mw|Ores-rcfilters-damaging-title}}.\n* \"User
intent\" is based on {{msg-mw|Ores-rcfilters-goodfaith-title}}.\n* \"Active
Filters\" is based on {{msg-mw|rcfilters-activefilters}}.",
+ "wikibase-rcfilters-damaging-conflicts-hide-wikibase": "Tooltip shown
when hovering over a 'Contribution quality predictions' filter tag, when the
'Wikidata edits' filter is selected and there is a conflict. Propagated
Wikidata edits do not have ORES scores avaialble. Parameters:\n* $1 -
Comma-separated string of selected Type of Change filters, e.g. \"Wikidata
edits\"\n* $2 - Count of selected Type of Change filters, for PLURAL",
+ "wikibase-rcfilters-goodfaith-conflicts-hide-wikibase": "Tooltip shown
when hovering over a 'User intent predictions' filter tag, when the 'Wikidata
edits' filter is selected and there is a conflict. 'Wikidata edits' are not
scored by ORES. Parameters:\n* $1 - Comma-separated string of selected Type of
Change filters, e.g. \"Wikidata edits\"\n* $2 - Count of selected Type of
Change filters, for PLURAL",
"wikibase-replicationnote": "Note telling the user that it can take a
few minutes until the made changes are visible on all wikis.\nPreceded by
message {{msg-mw|Wikibase-linkitem-success-link}}",
"wikibase-watchlist-show-changes-pref": "Option in the watchlist
section of preferences to always show wikibase edits by default in the
watchlist. Appears as a checkbox in the same list with options such as:\n*
{{msg-mw|tog-watchdefault}}\n* {{msg-mw|tog-watchmoves}}\nAnd so on.",
"wikibase-error-deserialize-error": "Generic error when invalid
(undeserializable) data has been given.",
diff --git a/client/includes/Hooks/ChangesListSpecialPageHookHandlers.php
b/client/includes/Hooks/ChangesListSpecialPageHookHandlers.php
index 55460ba..2e0f963 100644
--- a/client/includes/Hooks/ChangesListSpecialPageHookHandlers.php
+++ b/client/includes/Hooks/ChangesListSpecialPageHookHandlers.php
@@ -2,9 +2,12 @@
namespace Wikibase\Client\Hooks;
+use ChangesListBooleanFilter;
use ChangesListSpecialPage;
+use ExtensionRegistry;
use FormOptions;
use IContextSource;
+use IDatabase;
use MediaWiki\MediaWikiServices;
use RequestContext;
use User;
@@ -113,29 +116,26 @@
/**
* Modifies recent changes and watchlist options to show a toggle for
Wikibase changes
- * @see
https://www.mediawiki.org/wiki/Manual:Hooks/ChangesListSpecialPageFilters
+ * @see
https://www.mediawiki.org/wiki/Manual:Hooks/ChangesListSpecialPageStructuredFilters
*
* @param ChangesListSpecialPage $specialPage
- * @param array &$filters
*
* @return bool
*/
- public static function onChangesListSpecialPageFilters(
- ChangesListSpecialPage $specialPage,
- array &$filters
+ public static function onChangesListSpecialPageStructuredFilters(
+ ChangesListSpecialPage $specialPage
) {
$hookHandler = self::getInstance(
$specialPage->getContext(),
$specialPage->getName()
);
- $hookHandler->addFilterIfEnabled( $filters );
+ $hookHandler->addFilterIfEnabled( $specialPage );
return true;
}
/**
- * Modifies watchlist and recent changes query to include external
changes
* @see
https://www.mediawiki.org/wiki/Manual:Hooks/ChangesListSpecialPageQuery
*
* @param string $specialPageName
@@ -162,83 +162,109 @@
$specialPageName
);
- $conds = $hookHandler->addWikibaseConditions( $conds, $opts );
+ $hookHandler->addWikibaseConditionsIfFilterUnavailable( $conds
);
return true;
}
- /**
- * @param array &$filters
- */
- public function addFilterIfEnabled( array &$filters ) {
- if ( $this->hasWikibaseChangesEnabled() ) {
- $filterName = $this->getFilterName();
+ // This is separate so hasWikibaseChangesEnabled can be mocked
- // the toggle needs to be the inverse to invoke the
inverse display status.
- // e.g. if Wikibase changes currently hidden, then when
the user
- // clicks the toggle, then Wikibase changes are
displayed.
- $filters[$filterName] = array(
- 'msg' => 'wikibase-rc-hide-wikidata',
- 'default' =>
!$this->hasWikibaseChangesDisplayed()
+ /**
+ * This is used to force-hide Wikibase changes if
hasWikibaseChangesEnabled returns
+ * false. The user will not even see the option in that case.
+ *
+ * @param array &$conds
+ */
+ protected function addWikibaseConditionsIfFilterUnavailable( array
&$conds ) {
+ if ( !$this->hasWikibaseChangesEnabled() ) {
+ // Force-hide if hasWikibaseChangesEnabled is false
+ // The user-facing hideWikibase is handled by
+ // ChangesListSpecialPageStructuredFilters and
connected code.
+ $this->addWikibaseConditions(
+ $this->loadBalancer->getConnection( DB_REPLICA
),
+ $conds
);
}
}
/**
- * @param array &$conds
- * @param FormOptions $opts
- *
- * @return array
+ * @param ChangesListSpecialPage $specialPage
*/
- public function addWikibaseConditions( array &$conds, FormOptions $opts
) {
- if ( $this->shouldHideWikibaseChanges( $opts ) ) {
- $dbr = $this->loadBalancer->getConnection( DB_REPLICA );
- $conds[] = 'rc_source != ' . $dbr->addQuotes(
RecentChangeFactory::SRC_WIKIBASE );
- $this->loadBalancer->reuseConnection( $dbr );
+ public function addFilterIfEnabled( ChangesListSpecialPage $specialPage
) {
+ // The *user-facing* filter is only registered if external
changes
+ // are enabled, and the user does not have enhanced recent
changes.
+ //
+ // If the user-facing filter is not registered, it's always
*hidden*.
+ // (See ChangesListSpecialPageQuery).
+ if ( $this->hasWikibaseChangesEnabled() ) {
+ $this->addFilter( $specialPage );
}
-
- return $conds;
}
/**
- * @param FormOptions $opts
- *
- * @return boolean
+ * @param ChangesListSpecialPage $specialPage
*/
- private function shouldHideWikibaseChanges( FormOptions $opts ) {
- if ( !$this->hasWikibaseChangesEnabled() ) {
- return true;
- }
-
+ protected function addFilter( ChangesListSpecialPage $specialPage ) {
$filterName = $this->getFilterName();
+ $changeTypeGroup = $specialPage->getFilterGroup( 'changeType' );
- if ( !$opts->offsetExists( $filterName ) ) {
- return true;
+ $specialPage->getOutput()->addModules(
'wikibase.client.jqueryMsg' );
+
+ $wikidataFilter = new ChangesListBooleanFilter( [
+ 'name' => $filterName,
+ 'group' => $changeTypeGroup,
+ 'priority' => -4,
+ 'label' => 'wikibase-rcfilters-hide-wikibase-label',
+ 'description' =>
'wikibase-rcfilters-hide-wikibase-description',
+ 'showHide' => 'wikibase-rc-hide-wikidata',
+ // If the preference is enabled, then don't hide
Wikidata edits
+ 'default' => !$this->hasShowWikibaseEditsPrefEnabled(),
+ 'queryCallable' => function ( $specialClassName, $ctx,
$dbr, &$tables, &$fields,
+ &$conds, &$query_options, &$join_conds ) {
+ $this->addWikibaseConditions( $dbr, $conds );
+ },
+ 'cssClassSuffix' => 'src-mw-wikibase',
+ 'isRowApplicableCallable' => function ( $ctx, $rc ) {
+ return $rc->getAttribute( 'rc_source' ) ===
RecentChangeFactory::SRC_WIKIBASE;
+ }
+ ] );
+
+ $extensionRegistry = ExtensionRegistry::getInstance();
+
+ if ( $extensionRegistry->isLoaded( 'ORES' ) ) {
+ $damagingGroup = $specialPage->getFilterGroup(
'damaging' );
+ $wikidataFilter->conflictsWith(
+ $damagingGroup,
+
'wikibase-rcfilters-hide-wikibase-conflicts-ores-global',
+
'wikibase-rcfilters-hide-wikibase-conflicts-ores',
+
'wikibase-rcfilters-damaging-conflicts-hide-wikibase'
+ );
+
+ $goodfaithGroup = $specialPage->getFilterGroup(
'goodfaith' );
+ $wikidataFilter->conflictsWith(
+ $goodfaithGroup,
+
'wikibase-rcfilters-hide-wikibase-conflicts-ores-global',
+
'wikibase-rcfilters-hide-wikibase-conflicts-ores',
+
'wikibase-rcfilters-goodfaith-conflicts-hide-wikibase'
+ );
}
+ }
- return $opts->getValue( $filterName ) === true;
+ /**
+ * @param IDatabase $dbr
+ * @param array &$conds
+ */
+ public function addWikibaseConditions( IDatabase $dbr, array &$conds ) {
+ $conds[] = 'rc_source != ' . $dbr->addQuotes(
RecentChangeFactory::SRC_WIKIBASE );
}
/**
* @return bool
*/
- private function hasWikibaseChangesEnabled() {
+ protected function hasWikibaseChangesEnabled() {
// do not include wikibase changes for activated enhanced
watchlist
// since we do not support that format yet (T46222)
return $this->showExternalChanges &&
!$this->isEnhancedChangesEnabled();
- }
-
- /**
- * @return bool
- */
- private function hasWikibaseChangesDisplayed() {
- if ( $this->request->getVal( 'action' ) === 'submit' ) {
- return !$this->request->getBool( $this->getFilterName()
);
- }
-
- // if preference enabled, then Wikibase edits are included by
default and
- // the toggle default value needs to be the inverse to hide
them, and vice versa.
- return $this->hasShowWikibaseEditsPrefEnabled();
}
/**
diff --git a/client/includes/Hooks/MagicWordHookHandlers.php
b/client/includes/Hooks/MagicWordHookHandlers.php
new file mode 100644
index 0000000..f01a177
--- /dev/null
+++ b/client/includes/Hooks/MagicWordHookHandlers.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Wikibase\Client\Hooks;
+
+use Language;
+use Message;
+use Parser;
+use ResourceLoaderContext;
+use Wikibase\SettingsArray;
+use Wikibase\Client\WikibaseClient;
+
+/**
+ * File defining hooks related to magic words
+ * @license GPL-2.0+
+ */
+class MagicWordHookHandlers {
+ /**
+ * @var SettingsArray $settings
+ */
+ protected $settings;
+
+ /**
+ * WikibaseClient $wikibaseClient
+ */
+ public function __construct( SettingsArray $settings ) {
+ $this->settings = $settings;
+ }
+
+ /**
+ * @return self
+ */
+ public static function newFromGlobalState() {
+ $client = WikibaseClient::getDefaultInstance();
+ return new self( $client->getSettings() );
+ }
+
+ /**
+ * Register the magic word.
+ *
+ * @param string[] &$aCustomVariableIds
+ *
+ * @return bool
+ */
+ public static function onMagicWordwgVariableIDs( &$aCustomVariableIds )
{
+ $aCustomVariableIds[] = 'noexternallanglinks';
+ $aCustomVariableIds[] = 'wbreponame';
+
+ return true;
+ }
+
+ /**
+ * Gets the user-facing repository name.
+ *
+ * This can either be a message's text, or the raw value from
+ * settings if that is not a message
+ *
+ * @param Language $lang Language to get text in
+ */
+ protected function getRepoName( Language $lang ) {
+ $repoSiteName = $this->settings->getSetting( 'repoSiteName' );
+
+ $message = new Message( $repoSiteName );
+ $message->inLanguage( $lang );
+
+ if ( $message->exists() ) {
+ return $message->parse();
+ } else {
+ return $repoSiteName;
+ }
+ }
+
+ /**
+ * Static handler for the ParserGetVariableValueSwitch hook
+ *
+ * @param Parser &$parser
+ * @param array &$cache
+ * @param string &$magicWordId
+ * @param string &$ret
+ *
+ * @return bool
+ */
+ public static function onParserGetVariableValueSwitch( Parser &$parser,
&$cache, &$magicWordId, &$ret ) {
+ $handler = self::newFromGlobalState();
+ $handler->doParserGetVariableValueSwitch( $parser, $cache,
$magicWordId, $ret );
+ }
+
+ /**
+ * Apply the magic word.
+ *
+ * @param Parser &$parser
+ * @param array &$cache
+ * @param string &$magicWordId
+ * @param string &$ret
+ *
+ * @return bool
+ */
+ protected function doParserGetVariableValueSwitch( Parser &$parser,
&$cache, &$magicWordId, &$ret ) {
+ if ( $magicWordId === 'noexternallanglinks' ) {
+ NoLangLinkHandler::handle( $parser, '*' );
+ } elseif ( $magicWordId === 'wbreponame' ) {
+ $lang = $parser->getTargetLanguage();
+ $ret = $this->getRepoName( $lang );
+ }
+
+ return true;
+ }
+
+ /**
+ * Static handler for the ResourceLoaderJqueryMsgModuleMagicWords hook
+ *
+ * @param array $magicWords
+ */
+ public static function onResourceLoaderJqueryMsgModuleMagicWords(
ResourceLoaderContext $context, array &$magicWords ) {
+ $handler = self::newFromGlobalState();
+ $handler->doResourceLoaderJqueryMsgModuleMagicWords( $context,
$magicWords );
+ }
+
+ /**
+ * Adds magic word constant(s) for use by jQueryMsg
+ *
+ * @param array $magicWords Associative array mapping all-caps magic
+ * words to string values
+ */
+ protected function doResourceLoaderJqueryMsgModuleMagicWords(
ResourceLoaderContext $context, array &$magicWords ) {
+ $lang = Language::factory( $context->getLanguage() );
+ $magicWords['WBREPONAME'] = $this->getRepoName( $lang );
+ }
+
+}
diff --git a/client/includes/Modules/SiteModule.php
b/client/includes/Modules/SiteModule.php
index 2973094..72cdeb6 100644
--- a/client/includes/Modules/SiteModule.php
+++ b/client/includes/Modules/SiteModule.php
@@ -4,9 +4,11 @@
use FormatJson;
use MediaWikiSite;
+use ResourceLoader;
use ResourceLoaderContext;
use ResourceLoaderModule;
use Wikibase\Client\WikibaseClient;
+use Xml;
/**
* Provides information about the current (client) site
@@ -42,7 +44,11 @@
);
}
- return 'mediaWiki.config.set( "wbCurrentSite", ' .
FormatJson::encode( $currentSite ) . ' );';
+ return Xml::encodeJsCall(
+ 'mw.config.set',
+ [ 'wbCurrentSite', $currentSite ],
+ ResourceLoader::inDebugMode()
+ );
}
}
diff --git
a/client/tests/phpunit/includes/Hooks/ChangesListSpecialPageHookHandlersTest.php
b/client/tests/phpunit/includes/Hooks/ChangesListSpecialPageHookHandlersTest.php
index 2a3dfe4..aa51402 100644
---
a/client/tests/phpunit/includes/Hooks/ChangesListSpecialPageHookHandlersTest.php
+++
b/client/tests/phpunit/includes/Hooks/ChangesListSpecialPageHookHandlersTest.php
@@ -2,10 +2,12 @@
namespace Wikibase\Client\Tests\Hooks;
+use ExtensionRegistry;
use FauxRequest;
use FormOptions;
use IDatabase;
use SpecialPageFactory;
+use TestingAccessWrapper;
use User;
use Wikibase\Client\Hooks\ChangesListSpecialPageHookHandlers;
use Wikimedia\Rdbms\LoadBalancer;
@@ -18,35 +20,90 @@
*
* @license GPL-2.0+
* @author Katie Filbert < [email protected] >
+ * @author Matthew Flaschen < [email protected] >
*/
class ChangesListSpecialPageHookHandlersTest extends
\PHPUnit_Framework_TestCase {
+ protected $extensionRegistry;
- public function testOnChangesListSpecialPageFilters() {
+ protected $oldExtensionRegistryLoaded;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->extensionRegistry = TestingAccessWrapper::newFromObject(
+ ExtensionRegistry::getInstance()
+ );
+
+ $this->oldExtensionRegistryLoaded =
$this->extensionRegistry->loaded;
+
+ // Forget about the other extensions. Although ORES may be
loaded,
+ // since this is only unit-testing *our* listener, ORES's
listener
+ // hasn't run, so for all intents and purposes it's not loaded.
+ $this->extensionRegistry->loaded = [ 'Wikibase' ];
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+
+ $this->extensionRegistry->loaded =
$this->oldExtensionRegistryLoaded;
+ }
+
+ public function testAddFilter() {
$user = $this->getUser(
array(
- array( 'usernewrc' => 0 )
+ array( 'usenewrc' => 0 )
)
);
/** @var \ChangesListSpecialPage $specialPage */
$specialPage = SpecialPageFactory::getPage( 'Recentchanges' );
+
+ $wrappedSpecialPage = TestingAccessWrapper::newFromObject(
+ $specialPage
+ );
+
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
+ $this->getRequest( array() ),
+ $this->getUser( [] ),
+ $this->getLoadBalancer(),
+ 'Recentchanges',
+ true
+ ) );
+
$specialPage->getContext()->setUser( $user );
- $filters = array();
-
-
ChangesListSpecialPageHookHandlers::onChangesListSpecialPageFilters(
- $specialPage,
- $filters
+ // Register built-in filters, since the Wikidata one uses its
group
+ $wrappedSpecialPage->registerFiltersFromDefinitions(
+ $wrappedSpecialPage->filterGroupDefinitions
);
- $expected = array(
- 'hideWikibase' => array(
- 'msg' => 'wikibase-rc-hide-wikidata',
- 'default' => true
- )
+ $hookHandler->addFilter(
+ $specialPage
);
- $this->assertSame( $expected, $filters );
+ $changeType = $specialPage->getFilterGroup( 'changeType' );
+ $filter = $changeType->getFilter( 'hideWikibase' );
+
+ // I could do all of getJsData(), but that would make it
brittle to
+ // unrelated changes.
+ $expectedFields = [
+ 'label' => 'wikibase-rcfilters-hide-wikibase-label',
+ 'description' =>
'wikibase-rcfilters-hide-wikibase-description',
+ 'showHide' => 'wikibase-rc-hide-wikidata',
+ 'default' => true,
+ ];
+
+ $actualFields = [
+ 'label' => $filter->getLabel(),
+ 'description' => $filter->getDescription(),
+ 'showHide' => $filter->getShowHide(),
+ 'default' => $filter->getDefault(),
+ ];
+
+ $this->assertSame(
+ $expectedFields,
+ $actualFields
+ );
}
public function testOnChangesListSpecialPageQuery() {
@@ -73,86 +130,138 @@
}
/**
- * @dataProvider addWikibaseConditionsProvider
+ * @dataProvider addWikibaseConditionsIfFilterUnavailableProvider
*/
- public function testAddWikibaseConditions(
- array $expected,
- array $userOptions,
- $optionDefault
- ) {
+ public function testAddWikibaseConditionsIfFilterUnavailable(
$expectedAddConditionsCalls, $hasWikibaseChangesEnabled ) {
+ $hookHandlerMock = $this->getMockBuilder(
ChangesListSpecialPageHookHandlers::class )
+ ->setConstructorArgs(
+ [
+ $this->getRequest( array() ),
+ $this->getUser( [] ),
+ $this->getLoadBalancer(),
+ 'Recentchanges',
+ true
+ ]
+ )
+ ->setMethods( [
+ 'hasWikibaseChangesEnabled',
+ 'addWikibaseConditions'
+ ] )
+ ->getMock();
+
+ $hookHandlerMock->method( 'hasWikibaseChangesEnabled' )->will(
+ $this->returnValue( $hasWikibaseChangesEnabled )
+ );
+
+ $hookHandlerMock->expects( $this->exactly(
$expectedAddConditionsCalls ) )
+ ->method( 'addWikibaseConditions' )
+ ->with(
+ $this->isInstanceOf( IDatabase::class ),
+ $this->equalTo( [] )
+ );
+
+ $conds = [];
+
+ $hookHandlerMock = TestingAccessWrapper::newFromObject(
$hookHandlerMock );
+ $hookHandlerMock->__call(
'addWikibaseConditionsIfFilterUnavailable', [ &$conds ] );
+ }
+
+ public function addWikibaseConditionsIfFilterUnavailableProvider() {
+ return [
+ [
+ 0,
+ true
+ ],
+
+ [
+ 1,
+ false
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider getOptionNameProvider
+ */
+ public function testGetOptionName( $expected, $pageName ) {
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
+ $this->getRequest( array() ),
+ $this->getUser( [] ),
+ $this->getLoadBalancer(),
+ $pageName,
+ true
+ ) );
+
+ $this->assertSame(
+ $expected,
+ $hookHandler->getOptionName()
+ );
+ }
+
+ public function getOptionNameProvider() {
+ return [
+ [
+ 'wlshowwikibase',
+ 'Watchlist'
+ ],
+
+ [
+ 'rcshowwikidata',
+ 'Recentchanges',
+ ],
+
+ [
+ 'rcshowwikidata',
+ 'Recentchangeslinked'
+ ],
+ ];
+ }
+
+ public function testAddWikibaseConditions() {
$hookHandler = new ChangesListSpecialPageHookHandlers(
$this->getRequest( array() ),
- $this->getUser( $userOptions ),
+ $this->getUser( [] ),
$this->getLoadBalancer(),
'Watchlist',
true
);
- $opts = new FormOptions();
- $opts->add( 'hideWikibase', $optionDefault );
-
$conds = array();
- $hookHandler->addWikibaseConditions( $conds, $opts );
+ $hookHandler->addWikibaseConditions(
+ wfGetDB( DB_REPLICA ),
+ $conds
+ );
+
+ $expected = [ "rc_source != 'wb'" ];
$this->assertEquals( $expected, $conds );
}
- public function addWikibaseConditionsProvider() {
- return array(
- array(
- array(),
- array( 'usenewrc' => 0, 'wlshowwikibase' => 1 ),
- false
- ),
- array(
- array( "rc_source != 'wb'" ),
- array( 'usenewrc' => 0 ),
- true
- )
- );
- }
-
- public function testAddWikibaseConditions_wikibaseChangesDisabled() {
- $hookHandler = new ChangesListSpecialPageHookHandlers(
- $this->getRequest( array() ),
- $this->getUser( array( 'usenewrc' => 1 ) ),
- $this->getLoadBalancer(),
- 'Watchlist',
- true
- );
-
- $opts = new FormOptions();
-
- $conds = array();
- $hookHandler->addWikibaseConditions( $conds, $opts );
-
- $this->assertEquals( array( "rc_source != 'wb'" ), $conds );
- }
-
/**
- * @dataProvider filterNotAddedWhenUsingEnhancedChangesProvider
+ * @dataProvider
hasWikibaseChangesEnabledWhenUsingEnhancedChangesProvider
*/
- public function testFilterNotAddedWhenUsingEnhancedChanges(
+ public function testHasWikibaseChangesEnabledWhenUsingEnhancedChanges(
array $requestParams,
array $userOptions,
$pageName,
$message
) {
- $hookHandler = new ChangesListSpecialPageHookHandlers(
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
$this->getRequest( $requestParams ),
$this->getUser( $userOptions ),
$this->getLoadBalancer(),
$pageName,
true
+ ) );
+
+ $this->assertSame(
+ false,
+ $hookHandler->hasWikibaseChangesEnabled(),
+ $message
);
-
- $filters = array();
- $hookHandler->addFilterIfEnabled( $filters );
-
- $this->assertSame( array(), $filters, $message );
}
- public function filterNotAddedWhenUsingEnhancedChangesProvider() {
+ public function
hasWikibaseChangesEnabledWhenUsingEnhancedChangesProvider() {
return array(
array(
array(),
@@ -194,37 +303,30 @@
}
/**
- * @dataProvider filter_withoutShowWikibaseEditsByDefaultPreference
+ * @dataProvider
hasWikibaseChangesEnabled_withoutShowWikibaseEditsByDefaultPreferenceProvider
*/
- public function testFilter_withoutShowWikibaseEditsByDefaultPreference(
+ public function
testHasWikibaseChangesEnabled_withoutShowWikibaseEditsByDefaultPreference(
array $requestParams,
array $userOptions,
$expectedFilterName,
$expectedToggleDefault,
$specialPageName
) {
- $hookHandler = new ChangesListSpecialPageHookHandlers(
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
$this->getRequest( $requestParams ),
$this->getUser( $userOptions ),
$this->getLoadBalancer(),
$specialPageName,
true
+ ) );
+
+ $this->assertSame(
+ true,
+ $hookHandler->hasWikibaseChangesEnabled()
);
-
- $filters = array();
- $hookHandler->addFilterIfEnabled( $filters );
-
- $expected = array(
- $expectedFilterName => array(
- 'msg' => 'wikibase-rc-hide-wikidata',
- 'default' => $expectedToggleDefault
- )
- );
-
- $this->assertSame( $expected, $filters );
}
- public function filter_withoutShowWikibaseEditsByDefaultPreference() {
+ public function
hasWikibaseChangesEnabled_withoutShowWikibaseEditsByDefaultPreferenceProvider()
{
return array(
array(
array(),
@@ -272,37 +374,30 @@
}
/**
- * @dataProvider filter_withShowWikibaseEditsByDefaultPreference
+ * @dataProvider
hasWikibaseChangesEnabled_withShowWikibaseEditsByDefaultPreferenceProvider
*/
- public function testFilter_withShowWikibaseEditsByDefaultPreference(
+ public function
testHasWikibaseChangesEnabled_withShowWikibaseEditsByDefaultPreference(
array $requestParams,
array $userOptions,
$expectedFilterName,
$expectedToggleDefault,
$specialPageName
) {
- $hookHandler = new ChangesListSpecialPageHookHandlers(
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
$this->getRequest( $requestParams ),
$this->getUser( $userOptions ),
$this->getLoadBalancer(),
$specialPageName,
true
+ ) );
+
+ $this->assertSame(
+ true,
+ $hookHandler->hasWikibaseChangesEnabled()
);
-
- $filters = array();
- $hookHandler->addFilterIfEnabled( $filters );
-
- $expected = array(
- $expectedFilterName => array(
- 'msg' => 'wikibase-rc-hide-wikidata',
- 'default' => $expectedToggleDefault
- )
- );
-
- $this->assertSame( $expected, $filters );
}
- public function filter_withShowWikibaseEditsByDefaultPreference() {
+ public function
hasWikibaseChangesEnabled_withShowWikibaseEditsByDefaultPreferenceProvider() {
return array(
array(
array(),
@@ -343,28 +438,28 @@
}
/**
- * @dataProvider
filterNotAddedWhenExternalRecentChangesDisabledProvider() {
+ * @dataProvider
hasWikibaseChangesEnabledWhenExternalRecentChangesDisabledProvider() {
*/
- public function testFilterNotAddedWhenExternalRecentChangesDisabled(
$specialPageName ) {
- $hookHandler = new ChangesListSpecialPageHookHandlers(
+ public function
testHasWikibaseChangesEnabledWhenExternalRecentChangesDisabled(
$specialPageName ) {
+ $hookHandler = TestingAccessWrapper::newFromObject( new
ChangesListSpecialPageHookHandlers(
$this->getRequest( array() ),
$this->getUser( array( 'usenewrc' => 0 ) ),
$this->getLoadBalancer(),
$specialPageName,
- false
+ /* $showExternalChanges= */ false
+ ) );
+
+ $this->assertSame(
+ false,
+ $hookHandler->hasWikibaseChangesEnabled()
);
-
- $filters = array();
- $hookHandler->addFilterIfEnabled( $filters );
-
- $this->assertSame( array(), $filters );
}
- public function
filterNotAddedWhenExternalRecentChangesDisabledProvider() {
+ public function
hasWikibaseChangesEnabledWhenExternalRecentChangesDisabledProvider() {
return array(
array( 'Watchlist' ),
- array( 'RecentChanges' ),
- array( 'RecentChangesLinked' )
+ array( 'Recentchanges' ),
+ array( 'Recentchangeslinked' )
);
}
diff --git a/client/tests/phpunit/includes/Hooks/MagicWordHookHandlersTest.php
b/client/tests/phpunit/includes/Hooks/MagicWordHookHandlersTest.php
new file mode 100644
index 0000000..7436e53
--- /dev/null
+++ b/client/tests/phpunit/includes/Hooks/MagicWordHookHandlersTest.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Wikibase\Client\Tests\Hooks;
+
+use Language;
+use Wikibase\Client\Hooks\MagicWordHookHandlers;
+use MediaWiki\MediaWikiServices;
+use MediaWikiTestCase;
+use Parser;
+use Wikibase\SettingsArray;
+use Title;
+use TestingAccessWrapper;
+use Wikibase\Client\WikibaseClient;
+
+/**
+ * @covers Wikibase\Client\Hooks\MagicWordHookHandlers
+ *
+ * @group WikibaseClient
+ * @group Wikibase
+ *
+ * @license GPL-2.0+
+ * @author Matthew Flaschen < [email protected] >
+ */
+class MagicWordHookHandlersTest extends MediaWikiTestCase {
+
+ /**
+ * @dataProvider provideGetRepoName
+ */
+ public function testGetRepoName( $expected, $langCode, $siteName ) {
+ $settings = new SettingsArray();
+ $settings->setSetting( 'repoSiteName', $siteName );
+
+ $handler = TestingAccessWrapper::newFromObject(
+ new MagicWordHookHandlers( $settings )
+ );
+
+ $actual = $handler->getRepoName(
+ Language::factory( $langCode )
+ );
+
+ $this->assertEquals(
+ $expected,
+ $actual
+ );
+ }
+
+ // I looked at mocking the messages, but MessageCache
+ // is not in ServiceWiring (yet), so these are real messsages,
+ // except non-existent-message to test that feature.
+
+ public function provideGetRepoName() {
+ return [
+ [
+ 'Client for the Wikibase extension',
+ 'en',
+ 'wikibase-client-desc',
+ ],
+
+ [
+ 'Cliente para la extensión Wikibase',
+ 'es',
+ 'wikibase-client-desc',
+ ],
+
+ [
+ 'non-existent-message',
+ 'en',
+ 'non-existent-message',
+ ],
+ ];
+ }
+
+ // TODO: Test noexternallanglinks
+
+ public function testDoParserGetVariableValueSwitch() {
+ $parser = $this->getMockBuilder( Parser::class )
+ ->getMock();
+
+ // Configure the stub.
+ $parser->method( 'getTargetLanguage' )
+ ->willReturn( Language::factory( 'en' ) );
+
+ $ret = null;
+
+ $settings = new SettingsArray();
+ $settings->setSetting( 'repoSiteName', 'wikibase-client-desc' );
+
+ $handler = TestingAccessWrapper::newFromObject(
+ new MagicWordHookHandlers( $settings )
+ );
+
+ $cache = [];
+ $word = 'wbreponame';
+ call_user_func_array(
+ [ $handler, 'doParserGetVariableValueSwitch' ],
+ [ &$parser, &$cache, &$word, &$ret ]
+ );
+
+ $this->assertEquals(
+ 'Client for the Wikibase extension',
+ $ret
+ );
+ }
+
+}
diff --git a/client/tests/phpunit/includes/Modules/SiteModuleTest.php
b/client/tests/phpunit/includes/Modules/SiteModuleTest.php
index 4567053..1353eea 100644
--- a/client/tests/phpunit/includes/Modules/SiteModuleTest.php
+++ b/client/tests/phpunit/includes/Modules/SiteModuleTest.php
@@ -29,8 +29,8 @@
public function testGetScript() {
$module = new SiteModule();
$script = $module->getScript( $this->getContext() );
- $this->assertStringStartsWith( 'mediaWiki.config.set(
"wbCurrentSite", ', $script );
- $this->assertStringEndsWith( ' );', $script );
+ $this->assertStringStartsWith(
'mw.config.set("wbCurrentSite",', $script );
+ $this->assertStringEndsWith( ');', $script );
}
}
--
To view, visit https://gerrit.wikimedia.org/r/342294
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I0b910d273a434b5bcbc38deb0fb04f6a2cd8ac8c
Gerrit-PatchSet: 12
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Mattflaschen <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits