jenkins-bot has submitted this change and it was merged. Change subject: Error message for Special:GoToLinkedPage ......................................................................
Error message for Special:GoToLinkedPage Error message for Special:GoToLinkedPage -The entered ID of the item is not valid -Item was not found -There was no page found for that combination of item and site Bug: T72127 Change-Id: I185aacfe288e8e12b5202c59b366233c236263ac --- M repo/i18n/en.json M repo/i18n/qqq.json M repo/includes/specials/SpecialGoToLinkedPage.php M repo/tests/phpunit/includes/specials/SpecialGoToLinkedPageTest.php 4 files changed, 148 insertions(+), 27 deletions(-) Approvals: Hoo man: Looks good to me, approved jenkins-bot: Verified diff --git a/repo/i18n/en.json b/repo/i18n/en.json index 401be0c..848d123 100644 --- a/repo/i18n/en.json +++ b/repo/i18n/en.json @@ -141,6 +141,9 @@ "wikibase-gotolinkedpage-lookup-item": "Item id:", "wikibase-gotolinkedpage-submit": "Go", "wikibase-gotolinkedpage-summary": "Special:GoToLinkedPage is used to find the page for an item on a connected site.<br /> The left field, \"Site:\", is where you enter the language and site code.<br /> For the right field, \"Item id:\", you must put in the item id you are looking for.", + "wikibase-gotolinkedpage-error-page-not-found": "There was no page found for that combination of item and site", + "wikibase-gotolinkedpage-error-item-id-invalid": "The entered ID of the item is not valid", + "wikibase-gotolinkedpage-error-item-not-found": "Item was not found", "special-itemdisambiguation": "Item disambiguation", "wikibase-itemdisambiguation-lookup-fieldset": "Search for items by language and label", "wikibase-itemdisambiguation-lookup-language": "Language code:", diff --git a/repo/i18n/qqq.json b/repo/i18n/qqq.json index 09bb7e7..596ad81 100644 --- a/repo/i18n/qqq.json +++ b/repo/i18n/qqq.json @@ -169,6 +169,9 @@ "wikibase-gotolinkedpage-lookup-item": "Label for the textfield holding the item ID. See also the Wikidata glossary for [[d:Wikidata:Glossary#Items|items]].", "wikibase-gotolinkedpage-submit": "Text for the submit button in the search form which if successfully will go (redirect) to the specified linked page (sitelink).\n{{Identical|Go}}", "wikibase-gotolinkedpage-summary": "Summary and explanation of the GoToLinkedPage.\n\nFor right-to-left languages swap \"right\" and \"left\".\n\n\"Site\" is {{msg-mw|wikibase-gotolinkedpage-lookup-site}}.\n\n\"item id\" is {{msg-mw|wikibase-gotolinkedpage-lookup-item}}.", + "wikibase-gotolinkedpage-error-page-not-found": "Error message when no page was found for the given input", + "wikibase-gotolinkedpage-error-item-id-invalid": "Error message when the syntax of the ID is invalid", + "wikibase-gotolinkedpage-error-item-not-found": "Error message when there is no item with the given ID", "special-itemdisambiguation": "{{doc-special|ItemDisambiguation}}\nThis special page returns all items with a given label. It provides an interface to disambiguate them. See also the Wikidata glossary for [[d:Wikidata:Glossary#languageattribute-label|label]] and [[d:Wikidata:Glossary#Items|items]].", "wikibase-itemdisambiguation-lookup-fieldset": "This is the title for the fieldset on the special page for further refining the search. This is the search by language and label.", "wikibase-itemdisambiguation-lookup-language": "Label for the textfield holding the language id.\n{{Identical|Language code}}", diff --git a/repo/includes/specials/SpecialGoToLinkedPage.php b/repo/includes/specials/SpecialGoToLinkedPage.php index bba00d6..b449ed4 100644 --- a/repo/includes/specials/SpecialGoToLinkedPage.php +++ b/repo/includes/specials/SpecialGoToLinkedPage.php @@ -9,6 +9,9 @@ use Wikibase\Lib\Store\EntityRedirectLookup; use Wikibase\Lib\Store\SiteLinkLookup; use Wikibase\Repo\WikibaseRepo; +use Wikibase\Lib\Store\EntityLookup; +use Wikibase\DataModel\Services\EntityId\EntityIdParsingException; +use Wikibase\DataModel\Services\EntityId\EntityIdParser; /** * Enables accessing a linked page on a site by providing the item id and site @@ -35,6 +38,22 @@ private $redirectLookup; /** + * @var EntityIdParser + */ + private $idParser; + + /** + * @var EntityLookup + */ + private $entityLookup; + + /** + * Error message key + * @var string|null + */ + private $errorMessageKey; + + /** * @see SpecialWikibasePage::__construct */ public function __construct() { @@ -45,8 +64,12 @@ $this->initServices( $wikibaseRepo->getSiteStore(), $wikibaseRepo->getStore()->newSiteLinkStore(), - $wikibaseRepo->getStore()->getEntityRedirectLookup() + $wikibaseRepo->getStore()->getEntityRedirectLookup(), + $wikibaseRepo->getEntityIdParser(), + $wikibaseRepo->getStore()->getEntityLookup() ); + + $this->errorMessageKey = null; } /** @@ -60,42 +83,42 @@ public function initServices( SiteStore $siteStore, SiteLinkLookup $siteLinkLookup, - EntityRedirectLookup $redirectLookup + EntityRedirectLookup $redirectLookup, + EntityIdParser $idParser, + EntityLookup $entityLookup ) { $this->siteStore = $siteStore; $this->siteLinkLookup = $siteLinkLookup; $this->redirectLookup = $redirectLookup; + $this->idParser = $idParser; + $this->entityLookup = $entityLookup; } /** * @param string $subPage - * @return array array( string $site, ItemId $itemId, string $itemString ) + * @return array array( string $site, string $itemString ) */ protected function getArguments( $subPage ) { $request = $this->getRequest(); $parts = ( $subPage === '' ) ? array() : explode( '/', $subPage, 2 ); $site = trim( $request->getVal( 'site', isset( $parts[0] ) ? $parts[0] : '' ) ); - $itemString = trim( $request->getVal( 'itemid', isset( $parts[1] ) ? $parts[1] : 0 ) ); - try { - $itemId = new ItemId( $itemString ); - } catch ( InvalidArgumentException $ex ) { - $itemId = null; - $itemString = ''; - } - return array( $site, $itemId, $itemString ); + return array( $site, $itemString ); } /** * @param string $site - * @param ItemId|null $itemId + * @param string|null $itemString * @return string|null the URL to redirect to or null if the sitelink does not exist */ - protected function getTargetUrl( $site, ItemId $itemId = null ) { + protected function getTargetUrl( $site, $itemString = null ) { + $itemId = $this->getItemId( $itemString ); + if ( $site === '' || $itemId === null ) { return null; } + $site = $this->stringNormalizer->trimToNFC( $site ); if ( !$this->siteStore->getSite( $site ) ) { @@ -115,7 +138,35 @@ $siteObj = $this->siteStore->getSite( $site ); $url = $siteObj->getPageUrl( $pageName ); return $url; + } else { + $this->errorMessageKey = "page-not-found"; } + + return null; + } + + /** + * Parses a string to itemId + * + * @param string $itemString + * @return ItemId|null + */ + private function getItemId( $itemString ) { + try { + $itemId = $this->idParser->parse( $itemString ); + if ( $itemId instanceof ItemId ) { + if ( !$this->entityLookup->hasEntity( $itemId ) ) { + $this->errorMessageKey = "item-not-found"; + return null; + } + return $itemId; + } + } catch ( EntityIdParsingException $e ) { + $this->errorMessageKey = 'item-id-invalid'; + } catch ( InvalidArgumentException $e ) { + $this->errorMessageKey = 'item-id-invalid'; + } + return null; } @@ -151,14 +202,17 @@ */ public function execute( $subPage ) { parent::execute( $subPage ); - list( $site, $itemId, $itemString ) = $this->getArguments( $subPage ); + list( $site, $itemString ) = $this->getArguments( $subPage ); - $url = $this->getTargetUrl( $site, $itemId ); - if ( null === $url ) { - $this->outputForm( $site, $itemString ); - } else { - $this->getOutput()->redirect( $url ); + if ( !empty( $site ) || !empty( $itemString ) ) { + $url = $this->getTargetUrl( $site, $itemString ); + if ( null !== $url ) { + return $this->getOutput()->redirect( $url ); + } } + + $this->outputError(); + $this->outputForm( $site, $itemString ); } /** @@ -231,4 +285,14 @@ ); } + /** + * Outputs an error message + */ + private function outputError() { + if ( $this->errorMessageKey !== null ) { + $this->showErrorHTML( + $this->msg( 'wikibase-gotolinkedpage-error-' . $this->errorMessageKey ) ); + } + } + } diff --git a/repo/tests/phpunit/includes/specials/SpecialGoToLinkedPageTest.php b/repo/tests/phpunit/includes/specials/SpecialGoToLinkedPageTest.php index e987220..ca2972f 100644 --- a/repo/tests/phpunit/includes/specials/SpecialGoToLinkedPageTest.php +++ b/repo/tests/phpunit/includes/specials/SpecialGoToLinkedPageTest.php @@ -9,6 +9,7 @@ use Wikibase\Lib\Store\EntityRedirectLookup; use Wikibase\Lib\Store\SiteLinkLookup; use Wikibase\Repo\Specials\SpecialGoToLinkedPage; +use Wikibase\DataModel\Entity\EntityIdParser; /** * @covers Wikibase\Repo\Specials\SpecialGoToLinkedPage @@ -84,6 +85,39 @@ } /** + * @return EntityIdParser + */ + private function getEntityIdParser() { + $mock = $this->getMock( 'Wikibase\DataModel\Services\EntityId\EntityIdParser' ); + $mock->expects( $this->any() ) + ->method( 'parse' ) + ->will( $this->returnCallback( function( $itemString ) { + return new ItemId( $itemString ); + } ) ); + + return $mock; + } + + /** + * @return EntityLookup + */ + private function getEntitylookup() { + $mock = $this->getMock( 'Wikibase\Lib\Store\EntityLookup' ); + $mock->expects( $this->any() ) + ->method( 'hasEntity' ) + ->will( $this->returnCallback( function( ItemId $itemId ) { + if ( $itemId->getSerialization() === 'Q23' + || $itemId->getSerialization() === 'Q24') { + return true; + } else { + return false; + } + } ) ); + + return $mock; + } + + /** * @return SpecialGoToLinkedPage */ protected function newSpecialPage() { @@ -92,7 +126,9 @@ $page->initServices( $this->getMockSiteStore(), $this->getMockSiteLinkLookup(), - $this->getEntityRedirectLookup() + $this->getEntityRedirectLookup(), + $this->getEntityIdParser(), + $this->getEntitylookup() ); return $page; @@ -100,16 +136,18 @@ public function requestWithoutRedirectProvider() { $cases = array(); - $cases['empty'] = array( '', null, '', '' ); - $cases['invalid'] = array( 'enwiki/invalid', null, 'enwiki', '' ); - $cases['notFound'] = array( 'enwiki/Q42', null, 'enwiki', 'Q42' ); + $cases['empty'] = array( '', null, '', '', '' ); + $cases['invalidItemID'] = array( 'enwiki/invalid', null, 'enwiki', 'invalid', 'The entered ID of the item is not valid' ); + $cases['notFound'] = array( 'enwiki/Q42', null, 'enwiki', 'Q42', 'Item was not found' ); + $cases['notFound2'] = array( 'XXwiki/Q23', null, 'XXwiki', 'Q23', 'There was no page found for that combination of item and site' ); + return $cases; } /** * @dataProvider requestWithoutRedirectProvider */ - public function testExecuteWithoutRedirect( $sub, $target, $site, $item ) { + public function testExecuteWithoutRedirect( $sub, $target, $site, $item, $error ) { /* @var FauxResponse $response */ list( $output, $response ) = $this->executeSpecialPage( $sub ); @@ -137,10 +175,23 @@ 'id' => 'wb-gotolinkedpage-submit', 'class' => 'wb-input-button', 'type' => 'submit', - 'name' => 'submit', - ) ); + 'name' => 'submit' + ) + ); foreach ( $matchers as $key => $matcher ) { - $this->assertTag( $matcher, $output, "Failed to match html output for: ".$key ); + $this->assertTag( $matcher, $output, "Failed to match html output for: " . $key ); + } + + $errorMatch = array( + 'tag' => 'p', + 'content' => $error, + 'attributes' => array( + 'class' => 'error' + ) + ); + + if ( !empty( $error ) ) { + $this->assertTag( $errorMatch, $output, "Failed to match error: " . $error ); } } -- To view, visit https://gerrit.wikimedia.org/r/228810 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I185aacfe288e8e12b5202c59b366233c236263ac Gerrit-PatchSet: 12 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Jonas Kress (WMDE) <jonas.kr...@wikimedia.de> Gerrit-Reviewer: Addshore <addshorew...@gmail.com> Gerrit-Reviewer: Hoo man <h...@online.de> Gerrit-Reviewer: Siebrand <siebr...@kitano.nl> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits