return $mockStore;
}
+ /**
+ * @return PHPUnit_Framework_MockObject_MockObject|ActorMigration
+ */
+ private function getMockActorMigration() {
+ $mockStore = $this->getMockBuilder( ActorMigration::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mockStore->expects( $this->any() )
+ ->method( 'getJoin' )
+ ->willReturn( [
+ 'tables' => [ 'actormigration' => 'table' ],
+ 'fields' => [
+ 'rc_user' => 'actormigration_user',
+ 'rc_user_text' => 'actormigration_user_text',
+ 'rc_actor' => 'actormigration_actor',
+ ],
+ 'joins' => [ 'actormigration' => 'join' ],
+ ] );
+ $mockStore->expects( $this->any() )
+ ->method( 'getWhere' )
+ ->willReturn( [
+ 'tables' => [ 'actormigration' => 'table' ],
+ 'conds' => 'actormigration_conds',
+ 'joins' => [ 'actormigration' => 'join' ],
+ ] );
+ $mockStore->expects( $this->any() )
+ ->method( 'isAnon' )
+ ->willReturn( 'actormigration is anon' );
+ $mockStore->expects( $this->any() )
+ ->method( 'isNotAnon' )
+ ->willReturn( 'actormigration is not anon' );
+ return $mockStore;
+ }
+
/**
* @param PHPUnit_Framework_MockObject_MockObject|Database $mockDb
* @return WatchedItemQueryService
private function newService( $mockDb ) {
return new WatchedItemQueryService(
$this->getMockLoadBalancer( $mockDb ),
- $this->getMockCommentStore()
+ $this->getMockCommentStore(),
+ $this->getMockActorMigration(),
+ $this->getMockWatchedItemStore()
);
}
)
->will( $this->returnCallback( function ( $a, $conj ) {
$sqlConj = $conj === LIST_AND ? ' AND ' : ' OR ';
- return join( $sqlConj, array_map( function ( $s ) {
- return '(' . $s . ')';
- }, $a
- ) );
+ $conds = [];
+ foreach ( $a as $k => $v ) {
+ if ( is_int( $k ) ) {
+ $conds[] = "($v)";
+ } elseif ( is_array( $v ) ) {
+ $conds[] = "($k IN ('" . implode( "','", $v ) . "'))";
+ } else {
+ $conds[] = "($k = '$v')";
+ }
+ }
+ return implode( $sqlConj, $conds );
} ) );
$mock->expects( $this->any() )
return $mock;
}
+ /**
+ * @param PHPUnit_Framework_MockObject_MockObject|Database $mockDb
+ * @return PHPUnit_Framework_MockObject_MockObject|WatchedItemStore
+ */
+ private function getMockWatchedItemStore() {
+ $mock = $this->getMockBuilder( WatchedItemStore::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mock->expects( $this->any() )
+ ->method( 'getLatestNotificationTimestamp' )
+ ->will( $this->returnCallback( function ( $timestamp ) {
+ return $timestamp;
+ } ) );
+ return $mock;
+ }
+
/**
* @param int $id
* @return PHPUnit_Framework_MockObject_MockObject|User
],
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
],
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
[
[ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER ] ],
null,
- [],
- [ 'rc_user_text' ],
- [],
+ [ 'actormigration' => 'table' ],
+ [ 'rc_user_text' => 'actormigration_user_text' ],
[],
[],
+ [ 'actormigration' => 'join' ],
],
[
[ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER_ID ] ],
null,
- [],
- [ 'rc_user' ],
- [],
+ [ 'actormigration' => 'table' ],
+ [ 'rc_user' => 'actormigration_user' ],
[],
[],
+ [ 'actormigration' => 'join' ],
],
[
[ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
[
[ 'filters' => [ WatchedItemQueryService::FILTER_ANON ] ],
null,
+ [ 'actormigration' => 'table' ],
[],
+ [ 'actormigration is anon' ],
[],
- [ 'rc_user = 0' ],
- [],
- [],
+ [ 'actormigration' => 'join' ],
],
[
[ 'filters' => [ WatchedItemQueryService::FILTER_NOT_ANON ] ],
null,
+ [ 'actormigration' => 'table' ],
[],
+ [ 'actormigration is not anon' ],
[],
- [ 'rc_user != 0' ],
- [],
- [],
+ [ 'actormigration' => 'join' ],
],
[
[ 'filters' => [ WatchedItemQueryService::FILTER_PATROLLED ] ],
null,
[],
[],
- [ 'rc_patrolled = 0' ],
+ [ 'rc_patrolled' => 0 ],
[],
[],
],
[
[ 'onlyByUser' => 'SomeOtherUser' ],
null,
+ [ 'actormigration' => 'table' ],
[],
+ [ 'actormigration_conds' ],
[],
- [ 'rc_user_text' => 'SomeOtherUser' ],
- [],
- [],
+ [ 'actormigration' => 'join' ],
],
[
[ 'notByUser' => 'SomeOtherUser' ],
null,
+ [ 'actormigration' => 'table' ],
[],
+ [ 'NOT(actormigration_conds)' ],
[],
- [ "rc_user_text != 'SomeOtherUser'" ],
- [],
- [],
+ [ 'actormigration' => 'join' ],
],
[
[ 'dir' => WatchedItemQueryService::DIR_OLDER ],
$expectedJoinConds = array_merge(
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
[
[],
'deletedhistory',
+ [],
[
'(rc_type != ' . RC_LOG . ') OR ((rc_deleted & ' . LogPage::DELETED_ACTION . ') != ' .
LogPage::DELETED_ACTION . ')'
],
+ [],
],
[
[],
'suppressrevision',
+ [],
[
'(rc_type != ' . RC_LOG . ') OR (' .
'(rc_deleted & ' . ( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ') != ' .
( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ')'
],
+ [],
],
[
[],
'viewsuppressed',
+ [],
[
'(rc_type != ' . RC_LOG . ') OR (' .
'(rc_deleted & ' . ( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ') != ' .
( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ')'
],
+ [],
],
[
[ 'onlyByUser' => 'SomeOtherUser' ],
'deletedhistory',
+ [ 'actormigration' => 'table' ],
[
- 'rc_user_text' => 'SomeOtherUser',
+ 'actormigration_conds',
'(rc_deleted & ' . Revision::DELETED_USER . ') != ' . Revision::DELETED_USER,
'(rc_type != ' . RC_LOG . ') OR ((rc_deleted & ' . LogPage::DELETED_ACTION . ') != ' .
LogPage::DELETED_ACTION . ')'
],
+ [ 'actormigration' => 'join' ],
],
[
[ 'onlyByUser' => 'SomeOtherUser' ],
'suppressrevision',
+ [ 'actormigration' => 'table' ],
[
- 'rc_user_text' => 'SomeOtherUser',
+ 'actormigration_conds',
'(rc_deleted & ' . ( Revision::DELETED_USER | Revision::DELETED_RESTRICTED ) . ') != ' .
( Revision::DELETED_USER | Revision::DELETED_RESTRICTED ),
'(rc_type != ' . RC_LOG . ') OR (' .
'(rc_deleted & ' . ( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ') != ' .
( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ')'
],
+ [ 'actormigration' => 'join' ],
],
[
[ 'onlyByUser' => 'SomeOtherUser' ],
'viewsuppressed',
+ [ 'actormigration' => 'table' ],
[
- 'rc_user_text' => 'SomeOtherUser',
+ 'actormigration_conds',
'(rc_deleted & ' . ( Revision::DELETED_USER | Revision::DELETED_RESTRICTED ) . ') != ' .
( Revision::DELETED_USER | Revision::DELETED_RESTRICTED ),
'(rc_type != ' . RC_LOG . ') OR (' .
'(rc_deleted & ' . ( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ') != ' .
( LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED ) . ')'
],
+ [ 'actormigration' => 'join' ],
],
];
}
public function testGetWatchedItemsWithRecentChangeInfo_userPermissionRelatedExtraChecks(
array $options,
$notAllowedAction,
- array $expectedExtraConds
+ array $expectedExtraTables,
+ array $expectedExtraConds,
+ array $expectedExtraJoins
) {
$commonConds = [ 'wl_user' => 1, '(rc_this_oldid=page_latest) OR (rc_type=3)' ];
$conds = array_merge( $commonConds, $expectedExtraConds );
$mockDb->expects( $this->once() )
->method( 'select' )
->with(
- [ 'recentchanges', 'watchlist', 'page' ],
+ array_merge( [ 'recentchanges', 'watchlist', 'page' ], $expectedExtraTables ),
$this->isType( 'array' ),
$conds,
$this->isType( 'string' ),
$this->isType( 'array' ),
- $this->isType( 'array' )
+ array_merge( [
+ 'watchlist' => [ 'JOIN', [ 'wl_namespace=rc_namespace', 'wl_title=rc_title' ] ],
+ 'page' => [ 'LEFT JOIN', 'rc_cur_id=page_id' ],
+ ], $expectedExtraJoins )
)
->will( $this->returnValue( [] ) );
[],
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
[],
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
[],
[
'watchlist' => [
- 'INNER JOIN',
+ 'JOIN',
[
'wl_namespace=rc_namespace',
'wl_title=rc_title'
)
->will( $this->returnCallback( function ( $a, $conj ) {
$sqlConj = $conj === LIST_AND ? ' AND ' : ' OR ';
- return join( $sqlConj, array_map( function ( $s ) {
+ return implode( $sqlConj, array_map( function ( $s ) {
return '(' . $s . ')';
}, $a
) );