WMDE-leszek has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/278859

Change subject: [WIP]Use WatchedItemStore::getWatchedItemsForUser in 
ApiQueryWatchlistRaw
......................................................................

[WIP]Use WatchedItemStore::getWatchedItemsForUser in ApiQueryWatchlistRaw

Adds number of options to WatchedItemStore::getWatchedItemsForUser.
Also adds some tests for ApiQueryWatchlistRaw.

TODO: more tests for ApiQueryWatchlistRaw?
TODO: use WIS::getWatchedItemsForUser in ApiQueryWatchlistRaw::run

Change-Id: I875a92074b52c00ac11db1fa05615abbf5262ab1
---
M includes/WatchedItemStore.php
M tests/phpunit/includes/WatchedItemStoreUnitTest.php
A tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php
3 files changed, 611 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/59/278859/2

diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php
index 67ff15f..defa9c3 100644
--- a/includes/WatchedItemStore.php
+++ b/includes/WatchedItemStore.php
@@ -400,8 +400,17 @@
         * @param User $user
         * @param array $options Allowed keys:
         *        'forWrite' => bool defaults to false
-        *        'namespaceId' => int optional namespace ID to filter by 
(default to all namespaces)
         *        'ordered' => bool optional ordering by namespace ID and title
+        *        'namespaceIds' => int[] optional namespace IDs to filter by 
(defaults to all namespaces)
+        *        'limit' => int maximum number of items to return
+        *        'filter' => string optional filter, allowed values:
+        *        - changedSinceLastVisit,
+        *        - changedBeforeLastVisit,
+        *        'orderDescending' => bool reverse ordering of items, defaults 
to false
+        *        'from' => LinkTarget requires 'ordered' key, only return 
items starting from
+        *        those related to the link target
+        *        'until' => LinkTarget requires 'ordered' key, only return 
items until
+        *        those related to the link target
         *
         * @return WatchedItem[]
         */
@@ -409,14 +418,16 @@
                if ( !array_key_exists( 'forWrite', $options ) ) {
                        $options['forWrite'] = false;
                }
-
-               $conds = [ 'wl_user' => $user->getId() ];
-
-               $dbOptions = [];
-               if ( array_key_exists( 'ordered', $options ) && 
$options['ordered'] ) {
-                       $dbOptions['ORDER BY'] = [ 'wl_namespace', 'wl_title' ];
+               if ( !array_key_exists( 'namespaceIds', $options ) || 
!is_array( $options['namespaceIds'] ) ) {
+                       $options['namespaceIds'] = [];
                }
+
                $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : 
DB_SLAVE );
+
+               $extraConds = $this->getWatchedItemsForUserQueryConds( $db, 
$options );
+               $conds = array_merge( [ 'wl_user' => $user->getId() ], 
$extraConds );
+
+               $dbOptions = $this->getWatchedItemsForUserQueryDbOptions( 
$options );
 
                $res = $db->select(
                        'watchlist',
@@ -440,6 +451,72 @@
                return $watchedItems;
        }
 
