From bfa8662b7338cc916c38bcce0c68a3c08c55143c Mon Sep 17 00:00:00 2001 From: addshore Date: Mon, 14 Mar 2016 16:54:28 +0000 Subject: [PATCH] Add WatchedItemStore::countWatchedItems 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 | 23 +++++++++++++++ includes/specials/SpecialWatchlist.php | 17 ++++------- .../WatchedItemStoreIntegrationTest.php | 3 ++ .../includes/WatchedItemStoreUnitTest.php | 29 +++++++++++++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php index ff3ae2162e..b3a06e2737 100644 --- a/includes/WatchedItemStore.php +++ b/includes/WatchedItemStore.php @@ -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 * diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 7af1a54f0a..2dda093b13 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -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 ); } } diff --git a/tests/phpunit/includes/WatchedItemStoreIntegrationTest.php b/tests/phpunit/includes/WatchedItemStoreIntegrationTest.php index a34f8ee43b..91dd1aae24 100644 --- a/tests/phpunit/includes/WatchedItemStoreIntegrationTest.php +++ b/tests/phpunit/includes/WatchedItemStoreIntegrationTest.php @@ -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, diff --git a/tests/phpunit/includes/WatchedItemStoreUnitTest.php b/tests/phpunit/includes/WatchedItemStoreUnitTest.php index e483580352..983a5fe4dd 100644 --- a/tests/phpunit/includes/WatchedItemStoreUnitTest.php +++ b/tests/phpunit/includes/WatchedItemStoreUnitTest.php @@ -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' ); -- 2.20.1