Merge "Make Revision::__construct work with bad page ID"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 11 Jan 2018 16:33:34 +0000 (16:33 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 11 Jan 2018 16:33:34 +0000 (16:33 +0000)
includes/Revision.php
includes/Storage/RevisionArchiveRecord.php
includes/Storage/RevisionRecord.php
includes/Storage/RevisionStoreRecord.php
includes/specials/SpecialSearch.php
includes/widget/search/SimpleSearchResultSetWidget.php
includes/widget/search/SimpleSearchResultWidget.php
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionTest.php

index 8849697..510c1ee 100644 (file)
@@ -653,20 +653,27 @@ class Revision implements IDBAccessObject {
        /**
         * Returns the length of the text in this revision, or null if unknown.
         *
-        * @return int
+        * @return int|null
         */
        public function getSize() {
-               return $this->mRecord->getSize();
+               try {
+                       return $this->mRecord->getSize();
+               } catch ( RevisionAccessException $ex ) {
+                       return null;
+               }
        }
 
        /**
         * Returns the base36 sha1 of the content in this revision, or null if unknown.
         *
-        * @return string
+        * @return string|null
         */
        public function getSha1() {
-               // XXX: we may want to drop all the hashing logic, it's not worth the overhead.
-               return $this->mRecord->getSha1();
+               try {
+                       return $this->mRecord->getSha1();
+               } catch ( RevisionAccessException $ex ) {
+                       return null;
+               }
        }
 
        /**
@@ -1110,7 +1117,11 @@ class Revision implements IDBAccessObject {
 
                $comment = CommentStoreComment::newUnsavedComment( $summary, null );
 
-               $title = Title::newFromID( $pageId );
+               $title = Title::newFromID( $pageId, Title::GAID_FOR_UPDATE );
+               if ( $title === null ) {
+                       return null;
+               }
+
                $rec = self::getRevisionStore()->newNullRevision( $dbw, $title, $comment, $minor, $user );
 
                return new Revision( $rec );
index 419cb95..9999179 100644 (file)
@@ -107,6 +107,7 @@ class RevisionArchiveRecord extends RevisionRecord {
        }
 
        /**
+        * @throws RevisionAccessException if the size was unknown and could not be calculated.
         * @return int The nominal revision size, never null. May be computed on the fly.
         */
        public function getSize() {
@@ -120,6 +121,7 @@ class RevisionArchiveRecord extends RevisionRecord {
        }
 
        /**
+        * @throws RevisionAccessException if the hash was unknown and could not be calculated.
         * @return string The revision hash, never null. May be computed on the fly.
         */
        public function getSha1() {
index f490f9b..8734f48 100644 (file)
@@ -242,6 +242,7 @@ abstract class RevisionRecord {
         *
         * MCR migration note: this replaces Revision::getSize
         *
+        * @throws RevisionAccessException if the size was unknown and could not be calculated.
         * @return int
         */
        abstract public function getSize();
@@ -254,6 +255,7 @@ abstract class RevisionRecord {
         *
         * MCR migration note: this replaces Revision::getSha1
         *
+        * @throws RevisionAccessException if the hash was unknown and could not be calculated.
         * @return string
         */
        abstract public function getSha1();
index 341855d..e8efcfa 100644 (file)
@@ -150,6 +150,7 @@ class RevisionStoreRecord extends RevisionRecord {
        }
 
        /**
+        * @throws RevisionAccessException if the size was unknown and could not be calculated.
         * @return string The nominal revision size, never null. May be computed on the fly.
         */
        public function getSize() {
@@ -163,6 +164,7 @@ class RevisionStoreRecord extends RevisionRecord {
        }
 
        /**
+        * @throws RevisionAccessException if the hash was unknown and could not be calculated.
         * @return string The revision hash, never null. May be computed on the fly.
         */
        public function getSha1() {
index b3a58cb..f826844 100644 (file)
@@ -394,7 +394,8 @@ class SpecialSearch extends SpecialPage {
                $linkRenderer = $this->getLinkRenderer();
                $mainResultWidget = new FullSearchResultWidget( $this, $linkRenderer );
 
-               if ( $search->getFeatureData( 'enable-new-crossproject-page' ) ) {
+               // Default (null) on. Can be explicitly disabled.
+               if ( $search->getFeatureData( 'enable-new-crossproject-page' ) !== false ) {
                        $sidebarResultWidget = new InterwikiSearchResultWidget( $this, $linkRenderer );
                        $sidebarResultsWidget = new InterwikiSearchResultSetWidget(
                                $this,
index d6583a3..d0c259f 100644 (file)
@@ -13,6 +13,8 @@ use Html;
  * Renders one or more SearchResultSets into a sidebar grouped by
  * interwiki prefix. Includes a per-wiki header indicating where
  * the results are from.
+ *
+ * @deprecated since 1.31. Use InterwikiSearchResultSetWidget
  */
 class SimpleSearchResultSetWidget implements SearchResultSetWidget {
        /** @var SpecialSearch */
@@ -32,6 +34,7 @@ class SimpleSearchResultSetWidget implements SearchResultSetWidget {
                LinkRenderer $linkRenderer,
                InterwikiLookup $iwLookup
        ) {
+               wfDeprecated( __METHOD__, '1.31' );
                $this->specialSearch = $specialSearch;
                $this->resultWidget = $resultWidget;
                $this->linkRenderer = $linkRenderer;
index fa07563..552cbaf 100644 (file)
@@ -9,6 +9,8 @@ use SpecialSearch;
 
 /**
  * Renders a simple one-line result
+ *
+ * @deprecated since 1.31. Use other result widgets.
  */
 class SimpleSearchResultWidget implements SearchResultWidget {
        /** @var SpecialSearch */
@@ -17,6 +19,7 @@ class SimpleSearchResultWidget implements SearchResultWidget {
        protected $linkRenderer;
 
        public function __construct( SpecialSearch $specialSearch, LinkRenderer $linkRenderer ) {
+               wfDeprecated( __METHOD__, '1.31' );
                $this->specialSearch = $specialSearch;
                $this->linkRenderer = $linkRenderer;
        }
index 6139524..427a95e 100644 (file)
@@ -619,6 +619,16 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $this->assertEquals( __METHOD__, $rev->getContent()->getNativeData() );
        }
 
+       /**
+        * @covers Revision::newNullRevision
+        */
+       public function testNewNullRevision_badPage() {
+               $dbw = wfGetDB( DB_MASTER );
+               $rev = Revision::newNullRevision( $dbw, -1, 'a null revision', false );
+
+               $this->assertNull( $rev );
+       }
+
        /**
         * @covers Revision::insertOn
         */
index 7ce43ed..73d69a5 100644 (file)
@@ -1,7 +1,11 @@
 <?php
 
 use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\MutableRevisionRecord;
+use MediaWiki\Storage\RevisionAccessException;
+use MediaWiki\Storage\RevisionRecord;
 use MediaWiki\Storage\RevisionStore;
+use MediaWiki\Storage\SlotRecord;
 use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
@@ -1589,4 +1593,102 @@ class RevisionTest extends MediaWikiTestCase {
                );
        }
 
+       /**
+        * @covers Revision::getSize
+        */
+       public function testGetSize() {
+               $title = $this->getMockTitle();
+
+               $rec = new MutableRevisionRecord( $title );
+               $rev = new Revision( $rec, 0, $title );
+
+               $this->assertSame( 0, $rev->getSize(), 'Size of no slots is 0' );
+
+               $rec->setSize( 13 );
+               $this->assertSame( 13, $rev->getSize() );
+       }
+
+       /**
+        * @covers Revision::getSize
+        */
+       public function testGetSize_failure() {
+               $title = $this->getMockTitle();
+
+               $rec = $this->getMockBuilder( RevisionRecord::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $rec->method( 'getSize' )
+                       ->willThrowException( new RevisionAccessException( 'Oops!' ) );
+
+               $rev = new Revision( $rec, 0, $title );
+               $this->assertNull( $rev->getSize() );
+       }
+
+       /**
+        * @covers Revision::getSha1
+        */
+       public function testGetSha1() {
+               $title = $this->getMockTitle();
+
+               $rec = new MutableRevisionRecord( $title );
+               $rev = new Revision( $rec, 0, $title );
+
+               $emptyHash = SlotRecord::base36Sha1( '' );
+               $this->assertSame( $emptyHash, $rev->getSha1(), 'Sha1 of no slots is hash of empty string' );
+
+               $rec->setSha1( 'deadbeef' );
+               $this->assertSame( 'deadbeef', $rev->getSha1() );
+       }
+
+       /**
+        * @covers Revision::getSha1
+        */
+       public function testGetSha1_failure() {
+               $title = $this->getMockTitle();
+
+               $rec = $this->getMockBuilder( RevisionRecord::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $rec->method( 'getSha1' )
+                       ->willThrowException( new RevisionAccessException( 'Oops!' ) );
+
+               $rev = new Revision( $rec, 0, $title );
+               $this->assertNull( $rev->getSha1() );
+       }
+
+       /**
+        * @covers Revision::getContent
+        */
+       public function testGetContent() {
+               $title = $this->getMockTitle();
+
+               $rec = new MutableRevisionRecord( $title );
+               $rev = new Revision( $rec, 0, $title );
+
+               $this->assertNull( $rev->getContent(), 'Content of no slots is null' );
+
+               $content = new TextContent( 'Hello Kittens!' );
+               $rec->setContent( 'main', $content );
+               $this->assertSame( $content, $rev->getContent() );
+       }
+
+       /**
+        * @covers Revision::getContent
+        */
+       public function testGetContent_failure() {
+               $title = $this->getMockTitle();
+
+               $rec = $this->getMockBuilder( RevisionRecord::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $rec->method( 'getContent' )
+                       ->willThrowException( new RevisionAccessException( 'Oops!' ) );
+
+               $rev = new Revision( $rec, 0, $title );
+               $this->assertNull( $rev->getContent() );
+       }
+
 }