Merge "Revert "Log the reason why revision->getContent() returns null""
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiQueryWatchlistIntegrationTest.php
1 <?php
2
3 use MediaWiki\Linker\LinkTarget;
4 use MediaWiki\MediaWikiServices;
5
6 /**
7 * @group API
8 * @group Database
9 * @group medium
10 *
11 * @covers ApiQueryWatchlist
12 */
13 class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
14
15 public function __construct( $name = null, array $data = [], $dataName = '' ) {
16 parent::__construct( $name, $data, $dataName );
17 $this->tablesUsed = array_unique(
18 array_merge( $this->tablesUsed, [ 'watchlist', 'recentchanges', 'page' ] )
19 );
20 }
21
22 protected function setUp() {
23 parent::setUp();
24 self::$users['ApiQueryWatchlistIntegrationTestUser'] = $this->getMutableTestUser();
25 self::$users['ApiQueryWatchlistIntegrationTestUser2'] = $this->getMutableTestUser();
26 $this->doLogin( 'ApiQueryWatchlistIntegrationTestUser' );
27 }
28
29 private function getLoggedInTestUser() {
30 return self::$users['ApiQueryWatchlistIntegrationTestUser']->getUser();
31 }
32
33 private function getNonLoggedInTestUser() {
34 return self::$users['ApiQueryWatchlistIntegrationTestUser2']->getUser();
35 }
36
37 private function doPageEdit( User $user, LinkTarget $target, $content, $summary ) {
38 $title = Title::newFromLinkTarget( $target );
39 $page = WikiPage::factory( $title );
40 $page->doEditContent(
41 ContentHandler::makeContent( $content, $title ),
42 $summary,
43 0,
44 false,
45 $user
46 );
47 }
48
49 private function doMinorPageEdit( User $user, LinkTarget $target, $content, $summary ) {
50 $title = Title::newFromLinkTarget( $target );
51 $page = WikiPage::factory( $title );
52 $page->doEditContent(
53 ContentHandler::makeContent( $content, $title ),
54 $summary,
55 EDIT_MINOR,
56 false,
57 $user
58 );
59 }
60
61 private function doBotPageEdit( User $user, LinkTarget $target, $content, $summary ) {
62 $title = Title::newFromLinkTarget( $target );
63 $page = WikiPage::factory( $title );
64 $page->doEditContent(
65 ContentHandler::makeContent( $content, $title ),
66 $summary,
67 EDIT_FORCE_BOT,
68 false,
69 $user
70 );
71 }
72
73 private function doAnonPageEdit( LinkTarget $target, $content, $summary ) {
74 $title = Title::newFromLinkTarget( $target );
75 $page = WikiPage::factory( $title );
76 $page->doEditContent(
77 ContentHandler::makeContent( $content, $title ),
78 $summary,
79 0,
80 false,
81 User::newFromId( 0 )
82 );
83 }
84
85 private function doPatrolledPageEdit(
86 User $user,
87 LinkTarget $target,
88 $content,
89 $summary,
90 User $patrollingUser
91 ) {
92 $title = Title::newFromLinkTarget( $target );
93 $page = WikiPage::factory( $title );
94 $status = $page->doEditContent(
95 ContentHandler::makeContent( $content, $title ),
96 $summary,
97 0,
98 false,
99 $user
100 );
101 /** @var Revision $rev */
102 $rev = $status->value['revision'];
103 $rc = $rev->getRecentChange();
104 $rc->doMarkPatrolled( $patrollingUser, false, [] );
105 }
106
107 private function deletePage( LinkTarget $target, $reason ) {
108 $title = Title::newFromLinkTarget( $target );
109 $page = WikiPage::factory( $title );
110 $page->doDeleteArticleReal( $reason );
111 }
112
113 /**
114 * Performs a batch of page edits as a specified user
115 * @param User $user
116 * @param array $editData associative array, keys:
117 * - target => LinkTarget page to edit
118 * - content => string new content
119 * - summary => string edit summary
120 * - minorEdit => bool mark as minor edit if true (defaults to false)
121 * - botEdit => bool mark as bot edit if true (defaults to false)
122 */
123 private function doPageEdits( User $user, array $editData ) {
124 foreach ( $editData as $singleEditData ) {
125 if ( array_key_exists( 'minorEdit', $singleEditData ) && $singleEditData['minorEdit'] ) {
126 $this->doMinorPageEdit(
127 $user,
128 $singleEditData['target'],
129 $singleEditData['content'],
130 $singleEditData['summary']
131 );
132 continue;
133 }
134 if ( array_key_exists( 'botEdit', $singleEditData ) && $singleEditData['botEdit'] ) {
135 $this->doBotPageEdit(
136 $user,
137 $singleEditData['target'],
138 $singleEditData['content'],
139 $singleEditData['summary']
140 );
141 continue;
142 }
143 $this->doPageEdit(
144 $user,
145 $singleEditData['target'],
146 $singleEditData['content'],
147 $singleEditData['summary']
148 );
149 }
150 }
151
152 private function getWatchedItemStore() {
153 return MediaWikiServices::getInstance()->getWatchedItemStore();
154 }
155
156 /**
157 * @param User $user
158 * @param LinkTarget[] $targets
159 */
160 private function watchPages( User $user, array $targets ) {
161 $store = $this->getWatchedItemStore();
162 $store->addWatchBatchForUser( $user, $targets );
163 }
164
165 private function doListWatchlistRequest( array $params = [], $user = null ) {
166 return $this->doApiRequest(
167 array_merge(
168 [ 'action' => 'query', 'list' => 'watchlist' ],
169 $params
170 ), null, false, $user
171 );
172 }
173
174 private function doGeneratorWatchlistRequest( array $params = [] ) {
175 return $this->doApiRequest(
176 array_merge(
177 [ 'action' => 'query', 'generator' => 'watchlist' ],
178 $params
179 )
180 );
181 }
182
183 private function getItemsFromApiResponse( array $response ) {
184 return $response[0]['query']['watchlist'];
185 }
186
187 /**
188 * Convenience method to assert that actual items array fetched from API is equal to the expected
189 * array, Unlike assertEquals this only checks if values of specified keys are equal in both
190 * arrays. This could be used e.g. not to compare IDs that could change between test run
191 * but only stable keys.
192 * Optionally this also checks that specified keys are present in the actual item without
193 * performing any checks on the related values.
194 *
195 * @param array $actualItems array of actual items (associative arrays)
196 * @param array $expectedItems array of expected items (associative arrays),
197 * those items have less keys than actual items
198 * @param array $keysUsedInValueComparison list of keys of the actual item that will be used
199 * in the comparison of values
200 * @param array $requiredKeys optional, list of keys that must be present in the
201 * actual items. Values of those keys are not checked.
202 */
203 private function assertArraySubsetsEqual(
204 array $actualItems,
205 array $expectedItems,
206 array $keysUsedInValueComparison,
207 array $requiredKeys = []
208 ) {
209 $this->assertCount( count( $expectedItems ), $actualItems );
210
211 // not checking values of all keys of the actual item, so removing unwanted keys from comparison
212 $actualItemsOnlyComparedValues = array_map(
213 function ( array $item ) use ( $keysUsedInValueComparison ) {
214 return array_intersect_key( $item, array_flip( $keysUsedInValueComparison ) );
215 },
216 $actualItems
217 );
218
219 $this->assertEquals(
220 $expectedItems,
221 $actualItemsOnlyComparedValues
222 );
223
224 // Check that each item in $actualItems contains all of keys specified in $requiredKeys
225 $actualItemsKeysOnly = array_map( 'array_keys', $actualItems );
226 foreach ( $actualItemsKeysOnly as $keysOfTheItem ) {
227 $this->assertEmpty( array_diff( $requiredKeys, $keysOfTheItem ) );
228 }
229 }
230
231 private function getTitleFormatter() {
232 return new MediaWikiTitleCodec(
233 Language::factory( 'en' ),
234 MediaWikiServices::getInstance()->getGenderCache()
235 );
236 }
237
238 private function getPrefixedText( LinkTarget $target ) {
239 $formatter = $this->getTitleFormatter();
240 return $formatter->getPrefixedText( $target );
241 }
242
243 private function cleanTestUsersWatchlist() {
244 $user = $this->getLoggedInTestUser();
245 $store = $this->getWatchedItemStore();
246 $items = $store->getWatchedItemsForUser( $user );
247 foreach ( $items as $item ) {
248 $store->removeWatch( $user, $item->getLinkTarget() );
249 }
250 }
251
252 public function testListWatchlist_returnsWatchedItemsWithRCInfo() {
253 // Clean up after previous tests that might have added something to the watchlist of
254 // the user with the same user ID as user used here as the test user
255 $this->cleanTestUsersWatchlist();
256
257 $user = $this->getLoggedInTestUser();
258 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
259 $this->doPageEdit(
260 $user,
261 $target,
262 'Some Content',
263 'Create the page'
264 );
265 $this->watchPages( $user, [ $target ] );
266
267 $result = $this->doListWatchlistRequest();
268
269 $this->assertArrayHasKey( 'query', $result[0] );
270 $this->assertArrayHasKey( 'watchlist', $result[0]['query'] );
271
272 $this->assertArraySubsetsEqual(
273 $this->getItemsFromApiResponse( $result ),
274 [
275 [
276 'type' => 'new',
277 'ns' => $target->getNamespace(),
278 'title' => $this->getPrefixedText( $target ),
279 'bot' => false,
280 'new' => true,
281 'minor' => false,
282 ]
283 ],
284 [ 'type', 'ns', 'title', 'bot', 'new', 'minor' ],
285 [ 'pageid', 'revid', 'old_revid' ]
286 );
287 }
288
289 public function testIdsPropParameter() {
290 $user = $this->getLoggedInTestUser();
291 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
292 $this->doPageEdit(
293 $user,
294 $target,
295 'Some Content',
296 'Create the page'
297 );
298 $this->watchPages( $user, [ $target ] );
299
300 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'ids', ] );
301 $items = $this->getItemsFromApiResponse( $result );
302
303 $this->assertCount( 1, $items );
304 $this->assertArrayHasKey( 'pageid', $items[0] );
305 $this->assertArrayHasKey( 'revid', $items[0] );
306 $this->assertArrayHasKey( 'old_revid', $items[0] );
307 $this->assertEquals( 'new', $items[0]['type'] );
308 }
309
310 public function testTitlePropParameter() {
311 $user = $this->getLoggedInTestUser();
312 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
313 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
314 $this->doPageEdits(
315 $user,
316 [
317 [
318 'target' => $subjectTarget,
319 'content' => 'Some Content',
320 'summary' => 'Create the page',
321 ],
322 [
323 'target' => $talkTarget,
324 'content' => 'Some Talk Page Content',
325 'summary' => 'Create Talk page',
326 ],
327 ]
328 );
329 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
330
331 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', ] );
332
333 $this->assertEquals(
334 [
335 [
336 'type' => 'new',
337 'ns' => $talkTarget->getNamespace(),
338 'title' => $this->getPrefixedText( $talkTarget ),
339 ],
340 [
341 'type' => 'new',
342 'ns' => $subjectTarget->getNamespace(),
343 'title' => $this->getPrefixedText( $subjectTarget ),
344 ],
345 ],
346 $this->getItemsFromApiResponse( $result )
347 );
348 }
349
350 public function testFlagsPropParameter() {
351 $user = $this->getLoggedInTestUser();
352 $normalEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
353 $minorEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageM' );
354 $botEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageB' );
355 $this->doPageEdits(
356 $user,
357 [
358 [
359 'target' => $normalEditTarget,
360 'content' => 'Some Content',
361 'summary' => 'Create the page',
362 ],
363 [
364 'target' => $minorEditTarget,
365 'content' => 'Some Content',
366 'summary' => 'Create the page',
367 ],
368 [
369 'target' => $minorEditTarget,
370 'content' => 'Slightly Better Content',
371 'summary' => 'Change content',
372 'minorEdit' => true,
373 ],
374 [
375 'target' => $botEditTarget,
376 'content' => 'Some Content',
377 'summary' => 'Create the page with a bot',
378 'botEdit' => true,
379 ],
380 ]
381 );
382 $this->watchPages( $user, [ $normalEditTarget, $minorEditTarget, $botEditTarget ] );
383
384 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'flags', ] );
385
386 $this->assertEquals(
387 [
388 [
389 'type' => 'new',
390 'new' => true,
391 'minor' => false,
392 'bot' => true,
393 ],
394 [
395 'type' => 'edit',
396 'new' => false,
397 'minor' => true,
398 'bot' => false,
399 ],
400 [
401 'type' => 'new',
402 'new' => true,
403 'minor' => false,
404 'bot' => false,
405 ],
406 ],
407 $this->getItemsFromApiResponse( $result )
408 );
409 }
410
411 public function testUserPropParameter() {
412 $user = $this->getLoggedInTestUser();
413 $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
414 $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
415 $this->doPageEdit(
416 $user,
417 $userEditTarget,
418 'Some Content',
419 'Create the page'
420 );
421 $this->doAnonPageEdit(
422 $anonEditTarget,
423 'Some Content',
424 'Create the page'
425 );
426 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
427
428 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'user', ] );
429
430 $this->assertEquals(
431 [
432 [
433 'type' => 'new',
434 'anon' => true,
435 'user' => User::newFromId( 0 )->getName(),
436 ],
437 [
438 'type' => 'new',
439 'user' => $user->getName(),
440 ],
441 ],
442 $this->getItemsFromApiResponse( $result )
443 );
444 }
445
446 public function testUserIdPropParameter() {
447 $user = $this->getLoggedInTestUser();
448 $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
449 $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
450 $this->doPageEdit(
451 $user,
452 $userEditTarget,
453 'Some Content',
454 'Create the page'
455 );
456 $this->doAnonPageEdit(
457 $anonEditTarget,
458 'Some Content',
459 'Create the page'
460 );
461 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
462
463 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'userid', ] );
464
465 $this->assertEquals(
466 [
467 [
468 'type' => 'new',
469 'anon' => true,
470 'user' => 0,
471 'userid' => 0,
472 ],
473 [
474 'type' => 'new',
475 'user' => $user->getId(),
476 'userid' => $user->getId(),
477 ],
478 ],
479 $this->getItemsFromApiResponse( $result )
480 );
481 }
482
483 public function testCommentPropParameter() {
484 $user = $this->getLoggedInTestUser();
485 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
486 $this->doPageEdit(
487 $user,
488 $target,
489 'Some Content',
490 'Create the <b>page</b>'
491 );
492 $this->watchPages( $user, [ $target ] );
493
494 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'comment', ] );
495
496 $this->assertEquals(
497 [
498 [
499 'type' => 'new',
500 'comment' => 'Create the <b>page</b>',
501 ],
502 ],
503 $this->getItemsFromApiResponse( $result )
504 );
505 }
506
507 public function testParsedCommentPropParameter() {
508 $user = $this->getLoggedInTestUser();
509 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
510 $this->doPageEdit(
511 $user,
512 $target,
513 'Some Content',
514 'Create the <b>page</b>'
515 );
516 $this->watchPages( $user, [ $target ] );
517
518 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'parsedcomment', ] );
519
520 $this->assertEquals(
521 [
522 [
523 'type' => 'new',
524 'parsedcomment' => 'Create the &lt;b&gt;page&lt;/b&gt;',
525 ],
526 ],
527 $this->getItemsFromApiResponse( $result )
528 );
529 }
530
531 public function testTimestampPropParameter() {
532 $user = $this->getLoggedInTestUser();
533 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
534 $this->doPageEdit(
535 $user,
536 $target,
537 'Some Content',
538 'Create the page'
539 );
540 $this->watchPages( $user, [ $target ] );
541
542 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'timestamp', ] );
543 $items = $this->getItemsFromApiResponse( $result );
544
545 $this->assertCount( 1, $items );
546 $this->assertArrayHasKey( 'timestamp', $items[0] );
547 $this->assertInternalType( 'string', $items[0]['timestamp'] );
548 }
549
550 public function testSizesPropParameter() {
551 $user = $this->getLoggedInTestUser();
552 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
553 $this->doPageEdit(
554 $user,
555 $target,
556 'Some Content',
557 'Create the page'
558 );
559 $this->watchPages( $user, [ $target ] );
560
561 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'sizes', ] );
562
563 $this->assertEquals(
564 [
565 [
566 'type' => 'new',
567 'oldlen' => 0,
568 'newlen' => 12,
569 ],
570 ],
571 $this->getItemsFromApiResponse( $result )
572 );
573 }
574
575 public function testNotificationTimestampPropParameter() {
576 $otherUser = $this->getNonLoggedInTestUser();
577 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
578 $this->doPageEdit(
579 $otherUser,
580 $target,
581 'Some Content',
582 'Create the page'
583 );
584 $store = $this->getWatchedItemStore();
585 $store->addWatch( $this->getLoggedInTestUser(), $target );
586 $store->updateNotificationTimestamp(
587 $otherUser,
588 $target,
589 '20151212010101'
590 );
591
592 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'notificationtimestamp', ] );
593
594 $this->assertEquals(
595 [
596 [
597 'type' => 'new',
598 'notificationtimestamp' => '2015-12-12T01:01:01Z',
599 ],
600 ],
601 $this->getItemsFromApiResponse( $result )
602 );
603 }
604
605 private function setupPatrolledSpecificFixtures( User $user ) {
606 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
607
608 $this->doPatrolledPageEdit(
609 $user,
610 $target,
611 'Some Content',
612 'Create the page (this gets patrolled)',
613 $user
614 );
615
616 $this->watchPages( $user, [ $target ] );
617 }
618
619 public function testPatrolPropParameter() {
620 $testUser = static::getTestSysop();
621 $user = $testUser->getUser();
622 $this->setupPatrolledSpecificFixtures( $user );
623
624 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'patrol', ], $user );
625
626 $this->assertEquals(
627 [
628 [
629 'type' => 'new',
630 'patrolled' => true,
631 'unpatrolled' => false,
632 ]
633 ],
634 $this->getItemsFromApiResponse( $result )
635 );
636 }
637
638 private function createPageAndDeleteIt( LinkTarget $target ) {
639 $this->doPageEdit(
640 $this->getLoggedInTestUser(),
641 $target,
642 'Some Content',
643 'Create the page that will be deleted'
644 );
645 $this->deletePage( $target, 'Important Reason' );
646 }
647
648 public function testLoginfoPropParameter() {
649 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
650 $this->createPageAndDeleteIt( $target );
651
652 $this->watchPages( $this->getLoggedInTestUser(), [ $target ] );
653
654 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'loginfo', ] );
655
656 $this->assertArraySubsetsEqual(
657 $this->getItemsFromApiResponse( $result ),
658 [
659 [
660 'type' => 'log',
661 'logtype' => 'delete',
662 'logaction' => 'delete',
663 'logparams' => [],
664 ],
665 ],
666 [ 'type', 'logtype', 'logaction', 'logparams' ],
667 [ 'logid' ]
668 );
669 }
670
671 public function testEmptyPropParameter() {
672 $user = $this->getLoggedInTestUser();
673 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
674 $this->doPageEdit(
675 $user,
676 $target,
677 'Some Content',
678 'Create the page'
679 );
680 $this->watchPages( $user, [ $target ] );
681
682 $result = $this->doListWatchlistRequest( [ 'wlprop' => '', ] );
683
684 $this->assertEquals(
685 [
686 [
687 'type' => 'new',
688 ]
689 ],
690 $this->getItemsFromApiResponse( $result )
691 );
692 }
693
694 public function testNamespaceParam() {
695 $user = $this->getLoggedInTestUser();
696 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
697 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
698 $this->doPageEdits(
699 $user,
700 [
701 [
702 'target' => $subjectTarget,
703 'content' => 'Some Content',
704 'summary' => 'Create the page',
705 ],
706 [
707 'target' => $talkTarget,
708 'content' => 'Some Content',
709 'summary' => 'Create the talk page',
710 ],
711 ]
712 );
713 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
714
715 $result = $this->doListWatchlistRequest( [ 'wlnamespace' => '0', ] );
716
717 $this->assertArraySubsetsEqual(
718 $this->getItemsFromApiResponse( $result ),
719 [
720 [
721 'ns' => 0,
722 'title' => $this->getPrefixedText( $subjectTarget ),
723 ],
724 ],
725 [ 'ns', 'title' ]
726 );
727 }
728
729 public function testUserParam() {
730 $user = $this->getLoggedInTestUser();
731 $otherUser = $this->getNonLoggedInTestUser();
732 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
733 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
734 $this->doPageEdit(
735 $user,
736 $subjectTarget,
737 'Some Content',
738 'Create the page'
739 );
740 $this->doPageEdit(
741 $otherUser,
742 $talkTarget,
743 'What is this page about?',
744 'Create the talk page'
745 );
746 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
747
748 $result = $this->doListWatchlistRequest( [
749 'wlprop' => 'user|title',
750 'wluser' => $otherUser->getName(),
751 ] );
752
753 $this->assertEquals(
754 [
755 [
756 'type' => 'new',
757 'ns' => $talkTarget->getNamespace(),
758 'title' => $this->getPrefixedText( $talkTarget ),
759 'user' => $otherUser->getName(),
760 ],
761 ],
762 $this->getItemsFromApiResponse( $result )
763 );
764 }
765
766 public function testExcludeUserParam() {
767 $user = $this->getLoggedInTestUser();
768 $otherUser = $this->getNonLoggedInTestUser();
769 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
770 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
771 $this->doPageEdit(
772 $user,
773 $subjectTarget,
774 'Some Content',
775 'Create the page'
776 );
777 $this->doPageEdit(
778 $otherUser,
779 $talkTarget,
780 'What is this page about?',
781 'Create the talk page'
782 );
783 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
784
785 $result = $this->doListWatchlistRequest( [
786 'wlprop' => 'user|title',
787 'wlexcludeuser' => $otherUser->getName(),
788 ] );
789
790 $this->assertEquals(
791 [
792 [
793 'type' => 'new',
794 'ns' => $subjectTarget->getNamespace(),
795 'title' => $this->getPrefixedText( $subjectTarget ),
796 'user' => $user->getName(),
797 ]
798 ],
799 $this->getItemsFromApiResponse( $result )
800 );
801 }
802
803 public function testShowMinorParams() {
804 $user = $this->getLoggedInTestUser();
805 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
806 $this->doPageEdits(
807 $user,
808 [
809 [
810 'target' => $target,
811 'content' => 'Some Content',
812 'summary' => 'Create the page',
813 ],
814 [
815 'target' => $target,
816 'content' => 'Slightly Better Content',
817 'summary' => 'Change content',
818 'minorEdit' => true,
819 ],
820 ]
821 );
822 $this->watchPages( $user, [ $target ] );
823
824 $resultMinor = $this->doListWatchlistRequest( [
825 'wlshow' => WatchedItemQueryService::FILTER_MINOR,
826 'wlprop' => 'flags'
827 ] );
828 $resultNotMinor = $this->doListWatchlistRequest( [
829 'wlshow' => WatchedItemQueryService::FILTER_NOT_MINOR, 'wlprop' => 'flags'
830 ] );
831
832 $this->assertArraySubsetsEqual(
833 $this->getItemsFromApiResponse( $resultMinor ),
834 [
835 [ 'minor' => true, ]
836 ],
837 [ 'minor' ]
838 );
839 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotMinor ) );
840 }
841
842 public function testShowBotParams() {
843 $user = $this->getLoggedInTestUser();
844 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
845 $this->doBotPageEdit(
846 $user,
847 $target,
848 'Some Content',
849 'Create the page'
850 );
851 $this->watchPages( $user, [ $target ] );
852
853 $resultBot = $this->doListWatchlistRequest( [
854 'wlshow' => WatchedItemQueryService::FILTER_BOT
855 ] );
856 $resultNotBot = $this->doListWatchlistRequest( [
857 'wlshow' => WatchedItemQueryService::FILTER_NOT_BOT
858 ] );
859
860 $this->assertArraySubsetsEqual(
861 $this->getItemsFromApiResponse( $resultBot ),
862 [
863 [ 'bot' => true ],
864 ],
865 [ 'bot' ]
866 );
867 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotBot ) );
868 }
869
870 public function testShowAnonParams() {
871 $user = $this->getLoggedInTestUser();
872 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
873 $this->doAnonPageEdit(
874 $target,
875 'Some Content',
876 'Create the page'
877 );
878 $this->watchPages( $user, [ $target ] );
879
880 $resultAnon = $this->doListWatchlistRequest( [
881 'wlprop' => 'user',
882 'wlshow' => WatchedItemQueryService::FILTER_ANON
883 ] );
884 $resultNotAnon = $this->doListWatchlistRequest( [
885 'wlprop' => 'user',
886 'wlshow' => WatchedItemQueryService::FILTER_NOT_ANON
887 ] );
888
889 $this->assertArraySubsetsEqual(
890 $this->getItemsFromApiResponse( $resultAnon ),
891 [
892 [ 'anon' => true ],
893 ],
894 [ 'anon' ]
895 );
896 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotAnon ) );
897 }
898
899 public function testShowUnreadParams() {
900 $user = $this->getLoggedInTestUser();
901 $otherUser = $this->getNonLoggedInTestUser();
902 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
903 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
904 $this->doPageEdit(
905 $user,
906 $subjectTarget,
907 'Some Content',
908 'Create the page'
909 );
910 $this->doPageEdit(
911 $otherUser,
912 $talkTarget,
913 'Some Content',
914 'Create the talk page'
915 );
916 $store = $this->getWatchedItemStore();
917 $store->addWatchBatchForUser( $user, [ $subjectTarget, $talkTarget ] );
918 $store->updateNotificationTimestamp(
919 $otherUser,
920 $talkTarget,
921 '20151212010101'
922 );
923
924 $resultUnread = $this->doListWatchlistRequest( [
925 'wlprop' => 'notificationtimestamp|title',
926 'wlshow' => WatchedItemQueryService::FILTER_UNREAD
927 ] );
928 $resultNotUnread = $this->doListWatchlistRequest( [
929 'wlprop' => 'notificationtimestamp|title',
930 'wlshow' => WatchedItemQueryService::FILTER_NOT_UNREAD
931 ] );
932
933 $this->assertEquals(
934 [
935 [
936 'type' => 'new',
937 'notificationtimestamp' => '2015-12-12T01:01:01Z',
938 'ns' => $talkTarget->getNamespace(),
939 'title' => $this->getPrefixedText( $talkTarget )
940 ]
941 ],
942 $this->getItemsFromApiResponse( $resultUnread )
943 );
944 $this->assertEquals(
945 [
946 [
947 'type' => 'new',
948 'notificationtimestamp' => '',
949 'ns' => $subjectTarget->getNamespace(),
950 'title' => $this->getPrefixedText( $subjectTarget )
951 ]
952 ],
953 $this->getItemsFromApiResponse( $resultNotUnread )
954 );
955 }
956
957 public function testShowPatrolledParams() {
958 $user = static::getTestSysop()->getUser();
959 $this->setupPatrolledSpecificFixtures( $user );
960
961 $resultPatrolled = $this->doListWatchlistRequest( [
962 'wlprop' => 'patrol',
963 'wlshow' => WatchedItemQueryService::FILTER_PATROLLED
964 ], $user );
965 $resultNotPatrolled = $this->doListWatchlistRequest( [
966 'wlprop' => 'patrol',
967 'wlshow' => WatchedItemQueryService::FILTER_NOT_PATROLLED
968 ], $user );
969
970 $this->assertEquals(
971 [
972 [
973 'type' => 'new',
974 'patrolled' => true,
975 'unpatrolled' => false,
976 ]
977 ],
978 $this->getItemsFromApiResponse( $resultPatrolled )
979 );
980 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotPatrolled ) );
981 }
982
983 public function testNewAndEditTypeParameters() {
984 $user = $this->getLoggedInTestUser();
985 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
986 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
987 $this->doPageEdits(
988 $user,
989 [
990 [
991 'target' => $subjectTarget,
992 'content' => 'Some Content',
993 'summary' => 'Create the page',
994 ],
995 [
996 'target' => $subjectTarget,
997 'content' => 'Some Other Content',
998 'summary' => 'Change the content',
999 ],
1000 [
1001 'target' => $talkTarget,
1002 'content' => 'Some Talk Page Content',
1003 'summary' => 'Create Talk page',
1004 ],
1005 ]
1006 );
1007 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1008
1009 $resultNew = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'new' ] );
1010 $resultEdit = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'edit' ] );
1011
1012 $this->assertEquals(
1013 [
1014 [
1015 'type' => 'new',
1016 'ns' => $talkTarget->getNamespace(),
1017 'title' => $this->getPrefixedText( $talkTarget ),
1018 ],
1019 ],
1020 $this->getItemsFromApiResponse( $resultNew )
1021 );
1022 $this->assertEquals(
1023 [
1024 [
1025 'type' => 'edit',
1026 'ns' => $subjectTarget->getNamespace(),
1027 'title' => $this->getPrefixedText( $subjectTarget ),
1028 ],
1029 ],
1030 $this->getItemsFromApiResponse( $resultEdit )
1031 );
1032 }
1033
1034 public function testLogTypeParameters() {
1035 $user = $this->getLoggedInTestUser();
1036 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1037 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1038 $this->createPageAndDeleteIt( $subjectTarget );
1039 $this->doPageEdit(
1040 $user,
1041 $talkTarget,
1042 'Some Talk Page Content',
1043 'Create Talk page'
1044 );
1045 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1046
1047 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'log' ] );
1048
1049 $this->assertEquals(
1050 [
1051 [
1052 'type' => 'log',
1053 'ns' => $subjectTarget->getNamespace(),
1054 'title' => $this->getPrefixedText( $subjectTarget ),
1055 ],
1056 ],
1057 $this->getItemsFromApiResponse( $result )
1058 );
1059 }
1060
1061 private function getExternalRC( LinkTarget $target ) {
1062 $title = Title::newFromLinkTarget( $target );
1063
1064 $rc = new RecentChange;
1065 $rc->mTitle = $title;
1066 $rc->mAttribs = [
1067 'rc_timestamp' => wfTimestamp( TS_MW ),
1068 'rc_namespace' => $title->getNamespace(),
1069 'rc_title' => $title->getDBkey(),
1070 'rc_type' => RC_EXTERNAL,
1071 'rc_source' => 'foo',
1072 'rc_minor' => 0,
1073 'rc_cur_id' => $title->getArticleID(),
1074 'rc_user' => 0,
1075 'rc_user_text' => 'ext>External User',
1076 'rc_comment' => '',
1077 'rc_comment_text' => '',
1078 'rc_comment_data' => null,
1079 'rc_this_oldid' => $title->getLatestRevID(),
1080 'rc_last_oldid' => $title->getLatestRevID(),
1081 'rc_bot' => 0,
1082 'rc_ip' => '',
1083 'rc_patrolled' => 0,
1084 'rc_new' => 0,
1085 'rc_old_len' => $title->getLength(),
1086 'rc_new_len' => $title->getLength(),
1087 'rc_deleted' => 0,
1088 'rc_logid' => 0,
1089 'rc_log_type' => null,
1090 'rc_log_action' => '',
1091 'rc_params' => '',
1092 ];
1093 $rc->mExtra = [
1094 'prefixedDBkey' => $title->getPrefixedDBkey(),
1095 'lastTimestamp' => 0,
1096 'oldSize' => $title->getLength(),
1097 'newSize' => $title->getLength(),
1098 'pageStatus' => 'changed'
1099 ];
1100
1101 return $rc;
1102 }
1103
1104 public function testExternalTypeParameters() {
1105 $user = $this->getLoggedInTestUser();
1106 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1107 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1108 $this->doPageEdit(
1109 $user,
1110 $subjectTarget,
1111 'Some Content',
1112 'Create the page'
1113 );
1114 $this->doPageEdit(
1115 $user,
1116 $talkTarget,
1117 'Some Talk Page Content',
1118 'Create Talk page'
1119 );
1120
1121 $rc = $this->getExternalRC( $subjectTarget );
1122 $rc->save();
1123
1124 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1125
1126 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'external' ] );
1127
1128 $this->assertEquals(
1129 [
1130 [
1131 'type' => 'external',
1132 'ns' => $subjectTarget->getNamespace(),
1133 'title' => $this->getPrefixedText( $subjectTarget ),
1134 ],
1135 ],
1136 $this->getItemsFromApiResponse( $result )
1137 );
1138 }
1139
1140 public function testCategorizeTypeParameter() {
1141 $user = $this->getLoggedInTestUser();
1142 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1143 $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryWatchlistIntegrationTestCategory' );
1144 $this->doPageEdits(
1145 $user,
1146 [
1147 [
1148 'target' => $categoryTarget,
1149 'content' => 'Some Content',
1150 'summary' => 'Create the category',
1151 ],
1152 [
1153 'target' => $subjectTarget,
1154 'content' => 'Some Content [[Category:ApiQueryWatchlistIntegrationTestCategory]]t',
1155 'summary' => 'Create the page and add it to the category',
1156 ],
1157 ]
1158 );
1159 $title = Title::newFromLinkTarget( $subjectTarget );
1160 $revision = Revision::newFromTitle( $title );
1161
1162 $rc = RecentChange::newForCategorization(
1163 $revision->getTimestamp(),
1164 Title::newFromLinkTarget( $categoryTarget ),
1165 $user,
1166 $revision->getComment(),
1167 $title,
1168 0,
1169 $revision->getId(),
1170 null,
1171 false
1172 );
1173 $rc->save();
1174
1175 $this->watchPages( $user, [ $subjectTarget, $categoryTarget ] );
1176
1177 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'categorize' ] );
1178
1179 $this->assertEquals(
1180 [
1181 [
1182 'type' => 'categorize',
1183 'ns' => $categoryTarget->getNamespace(),
1184 'title' => $this->getPrefixedText( $categoryTarget ),
1185 ],
1186 ],
1187 $this->getItemsFromApiResponse( $result )
1188 );
1189 }
1190
1191 public function testLimitParam() {
1192 $user = $this->getLoggedInTestUser();
1193 $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1194 $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1195 $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
1196 $this->doPageEdits(
1197 $user,
1198 [
1199 [
1200 'target' => $target1,
1201 'content' => 'Some Content',
1202 'summary' => 'Create the page',
1203 ],
1204 [
1205 'target' => $target2,
1206 'content' => 'Some Talk Page Content',
1207 'summary' => 'Create Talk page',
1208 ],
1209 [
1210 'target' => $target3,
1211 'content' => 'Some Other Content',
1212 'summary' => 'Create the page',
1213 ],
1214 ]
1215 );
1216 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1217
1218 $resultWithoutLimit = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1219 $resultWithLimit = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1220
1221 $this->assertEquals(
1222 [
1223 [
1224 'type' => 'new',
1225 'ns' => $target3->getNamespace(),
1226 'title' => $this->getPrefixedText( $target3 )
1227 ],
1228 [
1229 'type' => 'new',
1230 'ns' => $target2->getNamespace(),
1231 'title' => $this->getPrefixedText( $target2 )
1232 ],
1233 [
1234 'type' => 'new',
1235 'ns' => $target1->getNamespace(),
1236 'title' => $this->getPrefixedText( $target1 )
1237 ],
1238 ],
1239 $this->getItemsFromApiResponse( $resultWithoutLimit )
1240 );
1241 $this->assertEquals(
1242 [
1243 [
1244 'type' => 'new',
1245 'ns' => $target3->getNamespace(),
1246 'title' => $this->getPrefixedText( $target3 )
1247 ],
1248 [
1249 'type' => 'new',
1250 'ns' => $target2->getNamespace(),
1251 'title' => $this->getPrefixedText( $target2 )
1252 ],
1253 ],
1254 $this->getItemsFromApiResponse( $resultWithLimit )
1255 );
1256 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
1257 $this->assertArrayHasKey( 'wlcontinue', $resultWithLimit[0]['continue'] );
1258 }
1259
1260 public function testAllRevParam() {
1261 $user = $this->getLoggedInTestUser();
1262 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1263 $this->doPageEdits(
1264 $user,
1265 [
1266 [
1267 'target' => $target,
1268 'content' => 'Some Content',
1269 'summary' => 'Create the page',
1270 ],
1271 [
1272 'target' => $target,
1273 'content' => 'Some Other Content',
1274 'summary' => 'Change the content',
1275 ],
1276 ]
1277 );
1278 $this->watchPages( $user, [ $target ] );
1279
1280 $resultAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wlallrev' => '', ] );
1281 $resultNoAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1282
1283 $this->assertEquals(
1284 [
1285 [
1286 'type' => 'edit',
1287 'ns' => $target->getNamespace(),
1288 'title' => $this->getPrefixedText( $target ),
1289 ],
1290 ],
1291 $this->getItemsFromApiResponse( $resultNoAllRev )
1292 );
1293 $this->assertEquals(
1294 [
1295 [
1296 'type' => 'edit',
1297 'ns' => $target->getNamespace(),
1298 'title' => $this->getPrefixedText( $target ),
1299 ],
1300 [
1301 'type' => 'new',
1302 'ns' => $target->getNamespace(),
1303 'title' => $this->getPrefixedText( $target ),
1304 ],
1305 ],
1306 $this->getItemsFromApiResponse( $resultAllRev )
1307 );
1308 }
1309
1310 public function testDirParams() {
1311 $user = $this->getLoggedInTestUser();
1312 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1313 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1314 $this->doPageEdits(
1315 $user,
1316 [
1317 [
1318 'target' => $subjectTarget,
1319 'content' => 'Some Content',
1320 'summary' => 'Create the page',
1321 ],
1322 [
1323 'target' => $talkTarget,
1324 'content' => 'Some Talk Page Content',
1325 'summary' => 'Create Talk page',
1326 ],
1327 ]
1328 );
1329 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1330
1331 $resultDirOlder = $this->doListWatchlistRequest( [ 'wldir' => 'older', 'wlprop' => 'title' ] );
1332 $resultDirNewer = $this->doListWatchlistRequest( [ 'wldir' => 'newer', 'wlprop' => 'title' ] );
1333
1334 $this->assertEquals(
1335 [
1336 [
1337 'type' => 'new',
1338 'ns' => $talkTarget->getNamespace(),
1339 'title' => $this->getPrefixedText( $talkTarget )
1340 ],
1341 [
1342 'type' => 'new',
1343 'ns' => $subjectTarget->getNamespace(),
1344 'title' => $this->getPrefixedText( $subjectTarget )
1345 ],
1346 ],
1347 $this->getItemsFromApiResponse( $resultDirOlder )
1348 );
1349 $this->assertEquals(
1350 [
1351 [
1352 'type' => 'new',
1353 'ns' => $subjectTarget->getNamespace(),
1354 'title' => $this->getPrefixedText( $subjectTarget )
1355 ],
1356 [
1357 'type' => 'new',
1358 'ns' => $talkTarget->getNamespace(),
1359 'title' => $this->getPrefixedText( $talkTarget )
1360 ],
1361 ],
1362 $this->getItemsFromApiResponse( $resultDirNewer )
1363 );
1364 }
1365
1366 public function testStartEndParams() {
1367 $user = $this->getLoggedInTestUser();
1368 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1369 $this->doPageEdit(
1370 $user,
1371 $target,
1372 'Some Content',
1373 'Create the page'
1374 );
1375 $this->watchPages( $user, [ $target ] );
1376
1377 $resultStart = $this->doListWatchlistRequest( [
1378 'wlstart' => '20010115000000',
1379 'wldir' => 'newer',
1380 'wlprop' => 'title',
1381 ] );
1382 $resultEnd = $this->doListWatchlistRequest( [
1383 'wlend' => '20010115000000',
1384 'wldir' => 'newer',
1385 'wlprop' => 'title',
1386 ] );
1387
1388 $this->assertEquals(
1389 [
1390 [
1391 'type' => 'new',
1392 'ns' => $target->getNamespace(),
1393 'title' => $this->getPrefixedText( $target ),
1394 ]
1395 ],
1396 $this->getItemsFromApiResponse( $resultStart )
1397 );
1398 $this->assertEmpty( $this->getItemsFromApiResponse( $resultEnd ) );
1399 }
1400
1401 public function testContinueParam() {
1402 $user = $this->getLoggedInTestUser();
1403 $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1404 $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1405 $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
1406 $this->doPageEdits(
1407 $user,
1408 [
1409 [
1410 'target' => $target1,
1411 'content' => 'Some Content',
1412 'summary' => 'Create the page',
1413 ],
1414 [
1415 'target' => $target2,
1416 'content' => 'Some Talk Page Content',
1417 'summary' => 'Create Talk page',
1418 ],
1419 [
1420 'target' => $target3,
1421 'content' => 'Some Other Content',
1422 'summary' => 'Create the page',
1423 ],
1424 ]
1425 );
1426 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1427
1428 $firstResult = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1429 $this->assertArrayHasKey( 'continue', $firstResult[0] );
1430 $this->assertArrayHasKey( 'wlcontinue', $firstResult[0]['continue'] );
1431
1432 $continuationParam = $firstResult[0]['continue']['wlcontinue'];
1433
1434 $continuedResult = $this->doListWatchlistRequest(
1435 [ 'wlcontinue' => $continuationParam, 'wlprop' => 'title' ]
1436 );
1437
1438 $this->assertEquals(
1439 [
1440 [
1441 'type' => 'new',
1442 'ns' => $target3->getNamespace(),
1443 'title' => $this->getPrefixedText( $target3 ),
1444 ],
1445 [
1446 'type' => 'new',
1447 'ns' => $target2->getNamespace(),
1448 'title' => $this->getPrefixedText( $target2 ),
1449 ],
1450 ],
1451 $this->getItemsFromApiResponse( $firstResult )
1452 );
1453 $this->assertEquals(
1454 [
1455 [
1456 'type' => 'new',
1457 'ns' => $target1->getNamespace(),
1458 'title' => $this->getPrefixedText( $target1 )
1459 ]
1460 ],
1461 $this->getItemsFromApiResponse( $continuedResult )
1462 );
1463 }
1464
1465 public function testOwnerAndTokenParams() {
1466 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1467 $this->doPageEdit(
1468 $this->getLoggedInTestUser(),
1469 $target,
1470 'Some Content',
1471 'Create the page'
1472 );
1473
1474 $otherUser = $this->getNonLoggedInTestUser();
1475 $otherUser->setOption( 'watchlisttoken', '1234567890' );
1476 $otherUser->saveSettings();
1477
1478 $this->watchPages( $otherUser, [ $target ] );
1479
1480 $reloadedUser = User::newFromName( $otherUser->getName() );
1481 $this->assertEquals( '1234567890', $reloadedUser->getOption( 'watchlisttoken' ) );
1482
1483 $result = $this->doListWatchlistRequest( [
1484 'wlowner' => $otherUser->getName(),
1485 'wltoken' => '1234567890',
1486 'wlprop' => 'title',
1487 ] );
1488
1489 $this->assertEquals(
1490 [
1491 [
1492 'type' => 'new',
1493 'ns' => $target->getNamespace(),
1494 'title' => $this->getPrefixedText( $target )
1495 ]
1496 ],
1497 $this->getItemsFromApiResponse( $result )
1498 );
1499 }
1500
1501 public function testOwnerAndTokenParams_wrongToken() {
1502 $otherUser = $this->getNonLoggedInTestUser();
1503 $otherUser->setOption( 'watchlisttoken', '1234567890' );
1504 $otherUser->saveSettings();
1505
1506 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
1507
1508 $this->doListWatchlistRequest( [
1509 'wlowner' => $otherUser->getName(),
1510 'wltoken' => 'wrong-token',
1511 ] );
1512 }
1513
1514 public function testOwnerAndTokenParams_noWatchlistTokenSet() {
1515 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
1516
1517 $this->doListWatchlistRequest( [
1518 'wlowner' => $this->getNonLoggedInTestUser()->getName(),
1519 'wltoken' => 'some-token',
1520 ] );
1521 }
1522
1523 public function testGeneratorWatchlistPropInfo_returnsWatchedPages() {
1524 $user = $this->getLoggedInTestUser();
1525 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1526 $this->doPageEdit(
1527 $user,
1528 $target,
1529 'Some Content',
1530 'Create the page'
1531 );
1532 $this->watchPages( $user, [ $target ] );
1533
1534 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'info' ] );
1535
1536 $this->assertArrayHasKey( 'query', $result[0] );
1537 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1538
1539 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1540 $pages = array_values( $result[0]['query']['pages'] );
1541
1542 $this->assertArraySubsetsEqual(
1543 $pages,
1544 [
1545 [
1546 'ns' => $target->getNamespace(),
1547 'title' => $this->getPrefixedText( $target ),
1548 'new' => true,
1549 ]
1550 ],
1551 [ 'ns', 'title', 'new' ]
1552 );
1553 }
1554
1555 public function testGeneratorWatchlistPropRevisions_returnsWatchedItemsRevisions() {
1556 $user = $this->getLoggedInTestUser();
1557 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1558 $this->doPageEdits(
1559 $user,
1560 [
1561 [
1562 'target' => $target,
1563 'content' => 'Some Content',
1564 'summary' => 'Create the page',
1565 ],
1566 [
1567 'target' => $target,
1568 'content' => 'Some Other Content',
1569 'summary' => 'Change the content',
1570 ],
1571 ]
1572 );
1573 $this->watchPages( $user, [ $target ] );
1574
1575 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'revisions', 'gwlallrev' => '' ] );
1576
1577 $this->assertArrayHasKey( 'query', $result[0] );
1578 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1579
1580 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1581 $pages = array_values( $result[0]['query']['pages'] );
1582
1583 $this->assertCount( 1, $pages );
1584 $this->assertEquals( 0, $pages[0]['ns'] );
1585 $this->assertEquals( $this->getPrefixedText( $target ), $pages[0]['title'] );
1586 $this->assertArraySubsetsEqual(
1587 $pages[0]['revisions'],
1588 [
1589 [
1590 'comment' => 'Create the page',
1591 'user' => $user->getName(),
1592 'minor' => false,
1593 ],
1594 [
1595 'comment' => 'Change the content',
1596 'user' => $user->getName(),
1597 'minor' => false,
1598 ],
1599 ],
1600 [ 'comment', 'user', 'minor' ]
1601 );
1602 }
1603
1604 }