3 namespace MediaWiki\Tests\Api\Query
;
5 use MediaWiki\Tests\Api\ApiTestCase
;
6 use MediaWiki\Title\TitleValue
;
7 use MediaWiki\User\User
;
8 use MediaWiki\Watchlist\WatchedItemQueryService
;
15 * @covers \MediaWiki\Api\ApiQueryWatchlistRaw
17 class ApiQueryWatchlistRawIntegrationTest
extends ApiTestCase
{
18 // TODO: This test should use Authority, but can't due to User::saveSettings
20 private $loggedInUser;
22 private $notLoggedInUser;
24 protected function setUp(): void
{
27 $this->loggedInUser
= $this->getMutableTestUser()->getUser();
28 $this->notLoggedInUser
= $this->getMutableTestUser()->getUser();
31 private function getLoggedInTestUser(): User
{
32 return $this->loggedInUser
;
35 private function getNotLoggedInTestUser(): User
{
36 return $this->notLoggedInUser
;
39 private function getWatchedItemStore() {
40 return $this->getServiceContainer()->getWatchedItemStore();
43 private function doListWatchlistRawRequest( array $params = [] ) {
44 return $this->doApiRequest( array_merge(
45 [ 'action' => 'query', 'list' => 'watchlistraw' ],
47 ), null, false, $this->getLoggedInTestUser() );
50 private function doGeneratorWatchlistRawRequest( array $params = [] ) {
51 return $this->doApiRequest( array_merge(
52 [ 'action' => 'query', 'generator' => 'watchlistraw' ],
54 ), null, false, $this->getLoggedInTestUser() );
57 private function getItemsFromApiResponse( array $response ) {
58 return $response[0]['watchlistraw'];
61 public function testListWatchlistRaw_returnsWatchedItems() {
62 $store = $this->getWatchedItemStore();
64 $this->getLoggedInTestUser(),
65 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage' )
68 $result = $this->doListWatchlistRawRequest();
70 $this->assertArrayHasKey( 'watchlistraw', $result[0] );
76 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
79 $this->getItemsFromApiResponse( $result )
83 public function testPropChanged_addsNotificationTimestamp() {
84 $target = new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage' );
85 $otherUser = $this->getNotLoggedInTestUser();
87 $store = $this->getWatchedItemStore();
89 $store->addWatch( $this->getLoggedInTestUser(), $target );
90 $store->updateNotificationTimestamp(
96 $result = $this->doListWatchlistRawRequest( [ 'wrprop' => 'changed' ] );
102 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
103 'changed' => '2015-12-12T01:01:01Z',
106 $this->getItemsFromApiResponse( $result )
110 public function testNamespaceParam() {
111 $store = $this->getWatchedItemStore();
113 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
114 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage' ),
115 new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage' ),
118 $result = $this->doListWatchlistRawRequest( [ 'wrnamespace' => '0' ] );
124 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
127 $this->getItemsFromApiResponse( $result )
131 public function testShowChangedParams() {
132 $subjectTarget = new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage' );
133 $talkTarget = new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage' );
134 $otherUser = $this->getNotLoggedInTestUser();
136 $store = $this->getWatchedItemStore();
138 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
142 $store->updateNotificationTimestamp(
148 $resultChanged = $this->doListWatchlistRawRequest(
149 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService
::FILTER_CHANGED
]
151 $resultNotChanged = $this->doListWatchlistRawRequest(
152 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService
::FILTER_NOT_CHANGED
]
159 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
160 'changed' => '2015-12-12T01:01:01Z',
163 $this->getItemsFromApiResponse( $resultChanged )
170 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage',
173 $this->getItemsFromApiResponse( $resultNotChanged )
177 public function testLimitParam() {
178 $store = $this->getWatchedItemStore();
180 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
181 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
182 new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
183 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
186 $resultWithoutLimit = $this->doListWatchlistRawRequest();
187 $resultWithLimit = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
193 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
197 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
201 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
204 $this->getItemsFromApiResponse( $resultWithoutLimit )
210 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
214 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
217 $this->getItemsFromApiResponse( $resultWithLimit )
220 $this->assertArrayNotHasKey( 'continue', $resultWithoutLimit[0] );
221 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
222 $this->assertArrayHasKey( 'wrcontinue', $resultWithLimit[0]['continue'] );
225 public function testDirParams() {
226 $store = $this->getWatchedItemStore();
228 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
229 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
230 new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
231 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
234 $resultDirAsc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
235 $resultDirDesc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'descending' ] );
241 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
245 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
249 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
252 $this->getItemsFromApiResponse( $resultDirAsc )
259 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
263 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
267 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
270 $this->getItemsFromApiResponse( $resultDirDesc )
274 public function testAscendingIsDefaultOrder() {
275 $store = $this->getWatchedItemStore();
277 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
278 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
279 new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
280 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
283 $resultNoDir = $this->doListWatchlistRawRequest();
284 $resultAscDir = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
287 $this->getItemsFromApiResponse( $resultNoDir ),
288 $this->getItemsFromApiResponse( $resultAscDir )
292 public function testFromTitleParam() {
293 $store = $this->getWatchedItemStore();
295 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
296 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
297 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
298 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
301 $result = $this->doListWatchlistRawRequest( [
302 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
309 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
313 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
316 $this->getItemsFromApiResponse( $result )
320 public function testToTitleParam() {
321 $store = $this->getWatchedItemStore();
323 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
324 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
325 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
326 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
329 $result = $this->doListWatchlistRawRequest( [
330 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
337 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
341 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
344 $this->getItemsFromApiResponse( $result )
348 public function testContinueParam() {
349 $store = $this->getWatchedItemStore();
351 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
352 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
353 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
354 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
357 $firstResult = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
358 $continuationParam = $firstResult[0]['continue']['wrcontinue'];
360 $this->assertSame( '0|ApiQueryWatchlistRawIntegrationTestPage3', $continuationParam );
362 $continuedResult = $this->doListWatchlistRawRequest( [ 'wrcontinue' => $continuationParam ] );
368 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
371 $this->getItemsFromApiResponse( $continuedResult )
375 public static function fromTitleToTitleContinueComboProvider() {
379 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
380 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
383 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1' ],
384 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
389 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
390 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
393 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
398 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
399 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
402 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
403 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
408 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
409 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
410 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
413 [ 'ns' => NS_MAIN
, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
420 * @dataProvider fromTitleToTitleContinueComboProvider
422 public function testFromTitleToTitleContinueCombo( array $params, array $expectedItems ) {
423 $store = $this->getWatchedItemStore();
425 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
426 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
427 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
428 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
431 $result = $this->doListWatchlistRawRequest( $params );
433 $this->assertEquals( $expectedItems, $this->getItemsFromApiResponse( $result ) );
436 public static function fromTitleToTitleContinueSelfContradictoryComboProvider() {
440 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
441 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
446 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
447 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
448 'wrdir' => 'descending',
453 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
454 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
461 * @dataProvider fromTitleToTitleContinueSelfContradictoryComboProvider
463 public function testFromTitleToTitleContinueSelfContradictoryCombo( array $params ) {
464 $store = $this->getWatchedItemStore();
466 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
467 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
468 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
471 $result = $this->doListWatchlistRawRequest( $params );
473 $this->assertSame( [], $this->getItemsFromApiResponse( $result ) );
474 $this->assertArrayNotHasKey( 'continue', $result[0] );
477 public function testOwnerAndTokenParams() {
478 $services = $this->getServiceContainer();
479 $userOptionsManager = $services->getUserOptionsManager();
481 $otherUser = $this->getNotLoggedInTestUser();
482 $userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
483 $otherUser->saveSettings();
485 $store = $this->getWatchedItemStore();
486 $store->addWatchBatchForUser( $otherUser, [
487 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
488 new TitleValue( NS_TALK
, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
491 $services->getMainWANObjectCache()->clearProcessCache();
492 $result = $this->doListWatchlistRawRequest( [
493 'wrowner' => $otherUser->getName(),
494 'wrtoken' => '1234567890',
501 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
505 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
508 $this->getItemsFromApiResponse( $result )
512 public function testOwnerAndTokenParams_wrongToken() {
513 $userOptionsManager = $this->getServiceContainer()->getUserOptionsManager();
515 $otherUser = $this->getNotLoggedInTestUser();
516 $userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
517 $otherUser->saveSettings();
519 $this->expectApiErrorCode( 'bad_wltoken' );
521 $this->doListWatchlistRawRequest( [
522 'wrowner' => $otherUser->getName(),
523 'wrtoken' => 'wrong-token',
527 public function testOwnerAndTokenParams_userHasNoWatchlistToken() {
528 $this->expectApiErrorCode( 'bad_wltoken' );
530 $this->doListWatchlistRawRequest( [
531 'wrowner' => $this->getNotLoggedInTestUser()->getName(),
532 'wrtoken' => 'some-watchlist-token',
536 public function testGeneratorWatchlistRawPropInfo_returnsWatchedItems() {
537 $store = $this->getWatchedItemStore();
539 $this->getLoggedInTestUser(),
540 new TitleValue( NS_MAIN
, 'ApiQueryWatchlistRawIntegrationTestPage' )
543 $result = $this->doGeneratorWatchlistRawRequest( [ 'prop' => 'info' ] );
545 $this->assertArrayHasKey( 'query', $result[0] );
546 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
547 $this->assertCount( 1, $result[0]['query']['pages'] );
549 // $result[0]['query']['pages'] uses page ids as keys
550 $item = array_values( $result[0]['query']['pages'] )[0];
552 $this->assertSame( NS_MAIN
, $item['ns'] );
553 $this->assertEquals( 'ApiQueryWatchlistRawIntegrationTestPage', $item['title'] );