Merge "Add SPARQL client to core"
[lhc/web/wiklou.git] / tests / phpunit / includes / Storage / RevisionStoreTest.php
index c9e9978..8e8de6e 100644 (file)
@@ -4,6 +4,7 @@ namespace MediaWiki\Tests\Storage;
 
 use HashBagOStuff;
 use Language;
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Storage\RevisionAccessException;
 use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SqlBlobStore;
@@ -30,7 +31,8 @@ class RevisionStoreTest extends MediaWikiTestCase {
                return new RevisionStore(
                        $loadBalancer ? $loadBalancer : $this->getMockLoadBalancer(),
                        $blobStore ? $blobStore : $this->getMockSqlBlobStore(),
-                       $WANObjectCache ? $WANObjectCache : $this->getHashWANObjectCache()
+                       $WANObjectCache ? $WANObjectCache : $this->getHashWANObjectCache(),
+                       MediaWikiServices::getInstance()->getCommentStore()
                );
        }
 
@@ -224,9 +226,10 @@ class RevisionStoreTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Storage\RevisionStore::getQueryInfo
         */
        public function testGetQueryInfo( $contentHandlerUseDb, $options, $expected ) {
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->overrideMwServices();
                $store = $this->getRevisionStore();
                $store->setContentHandlerUseDB( $contentHandlerUseDb );
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
                $this->assertEquals( $expected, $store->getQueryInfo( $options ) );
        }
 
