Add WatchedItemStore::countWatchedItems
authoraddshore <addshorewiki@gmail.com>
Mon, 14 Mar 2016 16:54:28 +0000 (16:54 +0000)
committeraddshore <addshorewiki@gmail.com>
Tue, 15 Mar 2016 15:58:51 +0000 (15:58 +0000)
This method counts the number of individual items
that a user is watching.
A subject and corresponding talk page would mean a
count of 2

Unit and integration tests are also added here

Bug: T129481
Change-Id: I4b55318dc1d1c5abab1c5da16cebf1a43ddf9248

includes/WatchedItemStore.php
includes/specials/SpecialWatchlist.php
tests/phpunit/includes/WatchedItemStoreIntegrationTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php

index ff3ae21..b3a06e2 100644 (file)
@@ -225,6 +225,29 @@ class WatchedItemStore {
                $this->loadBalancer->reuseConnection( $connection );
        }
 
+       /**
+        * Count the number of individual items that are watched by the user.
+        * If a subject and corresponding talk page are watched this will return 2.
+        *
+        * @param User $user
+        *
+        * @return int
+        */
+       public function countWatchedItems( User $user ) {
+               $dbr = $this->getConnection( DB_SLAVE );
+               $return = (int)$dbr->selectField(
+                       'watchlist',
+                       'COUNT(*)',
+                       [
+                               'wl_user' => $user->getId()
+                       ],
+                       __METHOD__
+               );
+               $this->reuseConnection( $dbr );
+
+               return $return;
+       }
+
        /**
         * @param LinkTarget $target
         *
index 7af1a54..2dda093 100644 (file)
@@ -568,8 +568,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $form = "";
                $user = $this->getUser();
 
-               $dbr = $this->getDB();
-               $numItems = $this->countItems( $dbr );
+               $numItems = $this->countItems();
                $showUpdatedMarker = $this->getConfig()->get( 'ShowUpdatedMarker' );
 
                // Show watchlist header
@@ -629,18 +628,14 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        /**
-        * Count the number of items on a user's watchlist
+        * Count the number of paired items on a user's watchlist.
+        * The assumption made here is that when a subject page is watched a talk page is also watched.
+        * Hence the number of individual items is halved.
         *
-        * @param IDatabase $dbr A database connection
         * @return int
         */
-       protected function countItems( $dbr ) {
-               # Fetch the raw count
-               $rows = $dbr->select( 'watchlist', [ 'count' => 'COUNT(*)' ],
-                       [ 'wl_user' => $this->getUser()->getId() ], __METHOD__ );
-               $row = $dbr->fetchObject( $rows );
-               $count = $row->count;
-
+       protected function countItems() {
+               $count = WatchedItemStore::getDefaultInstance()->countWatchedItems( $this->getUser() );
                return floor( $count / 2 );
        }
 }
index a34f8ee..91dd1aa 100644 (file)
@@ -26,6 +26,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                // Cleanup after previous tests
                $store->removeWatch( $user, $title );
                $initialWatchers = $store->countWatchers( $title );
+               $initialUserWatchedItems = $store->countWatchedItems( $user );
 
                $this->assertFalse(
                        $store->isWatched( $user, $title ),
@@ -37,6 +38,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                        $store->isWatched( $user, $title ),
                        'Page should be watched'
                );
+               $this->assertEquals( $initialUserWatchedItems + 1, $store->countWatchedItems( $user ) );
                $this->assertEquals( $initialWatchers + 1, $store->countWatchers( $title ) );
                $this->assertEquals(
                        $initialWatchers + 1,
@@ -56,6 +58,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                        $store->isWatched( $user, $title ),
                        'Page should be unwatched'
                );
+               $this->assertEquals( $initialUserWatchedItems, $store->countWatchedItems( $user ) );
                $this->assertEquals( $initialWatchers, $store->countWatchers( $title ) );
                $this->assertEquals(
                        $initialWatchers,
index e483580..983a5fe 100644 (file)
@@ -92,6 +92,35 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                $this->assertSame( $instance, WatchedItemStore::getDefaultInstance() );
        }
 
+       public function testCountWatchedItems() {
+               $user = $this->getMockNonAnonUserWithId( 1 );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->exactly( 1 ) )
+                       ->method( 'selectField' )
+                       ->with(
+                               'watchlist',
+                               'COUNT(*)',
+                               [
+                                       'wl_user' => $user->getId(),
+                               ],
+                               $this->isType( 'string' )
+                       )
+                       ->will( $this->returnValue( 12 ) );
+
+               $mockCache = $this->getMockCache();
+               $mockCache->expects( $this->never() )->method( 'get' );
+               $mockCache->expects( $this->never() )->method( 'set' );
+               $mockCache->expects( $this->never() )->method( 'delete' );
+
+               $store = new WatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $this->assertEquals( 12, $store->countWatchedItems( $user ) );
+       }
+
        public function testCountWatchers() {
                $titleValue = new TitleValue( 0, 'SomeDbKey' );