Merge "Remove use of BagOStuff TTL constants from unrelated code"
[mediawiki.git] / tests / phpunit / includes / api / query / ApiQueryWatchlistRawIntegrationTest.php
blob063e7c8af401d2d42f905b5ecdc7a6e2bdd374d1
1 <?php
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;
10 /**
11 * @group API
12 * @group Database
13 * @group medium
15 * @covers \MediaWiki\Api\ApiQueryWatchlistRaw
17 class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
18 // TODO: This test should use Authority, but can't due to User::saveSettings
19 /** @var User */
20 private $loggedInUser;
21 /** @var User */
22 private $notLoggedInUser;
24 protected function setUp(): void {
25 parent::setUp();
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' ],
46 $params
47 ), null, false, $this->getLoggedInTestUser() );
50 private function doGeneratorWatchlistRawRequest( array $params = [] ) {
51 return $this->doApiRequest( array_merge(
52 [ 'action' => 'query', 'generator' => 'watchlistraw' ],
53 $params
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();
63 $store->addWatch(
64 $this->getLoggedInTestUser(),
65 new TitleValue( NS_MAIN, 'ApiQueryWatchlistRawIntegrationTestPage' )
68 $result = $this->doListWatchlistRawRequest();
70 $this->assertArrayHasKey( 'watchlistraw', $result[0] );
72 $this->assertEquals(
75 'ns' => NS_MAIN,
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(
91 $otherUser,
92 $target,
93 '20151212010101'
96 $result = $this->doListWatchlistRawRequest( [ 'wrprop' => 'changed' ] );
98 $this->assertEquals(
101 'ns' => NS_MAIN,
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' ),
116 ] );
118 $result = $this->doListWatchlistRawRequest( [ 'wrnamespace' => '0' ] );
120 $this->assertEquals(
123 'ns' => NS_MAIN,
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(), [
139 $subjectTarget,
140 $talkTarget,
141 ] );
142 $store->updateNotificationTimestamp(
143 $otherUser,
144 $subjectTarget,
145 '20151212010101'
148 $resultChanged = $this->doListWatchlistRawRequest(
149 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_CHANGED ]
151 $resultNotChanged = $this->doListWatchlistRawRequest(
152 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_NOT_CHANGED ]
155 $this->assertEquals(
158 'ns' => NS_MAIN,
159 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
160 'changed' => '2015-12-12T01:01:01Z',
163 $this->getItemsFromApiResponse( $resultChanged )
166 $this->assertEquals(
169 'ns' => NS_TALK,
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' ),
184 ] );
186 $resultWithoutLimit = $this->doListWatchlistRawRequest();
187 $resultWithLimit = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
189 $this->assertEquals(
192 'ns' => NS_MAIN,
193 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
196 'ns' => NS_MAIN,
197 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
200 'ns' => NS_TALK,
201 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
204 $this->getItemsFromApiResponse( $resultWithoutLimit )
206 $this->assertEquals(
209 'ns' => NS_MAIN,
210 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
213 'ns' => NS_MAIN,
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' ),
232 ] );
234 $resultDirAsc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
235 $resultDirDesc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'descending' ] );
237 $this->assertEquals(
240 'ns' => NS_MAIN,
241 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
244 'ns' => NS_MAIN,
245 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
248 'ns' => NS_TALK,
249 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
252 $this->getItemsFromApiResponse( $resultDirAsc )
255 $this->assertEquals(
258 'ns' => NS_TALK,
259 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
262 'ns' => NS_MAIN,
263 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
266 'ns' => NS_MAIN,
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' ),
281 ] );
283 $resultNoDir = $this->doListWatchlistRawRequest();
284 $resultAscDir = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
286 $this->assertEquals(
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' ),
299 ] );
301 $result = $this->doListWatchlistRawRequest( [
302 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
303 ] );
305 $this->assertEquals(
308 'ns' => NS_MAIN,
309 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
312 'ns' => NS_MAIN,
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' ),
327 ] );
329 $result = $this->doListWatchlistRawRequest( [
330 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
331 ] );
333 $this->assertEquals(
336 'ns' => NS_MAIN,
337 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
340 'ns' => NS_MAIN,
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' ),
355 ] );
357 $firstResult = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
358 $continuationParam = $firstResult[0]['continue']['wrcontinue'];
360 $this->assertSame( '0|ApiQueryWatchlistRawIntegrationTestPage3', $continuationParam );
362 $continuedResult = $this->doListWatchlistRawRequest( [ 'wrcontinue' => $continuationParam ] );
364 $this->assertEquals(
367 'ns' => NS_MAIN,
368 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
371 $this->getItemsFromApiResponse( $continuedResult )
375 public static function fromTitleToTitleContinueComboProvider() {
376 return [
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' ),
429 ] );
431 $result = $this->doListWatchlistRawRequest( $params );
433 $this->assertEquals( $expectedItems, $this->getItemsFromApiResponse( $result ) );
436 public static function fromTitleToTitleContinueSelfContradictoryComboProvider() {
437 return [
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' ),
469 ] );
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' ),
489 ] );
491 $services->getMainWANObjectCache()->clearProcessCache();
492 $result = $this->doListWatchlistRawRequest( [
493 'wrowner' => $otherUser->getName(),
494 'wrtoken' => '1234567890',
495 ] );
497 $this->assertEquals(
500 'ns' => NS_MAIN,
501 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
504 'ns' => NS_TALK,
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',
524 ] );
527 public function testOwnerAndTokenParams_userHasNoWatchlistToken() {
528 $this->expectApiErrorCode( 'bad_wltoken' );
530 $this->doListWatchlistRawRequest( [
531 'wrowner' => $this->getNotLoggedInTestUser()->getName(),
532 'wrtoken' => 'some-watchlist-token',
533 ] );
536 public function testGeneratorWatchlistRawPropInfo_returnsWatchedItems() {
537 $store = $this->getWatchedItemStore();
538 $store->addWatch(
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'] );