@@ -254,9 +257,10 @@ class RevisionStoreTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Storage\RevisionStore::getArchiveQueryInfo
         */
        public function testGetArchiveQueryInfo_contentHandlerDb() {
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->overrideMwServices();
                $store = $this->getRevisionStore();
                $store->setContentHandlerUseDB( true );
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
                $this->assertEquals(
                        [
                                'tables' => [
@@ -282,9 +286,10 @@ class RevisionStoreTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Storage\RevisionStore::getArchiveQueryInfo
         */
        public function testGetArchiveQueryInfo_noContentHandlerDb() {
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->overrideMwServices();
                $store = $this->getRevisionStore();
                $store->setContentHandlerUseDB( false );
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
                $this->assertEquals(
                        [
                                'tables' => [
@@ -335,6 +340,62 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->assertSame( 'Food', $title->getDBkey() );
        }
 
+       public function testGetTitle_successFromPageIdOnFallback() {
+               $mockLoadBalancer = $this->getMockLoadBalancer();
+               // Title calls wfGetDB() so we have to set the main service
+               $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
+
+               $db = $this->getMockDatabase();
+               // Title calls wfGetDB() which uses a regular Connection
+               // Assert that the first call uses a REPLICA and the second falls back to master
+               $mockLoadBalancer->expects( $this->exactly( 2 ) )
+                       ->method( 'getConnection' )
+                       ->willReturn( $db );
+               // RevisionStore getTitle uses a ConnectionRef
+               $mockLoadBalancer->expects( $this->atLeastOnce() )
+                       ->method( 'getConnectionRef' )
+                       ->willReturn( $db );
+
+               // First call to Title::newFromID, faking no result (db lag?)
+               $db->expects( $this->at( 0 ) )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'page',
+                               $this->anything(),
+                               [ 'page_id' => 1 ]
+                       )
+                       ->willReturn( false );
+
+               // First select using rev_id, faking no result (db lag?)
+               $db->expects( $this->at( 1 ) )
+                       ->method( 'selectRow' )
+                       ->with(
+                               [ 'revision', 'page' ],
+                               $this->anything(),
+                               [ 'rev_id' => 2 ]
+                       )
+                       ->willReturn( false );
+
+               // Second call to Title::newFromID, no result
+               $db->expects( $this->at( 2 ) )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'page',
+                               $this->anything(),
+                               [ 'page_id' => 1 ]
+                       )
+                       ->willReturn( (object)[
+                               'page_namespace' => '2',
+                               'page_title' => 'Foodey',
+                       ] );
+
+               $store = $this->getRevisionStore( $mockLoadBalancer );
+               $title = $store->getTitle( 1, 2, RevisionStore::READ_NORMAL );
+
+               $this->assertSame( 2, $title->getNamespace() );
+               $this->assertSame( 'Foodey', $title->getDBkey() );
+       }
+
        public function testGetTitle_successFromRevId() {
                $mockLoadBalancer = $this->getMockLoadBalancer();
                // Title calls wfGetDB() so we have to set the main service
@@ -380,17 +441,15 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->assertSame( 'Food2', $title->getDBkey() );
        }
 
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getTitle
-        */
-       public function testGetTitle_throwsExceptionAfterFallbacks() {
+       public function testGetTitle_successFromRevIdOnFallback() {
                $mockLoadBalancer = $this->getMockLoadBalancer();
                // Title calls wfGetDB() so we have to set the main service
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
                // Title calls wfGetDB() which uses a regular Connection
-               $mockLoadBalancer->expects( $this->atLeastOnce() )
+               // Assert that the first call uses a REPLICA and the second falls back to master
+               $mockLoadBalancer->expects( $this->exactly( 2 ) )
                        ->method( 'getConnection' )
                        ->willReturn( $db );
                // RevisionStore getTitle uses a ConnectionRef
@@ -418,6 +477,88 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        )
                        ->willReturn( false );
 
+               // Second call to Title::newFromID, no result
+               $db->expects( $this->at( 2 ) )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'page',
+                               $this->anything(),
+                               [ 'page_id' => 1 ]
+                       )
+                       ->willReturn( false );
+
+               // Second select using rev_id, result
+               $db->expects( $this->at( 3 ) )
+                       ->method( 'selectRow' )
+                       ->with(
+                               [ 'revision', 'page' ],
+                               $this->anything(),
+                               [ 'rev_id' => 2 ]
+                       )
+                       ->willReturn( (object)[
+                               'page_namespace' => '2',
+                               'page_title' => 'Foodey',
+                       ] );
+
+               $store = $this->getRevisionStore( $mockLoadBalancer );
+               $title = $store->getTitle( 1, 2, RevisionStore::READ_NORMAL );
+
+               $this->assertSame( 2, $title->getNamespace() );
+               $this->assertSame( 'Foodey', $title->getDBkey() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getTitle
+        */
+       public function testGetTitle_correctFallbackAndthrowsExceptionAfterFallbacks() {
+               $mockLoadBalancer = $this->getMockLoadBalancer();
+               // Title calls wfGetDB() so we have to set the main service
+               $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
+
+               $db = $this->getMockDatabase();
+               // Title calls wfGetDB() which uses a regular Connection
+               // Assert that the first call uses a REPLICA and the second falls back to master
+
+               // RevisionStore getTitle uses getConnectionRef
+               // Title::newFromID uses getConnection
+               foreach ( [ 'getConnection', 'getConnectionRef' ] as $method ) {
+                       $mockLoadBalancer->expects( $this->exactly( 2 ) )
+                               ->method( $method )
+                               ->willReturnCallback( function ( $masterOrReplica ) use ( $db ) {
+                                       static $callCounter = 0;
+                                       $callCounter++;
+                                       // The first call should be to a REPLICA, and the second a MASTER.
+                                       if ( $callCounter === 1 ) {
+                                               $this->assertSame( DB_REPLICA, $masterOrReplica );
+                                       } elseif ( $callCounter === 2 ) {
+                                               $this->assertSame( DB_MASTER, $masterOrReplica );
+                                       }
+                                       return $db;
+                               } );
+               }
+               // First and third call to Title::newFromID, faking no result
+               foreach ( [ 0, 2 ] as $counter ) {
+                       $db->expects( $this->at( $counter ) )
+                               ->method( 'selectRow' )
+                               ->with(
+                                       'page',
+                                       $this->anything(),
+                                       [ 'page_id' => 1 ]
+                               )
+                               ->willReturn( false );
+               }
+
+               foreach ( [ 1, 3 ] as $counter ) {
+                       $db->expects( $this->at( $counter ) )
+                               ->method( 'selectRow' )
+                               ->with(
+                                       [ 'revision', 'page' ],
+                                       $this->anything(),
+                                       [ 'rev_id' => 2 ]
+                               )
+                               ->willReturn( false );
+               }
+
                $store = $this->getRevisionStore( $mockLoadBalancer );
 
                $this->setExpectedException( RevisionAccessException::class );
@@ -458,7 +599,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $blobStore = new SqlBlobStore( wfGetLB(), $cache );
                $blobStore->setLegacyEncoding( $encoding, Language::factory( $locale ) );
 
-               $store = new RevisionStore( wfGetLB(), $blobStore, $cache );
+               $store = $this->getRevisionStore( wfGetLB(), $blobStore, $cache );
 
                $record = $store->newRevisionFromRow(
                        $this->makeRow( $row ),
@@ -484,7 +625,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $blobStore = new SqlBlobStore( wfGetLB(), $cache );
                $blobStore->setLegacyEncoding( 'windows-1252', Language::factory( 'en' ) );
 
-               $store = new RevisionStore( wfGetLB(), $blobStore, $cache );
+               $store = $this->getRevisionStore( wfGetLB(), $blobStore, $cache );
 
                $record = $store->newRevisionFromRow(
                        $this->makeRow( $row ),