+       private function getWatchedItemsForUserQueryConds( IDatabase $db, array 
$options ) {
+               $conds = [];
+               if ( $options['namespaceIds'] ) {
+                       $conds['wl_namespace'] = array_map(
+                               function( $x ) {
+                                       return (int)$x;
+                               },
+                               $options['namespaceIds']
+                       );
+               }
+               if ( array_key_exists( 'filter', $options ) ) {
+                       if ( $options['filter'] === 'changedSinceLastVisit' ) {
+                               $conds[] = 'wl_notificationtimestamp IS NOT 
NULL';
+                       }
+                       if ( $options['filter'] === 'changedBeforeLastVisit' ) {
+                               $conds[] = 'wl_notificationtimestamp IS NULL';
+                       }
+               }
+               $ordered = array_key_exists( 'ordered', $options ) && 
$options['ordered'];
+               $reversedOrder = array_key_exists( 'orderDescending', $options 
) && $options['orderDescending'];
+               if ( $ordered && (
+                               array_key_exists( 'from', $options ) || 
array_key_exists( 'until', $options )
+                       ) ) {
+                       /** @var LinkTarget $target */
+                       if ( array_key_exists( 'from', $options ) ) {
+                               $target = $options['from'];
+                               $op = !$reversedOrder ? '>' : '<';
+                       } else {
+                               $target = $options['until'];
+                               $op = !$reversedOrder ? '<' : '>';
+                       }
+                       $conds[] = $db->makeList(
+                               [
+                                       "wl_namespace $op " . 
$target->getNamespace(),
+                                       $db->makeList(
+                                               [
+                                                       'wl_namespace = ' . 
$target->getNamespace(),
+                                                       "wl_title $op= " . 
$db->addQuotes( $target->getDBkey() )
+                                               ],
+                                               LIST_AND
+                                       )
+                               ],
+                               LIST_OR
+                       );
+               }
+               return $conds;
+       }
+
+       private function getWatchedItemsForUserQueryDbOptions( array $options ) 
{
+               $dbOptions = [];
+               if ( array_key_exists( 'ordered', $options ) && 
$options['ordered'] ) {
+                       $sortSuffix = '';
+                       if ( array_key_exists( 'orderDescending', $options ) && 
$options['orderDescending'] ) {
+                               $sortSuffix = ' DESC';
+                       }
+                       $dbOptions['ORDER BY'] = [ 'wl_namespace' . 
$sortSuffix, 'wl_title' . $sortSuffix ];
+                       if ( count( $options['namespaceIds'] ) === 1 ) {
+                               $dbOptions['ORDER BY'] = 'wl_title' . 
$sortSuffix;
+                       }
+               }
+               if ( array_key_exists( 'limit', $options ) ) {
+                       $dbOptions['LIMIT'] = (int)$options['limit'];
+               }
+               return $dbOptions;
+       }
+
        /**
         * Must be called separately for Subject & Talk namespaces
         *
diff --git a/tests/phpunit/includes/WatchedItemStoreUnitTest.php 
b/tests/phpunit/includes/WatchedItemStoreUnitTest.php
index a7ec3dc..fc15927 100644
--- a/tests/phpunit/includes/WatchedItemStoreUnitTest.php
+++ b/tests/phpunit/includes/WatchedItemStoreUnitTest.php
@@ -1206,7 +1206,7 @@
        /**
         * @dataProvider provideDbTypes
         */
