Move countVisitingWatchers to WatchedItemStore
authoraddshore <addshorewiki@gmail.com>
Fri, 5 Feb 2016 12:04:58 +0000 (13:04 +0100)
committerAddshore <addshorewiki@gmail.com>
Mon, 14 Mar 2016 15:56:43 +0000 (15:56 +0000)
Also adds tests

Bug: T129479
Change-Id: I2868c31fc09121de381d822e8f49194e3022bb42

includes/WatchedItemStore.php
includes/actions/InfoAction.php
tests/phpunit/includes/WatchedItemStoreIntegrationTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php

index 86e4925..c59beec 100644 (file)
@@ -205,6 +205,35 @@ class WatchedItemStore {
                return $return;
        }
 
+       /**
+        * Number of page watchers who also visited a "recent" edit
+        *
+        * @param LinkTarget $target
+        * @param mixed $threshold timestamp accepted by wfTimestamp
+        *
+        * @return int
+        * @throws DBUnexpectedError
+        * @throws MWException
+        */
+       public function countVisitingWatchers( LinkTarget $target, $threshold ) {
+               $dbr = $this->loadBalancer->getConnection( DB_SLAVE, [ 'watchlist' ] );
+               $visitingWatchers = (int)$dbr->selectField(
+                       'watchlist',
+                       'COUNT(*)',
+                       [
+                               'wl_namespace' => $target->getNamespace(),
+                               'wl_title' => $target->getDBkey(),
+                               'wl_notificationtimestamp >= ' .
+                               $dbr->addQuotes( $dbr->timestamp( $threshold ) ) .
+                               ' OR wl_notificationtimestamp IS NULL'
+                       ],
+                       __METHOD__
+               );
+               $this->loadBalancer->reuseConnection( $dbr );
+
+               return $visitingWatchers;
+       }
+
        /**
         * @param LinkTarget[] $targets
         * @param array $options Allowed keys:
index 60829b1..4596e41 100644 (file)
@@ -677,28 +677,17 @@ class InfoAction extends FormlessAction {
 
                                $setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
 
+                               $watchedItemStore = WatchedItemStore::getDefaultInstance();
+
                                $result = [];
-                               $result['watchers'] = WatchedItemStore::getDefaultInstance()->countWatchers( $title );
+                               $result['watchers'] = $watchedItemStore->countWatchers( $title );
 
                                if ( $config->get( 'ShowUpdatedMarker' ) ) {
-                                       // Threshold: last visited about 26 weeks before latest edit
                                        $updated = wfTimestamp( TS_UNIX, $page->getTimestamp() );
-                                       $age = $config->get( 'WatchersMaxAge' );
-                                       $threshold = $dbrWatchlist->timestamp( $updated - $age );
-                                       // Number of page watchers who also visited a "recent" edit
-                                       $visitingWatchers = (int)$dbrWatchlist->selectField(
-                                               'watchlist',
-                                               'COUNT(*)',
-                                               [
-                                                       'wl_namespace' => $title->getNamespace(),
-                                                       'wl_title' => $title->getDBkey(),
-                                                       'wl_notificationtimestamp >= ' .
-                                                               $dbrWatchlist->addQuotes( $threshold ) .
-                                                               ' OR wl_notificationtimestamp IS NULL'
-                                               ],
-                                               $fname
+                                       $result['visitingWatchers'] = $watchedItemStore->countVisitingWatchers(
+                                               $title,
+                                               $updated - $config->get( 'WatchersMaxAge' )
                                        );
-                                       $result['visitingWatchers'] = $visitingWatchers;
                                }
 
                                // Total number of edits
index 3e5f261..2aa9027 100644 (file)
@@ -70,15 +70,24 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                $store = WatchedItemStore::getDefaultInstance();
                $store->addWatch( $user, $title );
                $this->assertNull( $store->loadWatchedItem( $user, $title )->getNotificationTimestamp() );
+               $initialVisitingWatchers = $store->countVisitingWatchers( $title, '20150202020202' );
 
                $store->updateNotificationTimestamp( $otherUser, $title, '20150202010101' );
                $this->assertEquals(
                        '20150202010101',
                        $store->loadWatchedItem( $user, $title )->getNotificationTimestamp()
                );
+               $this->assertEquals(
+                       $initialVisitingWatchers - 1,
+                       $store->countVisitingWatchers( $title, '20150202020202' )
+               );
 
                $this->assertTrue( $store->resetNotificationTimestamp( $user, $title ) );
                $this->assertNull( $store->getWatchedItem( $user, $title )->getNotificationTimestamp() );
+               $this->assertEquals(
+                       $initialVisitingWatchers,
+                       $store->countVisitingWatchers( $title, '20150202020202' )
+               );
        }
 
        public function testDuplicateAllAssociatedEntries() {
index c8621fc..988ffed 100644 (file)
@@ -235,6 +235,47 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                );
        }
 
+       public function testCountVisitingWatchers() {
+               $titleValue = new TitleValue( 0, 'SomeDbKey' );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->exactly( 1 ) )
+                       ->method( 'selectField' )
+                       ->with(
+                               'watchlist',
+                               'COUNT(*)',
+                               [
+                                       'wl_namespace' => $titleValue->getNamespace(),
+                                       'wl_title' => $titleValue->getDBkey(),
+                                       'wl_notificationtimestamp >= \'TS111TS\' OR wl_notificationtimestamp IS NULL',
+                               ],
+                               $this->isType( 'string' )
+                       )
+                       ->will( $this->returnValue( 7 ) );
+               $mockDb->expects( $this->exactly( 1 ) )
+                       ->method( 'addQuotes' )
+                       ->will( $this->returnCallback( function( $value ) {
+                               return "'$value'";
+                       } ) );
+               $mockDb->expects( $this->exactly( 1 ) )
+                       ->method( 'timestamp' )
+                       ->will( $this->returnCallback( function( $value ) {
+                               return 'TS' . $value . 'TS';
+                       } ) );
+
+               $mockCache = $this->getMockCache();
+               $mockCache->expects( $this->never() )->method( 'set' );
+               $mockCache->expects( $this->never() )->method( 'get' );
+               $mockCache->expects( $this->never() )->method( 'delete' );
+
+               $store = new WatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $this->assertEquals( 7, $store->countVisitingWatchers( $titleValue, '111' ) );
+       }
+
        public function testDuplicateEntry_nothingToDuplicate() {
                $mockDb = $this->getMockDb();
                $mockDb->expects( $this->once() )