mediawiki-extensions-Echo/tests/phpunit/NotifUserTest.php
Roan Kattouw 0807c3c5ad NotifUser: Refactor getNotificationCount() and friends, add caching for global counts
Previously, getNotificationCount() only looked at local notifications,
and foreign notifications were added in separately by getMessageCount()
and getAlertCount(). This didn't make any sense and resulted in
counter-intuitive things like I4d49b543.

Instead, add a $global flag to getNotificationCount(). If $global=false,
the local count is returned as before, but if $global=true, the
global count (=local+foreign) is returned. If $global is omitted,
the user's cross-wiki notification preference determines which is returned.

Update getLastUnreadNotificationCount() in the same way, since it had
the same issues.

Also add caching for global counts and timestamps, using a global
memc key.

Bug: T133623
Change-Id: If78bfc710acd91a075771b565cc99f4c302a104d
2016-05-02 16:16:57 -07:00

204 lines
6.1 KiB
PHP

<?php
/**
* @group Echo
*/
class MWEchoNotifUserTest extends MediaWikiTestCase {
/**
* @var BagOStuff
*/
private $cache;
protected function setUp() {
parent::setUp();
$this->cache = ObjectCache::getMainStashInstance();
}
public function testNewFromUser() {
$exception = false;
try {
MWEchoNotifUser::newFromUser( User::newFromId( 0 ) );
} catch ( Exception $e ) {
$exception = true;
$this->assertEquals( "User must be logged in to view notification!",
$e->getMessage() );
}
$this->assertTrue( $exception, "Got exception" );
$notifUser = MWEchoNotifUser::newFromUser( User::newFromId( 2 ) );
$this->assertInstanceOf( 'MWEchoNotifUser', $notifUser );
}
public function testFlagCacheWithNewTalkNotification() {
$notifUser = MWEchoNotifUser::newFromUser( User::newFromId( 2 ) );
$notifUser->flagCacheWithNewTalkNotification();
$this->assertEquals( '1', $this->cache->get( $notifUser->getTalkNotificationCacheKey() ) );
}
public function testFlagCacheWithNoTalkNotification() {
$notifUser = MWEchoNotifUser::newFromUser( User::newFromId( 2 ) );
$notifUser->flagCacheWithNoTalkNotification();
$this->assertEquals( '0', $this->cache->get( $notifUser->getTalkNotificationCacheKey() ) );
}
public function testNotifCountHasReachedMax() {
$notifUser = MWEchoNotifUser::newFromUser( User::newFromId( 2 ) );
if ( $notifUser->getLocalNotificationCount() > MWEchoNotifUser::MAX_BADGE_COUNT ) {
$this->assertTrue( $notifUser->notifCountHasReachedMax() );
} else {
$this->assertFalse( $notifUser->notifCountHasReachedMax() );
}
}
public function testClearTalkNotification() {
$notifUser = MWEchoNotifUser::newFromUser( User::newFromId( 2 ) );
$notifUser->flagCacheWithNewTalkNotification();
$hasMax = $notifUser->notifCountHasReachedMax();
$notifUser->clearTalkNotification();
if ( $hasMax ) {
$this->assertEquals( '1', $this->cache->get( $notifUser->getTalkNotificationCacheKey() ) );
} else {
$this->assertEquals( '0', $this->cache->get( $notifUser->getTalkNotificationCacheKey() ) );
}
}
public function testGetEmailFormat() {
$user = User::newFromId( 2 );
$notifUser = MWEchoNotifUser::newFromUser( $user );
$this->setMwGlobals( 'wgAllowHTMLEmail', true );
$this->assertEquals( $notifUser->getEmailFormat(), $user->getOption( 'echo-email-format' ) );
$this->setMwGlobals( 'wgAllowHTMLEmail', false );
$this->assertEquals( $notifUser->getEmailFormat(), EchoHooks::EMAIL_FORMAT_PLAIN_TEXT );
}
public function testMarkRead() {
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => true ) ),
$this->mockEchoNotificationMapper(),
$this->mockEchoTargetPageMapper()
);
$this->assertFalse( $notifUser->markRead( array() ) );
$this->assertTrue( $notifUser->markRead( array( 1 ) ) );
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => false ) ),
$this->mockEchoNotificationMapper(),
$this->mockEchoTargetPageMapper()
);
$this->assertFalse( $notifUser->markRead( array() ) );
$this->assertFalse( $notifUser->markRead( array( 1 ) ) );
}
public function testMarkAllRead() {
// Successful mark as read & non empty fetch
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => true ) ),
$this->mockEchoNotificationMapper( array( $this->mockEchoNotification() ) ),
$this->mockEchoTargetPageMapper()
);
$this->assertTrue( $notifUser->markAllRead() );
// Unsuccessful mark as read & non empty fetch
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => false ) ),
$this->mockEchoNotificationMapper( array( $this->mockEchoNotification() ) ),
$this->mockEchoTargetPageMapper()
);
$this->assertFalse( $notifUser->markAllRead() );
// Successful mark as read & empty fetch
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => true ) ),
$this->mockEchoNotificationMapper(),
$this->mockEchoTargetPageMapper()
);
$this->assertFalse( $notifUser->markAllRead() );
// Unsuccessful mark as read & empty fetch
$notifUser = new MWEchoNotifUser(
User::newFromId( 2 ),
$this->cache,
$this->mockEchoUserNotificationGateway( array( 'markRead' => false ) ),
$this->mockEchoNotificationMapper(),
$this->mockEchoTargetPageMapper()
);
$this->assertFalse( $notifUser->markAllRead() );
}
public function mockEchoUserNotificationGateway( array $dbResult = array() ) {
$dbResult += array(
'markRead' => true
);
$gateway = $this->getMockBuilder( 'EchoUserNotificationGateway' )
->disableOriginalConstructor()
->getMock();
$gateway->expects( $this->any() )
->method( 'markRead' )
->will( $this->returnValue( $dbResult['markRead'] ) );
return $gateway;
}
public function mockEchoNotificationMapper( array $result = array() ) {
$mapper = $this->getMockBuilder( 'EchoNotificationMapper' )
->disableOriginalConstructor()
->getMock();
$mapper->expects( $this->any() )
->method( 'fetchUnreadByUser' )
->will( $this->returnValue( $result ) );
return $mapper;
}
public function mockEchoTargetPageMapper( array $result = array() ) {
$mapper = $this->getMockBuilder( 'EchoTargetPageMapper' )
->disableOriginalConstructor()
->getMock();
$mapper->expects( $this->any() )
->method( 'deleteByUserEvents' )
->will( $this->returnValue( $result ) );
return $mapper;
}
protected function mockEchoNotification() {
$notification = $this->getMockBuilder( 'EchoNotification' )
->disableOriginalConstructor()
->getMock();
$notification->expects( $this->any() )
->method( 'getEvent' )
->will( $this->returnValue( $this->mockEchoEvent() ) );
return $notification;
}
protected function mockEchoEvent() {
$event = $this->getMockBuilder( 'EchoEvent' )
->disableOriginalConstructor()
->getMock();
$event->expects( $this->any() )
->method( 'getId' )
->will( $this->returnValue( 1 ) );
return $event;
}
}