-       public function testGetWatchedItemsForUser_optionsAndEmptyResult( 
$forWrite, $dbType ) {
+       public function testGetWatchedItemsForUser_dbTypeOptions( $forWrite, 
$dbType ) {
                $mockDb = $this->getMockDb();
                $mockCache = $this->getMockCache();
                $mockLoadBalancer = $this->getMockLoadBalancer( $mockDb, 
$dbType );
@@ -1218,8 +1218,7 @@
                                'watchlist',
                                [ 'wl_namespace', 'wl_title', 
'wl_notificationtimestamp' ],
                                [ 'wl_user' => 1 ],
-                               $this->isType( 'string' ),
-                               [ 'ORDER BY' => [ 'wl_namespace', 'wl_title' ] ]
+                               $this->isType( 'string' )
                        )
                        ->will( $this->returnValue( [] ) );
 
@@ -1230,7 +1229,281 @@
 
                $watchedItems = $store->getWatchedItemsForUser(
                        $user,
-                       [ 'forWrite' => $forWrite, 'ordered' => true ]
+                       [ 'forWrite' => $forWrite ]
+               );
+               $this->assertEquals( [], $watchedItems );
+       }
+
+       public function provideGetWatchedItemsForUserOptions() {
+               return [
+                       [
+                               [
+                                       'namespaceIds' => [ 0, 1 ],
+                               ],
+                               [
+                                       'wl_namespace' => [ 0, 1 ],
+                               ],
+                               []
+                       ],
+                       [
+                               [
+                                       'ordered' => true,
+                               ],
+                               [],
+                               [ 'ORDER BY' => [ 'wl_namespace', 'wl_title' ] ]
+                       ],
+                       [
+                               [
+                                       'namespaceIds' => [ 0 ],
+                                       'ordered' => true,
+                               ],
+                               [
+                                       'wl_namespace' => [ 0 ],
+                               ],
+                               [ 'ORDER BY' => 'wl_title' ]
+                       ],
+                       [
+                               [ 'limit' => 10 ],
+                               [],
+                               [ 'LIMIT' => 10 ]
+                       ],
+                       [
+                               [
+                                       'namespaceIds' => [ 0, "1; DROP TABLE 
watchlist;\n--" ],
+                                       'limit' => "10; DROP TABLE 
watchlist;\n--",
+                               ],
+                               [
+                                       'wl_namespace' => [ 0, 1 ],
+                               ],
+                               [ 'LIMIT' => 10 ]
+                       ],
+                       [
+                               [ 'filter' => 'changedSinceLastVisit' ],
+                               [ 'wl_notificationtimestamp IS NOT NULL' ],
+                               []
+                       ],
+                       [
+                               [ 'filter' => 'changedBeforeLastVisit' ],
+                               [ 'wl_notificationtimestamp IS NULL' ],
+                               []
+                       ],
+                       [
+                               [
+                                       'ordered' => true,
+                                       'orderDescending' => true,
+                               ],
+                               [],
+                               [ 'ORDER BY' => [ 'wl_namespace DESC', 
'wl_title DESC' ] ]
+                       ],
+                       [
+                               [
+                                       'namespaceIds' => [ 0 ],
+                                       'ordered' => true,
+                                       'orderDescending' => true,
+                               ],
+                               [
+                                       'wl_namespace' => [ 0 ],
+                               ],
+                               [ 'ORDER BY' => 'wl_title DESC' ]
+                       ],
+                       [
+                               [
+                                       'namespaceIds' => 0,
+                               ],
+                               [],
+                               []
+                       ],
+                       [
+                               [
+                                       'namespaceIds' => "1; DROP TABLE 
watchlist;\n--",
+                               ],
+                               [],
+                               []
+                       ],
+                       [
+                               [
+                                       'orderDescending' => true,
+                               ],
+                               [],
+                               []
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetWatchedItemsForUserOptions
+        */
+       public function testGetWatchedItemsForUser_optionsAndEmptyResult(
+               array $options,
+               array $expectedConds,
+               array $expectedDbOptions
+       ) {
+               $mockDb = $this->getMockDb();
+               $mockCache = $this->getMockCache();
+               $user = $this->getMockNonAnonUserWithId( 1 );
+
+               $expectedConds = array_merge( [ 'wl_user' => 1 ], 
$expectedConds );
+               $mockDb->expects( $this->once() )
+                       ->method( 'select' )
+                       ->with(
+                               'watchlist',
+                               [ 'wl_namespace', 'wl_title', 
'wl_notificationtimestamp' ],
+                               $expectedConds,
+                               $this->isType( 'string' ),
+                               $expectedDbOptions
+                       )
+                       ->will( $this->returnValue( [] ) );
+
+               $store = new WatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $watchedItems = $store->getWatchedItemsForUser(
+                       $user,
+                       $options
+               );
+               $this->assertEquals( [], $watchedItems );
+       }
+
+       public function provideGetWatchedItemsForUser_fromUntilOptions() {
+               return [
+                       [
+                               [
+                                       'from' => new TitleValue( 0, 
'SomeDbKey' ),
+                                       'ordered' => true,
+                               ],
+                               [
+                                       "(wl_namespace > 0) OR ((wl_namespace = 
0) AND (wl_title >= 'SomeDbKey'))",
+                               ],
+                               [ 'ORDER BY' => [ 'wl_namespace', 'wl_title' ] ]
+                       ],
+                       [
+                               [
+                                       'from' => new TitleValue( 0, 
'SomeDbKey' ),
+                                       'ordered' => true,
+                                       'orderDescending' => true,
+                               ],
+                               [
+                                       "(wl_namespace < 0) OR ((wl_namespace = 
0) AND (wl_title <= 'SomeDbKey'))",
+                               ],
+                               [ 'ORDER BY' => [ 'wl_namespace DESC', 
'wl_title DESC' ] ]
+                       ],
+                       [
+                               [
+                                       'until' => new TitleValue( 0, 
'SomeDbKey' ),
+                                       'ordered' => true,
+                               ],
+                               [
+                                       "(wl_namespace < 0) OR ((wl_namespace = 
0) AND (wl_title <= 'SomeDbKey'))",
+                               ],
+                               [ 'ORDER BY' => [ 'wl_namespace', 'wl_title' ] ]
+                       ],
+                       [
+                               [
+                                       'until' => new TitleValue( 0, 
'SomeDbKey' ),
+                                       'ordered' => true,
+                                       'orderDescending' => true,
+                               ],
+                               [
+                                       "(wl_namespace > 0) OR ((wl_namespace = 
0) AND (wl_title >= 'SomeDbKey'))",
+                               ],
+                               [ 'ORDER BY' => [ 'wl_namespace DESC', 
'wl_title DESC' ] ]
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetWatchedItemsForUser_fromUntilOptions
+        */
+       public function testGetWatchedItemsForUser_fromUntilOptions(
+               array $options,
+               array $expectedConds,
+               array $expectedDbOptions
+       ) {
+               $mockCache = $this->getMockCache();
+               $user = $this->getMockNonAnonUserWithId( 1 );
+
+               $expectedConds = array_merge( [ 'wl_user' => 1 ], 
$expectedConds );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->once() )
+                       ->method( 'addQuotes' )
+                       ->will( $this->returnCallback( function( $value ) {
+                               return "'$value'";
+                       } ) );
+               $mockDb->expects( $this->exactly( 2 ) )
+                       ->method( 'makeList' )
+                       ->with(
+                               $this->isType( 'array' ),
+                               $this->isType( 'int' )
+                       )
+                       ->will( $this->returnCallback( function( $a, $conj ) {
+                               $sqlConj = $conj === LIST_AND ? ' AND ' : ' OR 
';
+                               return join( $sqlConj, array_map( function( $s 
) {
+                                       return '(' . $s . ')';
+                               }, $a
+                               ) );
+                       } ) );
+               $mockDb->expects( $this->once() )
+                       ->method( 'select' )
+                       ->with(
+                               'watchlist',
+                               [ 'wl_namespace', 'wl_title', 
'wl_notificationtimestamp' ],
+                               $expectedConds,
+                               $this->isType( 'string' ),
+                               $expectedDbOptions
+                       )
+                       ->will( $this->returnValue( [] ) );
+
+               $store = new WatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $watchedItems = $store->getWatchedItemsForUser(
+                       $user,
+                       $options
+               );
+               $this->assertEquals( [], $watchedItems );
+       }
+
+       public function provideGetWatchedItemsForUser_fromUntilNoOrdered() {
+               return [
+                       [ [ 'from' => new TitleValue( 0, 'SomeDbKey' ), ] ],
+                       [ [ 'until' => new TitleValue( 0, 'SomeDbKey' ), ] ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetWatchedItemsForUser_fromUntilNoOrdered
+        */
+       public function testGetWatchedItemsForUser_NoOrdered( array $options ) {
+               $mockCache = $this->getMockCache();
+               $user = $this->getMockNonAnonUserWithId( 1 );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->never() )->method( 'addQuotes' );
+               $mockDb->expects( $this->never() )->method( 'makeList' );
+               $mockDb->expects( $this->once() )
+                       ->method( 'select' )
+                       ->with(
+                               'watchlist',
+                               [ 'wl_namespace', 'wl_title', 
'wl_notificationtimestamp' ],
+                               [ 'wl_user' => 1 ],
+                               $this->isType( 'string' ),
+                               []
+                       )
+                       ->will( $this->returnValue( [] ) );
+
+               $store = new WatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $watchedItems = $store->getWatchedItemsForUser(
+                       $user,
+                       $options
                );
                $this->assertEquals( [], $watchedItems );
        }
diff --git a/tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php 
b/tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php
new file mode 100644
index 0000000..9703f99
--- /dev/null
+++ b/tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php
@@ -0,0 +1,250 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ *
+ * @covers ApiQueryWatchlistRaw
+ */
+class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
+
+       protected function setUp() {
+               parent::setUp();
+               self::$users['ApiQueryWatchlistRawIntegrationTestUser']
+                       = new TestUser( 
'ApiQueryWatchlistRawIntegrationTestUser' );
+               $this->doLogin( 'ApiQueryWatchlistRawIntegrationTestUser' );
+       }
+
+       public function addDBDataOnce() {
+               // TODO: is this needed at all? wl can include things that 
don't exist
+               $this->insertPage( 'ApiQueryWatchlistRawIntegrationTestPage1' );
+               $this->insertPage( 'ApiQueryWatchlistRawIntegrationTestPage2' );
+               $this->insertPage( 'ApiQueryWatchlistRawIntegrationTestPageA' );
+               $this->insertPage( 'ApiQueryWatchlistRawIntegrationTestPageB' );
+
+               $testUser = new TestUser( 
'ApiQueryWatchlistRawIntegrationTestUser' );
+               $user = $testUser->getUser();
+               $store = WatchedItemStore::getDefaultInstance();
+               $store->addWatchBatch( [
+                       [ $user, new TitleValue( 0, 
'ApiQueryWatchlistRawIntegrationTestPage1' ) ],
+                       [ $user, new TitleValue( 1, 
'ApiQueryWatchlistRawIntegrationTestPage1' ) ],
+                       [ $user, new TitleValue( 0, 
'ApiQueryWatchlistRawIntegrationTestPageB' ) ],
+                       [ $user, new TitleValue( 1, 
'ApiQueryWatchlistRawIntegrationTestPageB' ) ],
+                       [ $user, new TitleValue( 0, 
'ApiQueryWatchlistRawIntegrationTestPageA' ) ],
+                       [ $user, new TitleValue( 1, 
'ApiQueryWatchlistRawIntegrationTestPageA' ) ],
+                       [ $user, new TitleValue( 0, 
'ApiQueryWatchlistRawIntegrationTestPage2' ) ],
+               ] );
+               $otherUser = ( new TestUser( 
'ApiQueryWatchlistRawIntegrationTestUser_otherUser' ) )->getUser();
+               $store->updateNotificationTimestamp(
+                       $otherUser,
+                       new TitleValue( 0, 
'ApiQueryWatchlistRawIntegrationTestPage2' ),
+                       '20151212010101'
+               );
+       }
+
+       public function testListWatchlistRaw_returnsWatchedItems() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+               ] );
+               $resultHasExpectedPage = false;
+               foreach ( $result[0]['watchlistraw'] as $page ) {
+                       if ( $page['ns'] === 0 && $page['title'] === 
'ApiQueryWatchlistRawIntegrationTestPage1' ) {
+                               $resultHasExpectedPage = true;
+                       }
+               }
+               $this->assertTrue( $resultHasExpectedPage );
+       }
+
+       public function testPropChanged_addsNotificationTimestamp() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrprop' => 'changed',
+               ] );
+               $resultHasChangedField = false;
+               foreach ( $result[0]['watchlistraw'] as $page ) {
+                       if ( array_key_exists( 'changed', $page ) ) {
+                               $resultHasChangedField = true;
+                               break;
+                       }
+               }
+               $this->assertTrue( $resultHasChangedField );
+       }
+
+       public function testNamespaceParam() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrnamespace' => '0',
+               ] );
+               $resultHasTalkPage = false;
+               foreach ( $result[0]['watchlistraw'] as $page ) {
+                       if ( $page['ns'] === 1 ) {
+                               $resultHasTalkPage = true;
+                               break;
+                       }
+               }
+               $this->assertFalse( $resultHasTalkPage );
+       }
+
+       public function testShowChanged() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrprop' => 'changed',
+                       'wrshow' => 'changed',
+               ] );
+               $resultHasItemWithoutChangedField = false;
+               foreach ( $result[0]['watchlistraw'] as $page ) {
+                       if ( !array_key_exists( 'changed', $page ) ) {
+                               $resultHasItemWithoutChangedField = true;
+                               break;
+                       }
+               }
+               $this->assertFalse( $resultHasItemWithoutChangedField );
+       }
+
+       public function testShowNotChanged() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrprop' => 'changed',
+                       'wrshow' => '!changed',
+               ] );
+               $resultHasItemWithChangedField = false;
+               foreach ( $result[0]['watchlistraw'] as $page ) {
+                       if ( array_key_exists( 'changed', $page ) ) {
+                               $resultHasItemWithChangedField = true;
+                               break;
+                       }
+               }
+               $this->assertFalse( $resultHasItemWithChangedField );
+       }
+
+       public function testLimit() {
+               $resultWithoutLimit = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+               ] );
+               $this->assertGreaterThan( 5, count( 
$resultWithoutLimit[0]['watchlistraw'] ) );
+               $this->assertCount(
+                       5,
+                       $this->doApiRequest( [
+                               'action' => 'query',
+                               'list' => 'watchlistraw',
+                               'wrlimit' => 5,
+                       ] )[0]['watchlistraw']
+               );
+       }
+
+       public function testDirAscending() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrdir' => 'ascending',
+               ] );
+               $resultsNotInAscOrder = false;
+               $pages = $result[0]['watchlistraw'];
+               $previous = array_shift( $pages );
+               foreach ( $pages as $page ) {
+                       if ( $previous['ns'] > $page['ns'] || (
+                                       $previous['ns'] === $page['ns'] && 
$previous['title'] > $page['title']
+                               ) ) {
+                               $resultsNotInAscOrder = true;
+                               break;
+                       }
+               }
+               $this->assertFalse( $resultsNotInAscOrder );
+       }
+
+       public function testDirDescending() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrdir' => 'descending',
+               ] );
+               $resultsNotInDescOrder = false;
+               $pages = $result[0]['watchlistraw'];
+               $previous = array_shift( $pages );
+               foreach ( $pages as $page ) {
+                       if ( $previous['ns'] < $page['ns'] || (
+                                       $previous['ns'] === $page['ns'] && 
$previous['title'] < $page['title']
+                               ) ) {
+                               $resultsNotInDescOrder = true;
+                               break;
+                       }
+               }
+               $this->assertFalse( $resultsNotInDescOrder );
+       }
+
+       public function testAscendingIsDefaultOrder() {
+               $resultNoDir = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+               ] );
+               $resultAscDir = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrdir' => 'ascending',
+               ] );
+               $this->assertEquals( $resultAscDir[0]['watchlistraw'], 
$resultNoDir[0]['watchlistraw'] );
+       }
+
+       public function testFromTitle() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrfromtitle' => 
'ApiQueryWatchlistRawIntegrationTestPageA',
+               ] );
+               $pages = $result[0]['watchlistraw'];
+               $this->assertEquals( 
'ApiQueryWatchlistRawIntegrationTestPageA', $pages[0]['title'] );
+               $this->assertEquals( 0, $pages[0]['ns'] );
+               $resultContainsNotExpectedPage = false;
+               foreach ( $pages as $page ) {
+                       if ( $page['title'] === 
'ApiQueryWatchlistRawIntegrationTestPage1' ) {
+                               $resultContainsNotExpectedPage = true;
+                       }
+               }
+               $this->assertFalse( $resultContainsNotExpectedPage );
+       }
+
+       public function testToTitle() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrtotitle' => 
'ApiQueryWatchlistRawIntegrationTestPageA',
+               ] );
+               $pages = $result[0]['watchlistraw'];
+               $lastIndex = count( $pages ) - 1;
+               $this->assertEquals( 
'ApiQueryWatchlistRawIntegrationTestPageA', $pages[$lastIndex]['title'] );
+               $this->assertEquals( 0, $pages[$lastIndex]['ns'] );
+               $resultContainsNotExpectedPage = false;
+               foreach ( $pages as $page ) {
+                       if ( $page['title'] === 
'ApiQueryWatchlistRawIntegrationTestPageB' ) {
+                               $resultContainsNotExpectedPage = true;
+                       }
+               }
+               $this->assertFalse( $resultContainsNotExpectedPage );
+       }
+
+       public function testContinue() {
+               $result = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'watchlistraw',
+                       'wrcontinue' => 
'0|ApiQueryWatchlistRawIntegrationTestPageA',
+               ] );
+               $pages = $result[0]['watchlistraw'];
+               $this->assertEquals( 
'ApiQueryWatchlistRawIntegrationTestPageA', $pages[0]['title'] );
+               $this->assertEquals( 0, $pages[0]['ns'] );
+               $resultContainsNotExpectedPage = false;
+               foreach ( $pages as $page ) {
+                       if ( $page['title'] === 
'ApiQueryWatchlistRawIntegrationTestPage1' ) {
+                               $resultContainsNotExpectedPage = true;
+                       }
+               }
+               $this->assertFalse( $resultContainsNotExpectedPage );
+       }
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/278859
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I875a92074b52c00ac11db1fa05615abbf5262ab1
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: WMDE-leszek <leszek.mani...@wikimedia.de>
Gerrit-Reviewer: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: WMDE-Fisch <christoph.fisc...@wikimedia.de>
Gerrit-Reviewer: WMDE-leszek <leszek.mani...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to