Merge "Remove use of BagOStuff TTL constants from unrelated code"
[mediawiki.git] / tests / phpunit / includes / api / query / ApiQueryWatchlistIntegrationTest.php
blob11288dd5ae3e140d5cb6b20ac6862defa529f912
1 <?php
3 namespace MediaWiki\Tests\Api\Query;
5 use MediaWiki\CommentStore\CommentStoreComment;
6 use MediaWiki\Linker\LinkTarget;
7 use MediaWiki\Permissions\Authority;
8 use MediaWiki\Request\FauxRequest;
9 use MediaWiki\Revision\SlotRecord;
10 use MediaWiki\Tests\Api\ApiTestCase;
11 use MediaWiki\Tests\User\TempUser\TempUserTestTrait;
12 use MediaWiki\Title\TitleValue;
13 use MediaWiki\User\User;
14 use MediaWiki\Watchlist\WatchedItemQueryService;
15 use RecentChange;
17 /**
18 * @group medium
19 * @group API
20 * @group Database
22 * @covers \MediaWiki\Api\ApiQueryWatchlist
23 * @covers \MediaWiki\Watchlist\WatchedItemQueryService
25 class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
26 use TempUserTestTrait;
28 // TODO: This test should use Authority, but can't due to User::saveSettings
30 /** @var User */
31 private $loggedInUser;
32 /** @var User */
33 private $notLoggedInUser;
35 protected function setUp(): void {
36 parent::setUp();
38 $this->loggedInUser = $this->getMutableTestUser()->getUser();
39 $this->notLoggedInUser = $this->getMutableTestUser()->getUser();
42 private function getLoggedInTestUser(): User {
43 return $this->loggedInUser;
46 private function getNonLoggedInTestUser(): User {
47 return $this->notLoggedInUser;
50 private function doPageEdit( Authority $performer, $target, $content, $summary ) {
51 $this->editPage(
52 $target,
53 $content,
54 $summary,
55 NS_MAIN,
56 $performer
60 private function doMinorPageEdit( User $user, LinkTarget $target, $content, $summary ) {
61 $page = $this->getServiceContainer()->getWikiPageFactory()->newFromLinkTarget( $target );
62 $page->doUserEditContent(
63 $page->getContentHandler()->unserializeContent( $content ),
64 $user,
65 $summary,
66 EDIT_MINOR
70 private function doBotPageEdit( User $user, LinkTarget $target, $content, $summary ) {
71 $page = $this->getServiceContainer()->getWikiPageFactory()->newFromLinkTarget( $target );
72 $page->doUserEditContent(
73 $page->getContentHandler()->unserializeContent( $content ),
74 $user,
75 $summary,
76 EDIT_FORCE_BOT
80 private function doAnonPageEdit( LinkTarget $target, $content, $summary ) {
81 $this->disableAutoCreateTempUser();
82 $this->editPage(
83 $target,
84 $content,
85 $summary,
86 NS_MAIN,
87 $this->getServiceContainer()->getUserFactory()->newAnonymous()
91 private function doTempPageEdit( LinkTarget $target, $content, $summary ) {
92 $this->enableAutoCreateTempUser();
93 $this->editPage(
94 $target,
95 $content,
96 $summary,
97 NS_MAIN,
98 $this->getServiceContainer()->getTempUserCreator()->create( null, new FauxRequest() )->getUser()
102 private function doPatrolledPageEdit(
103 User $user,
104 LinkTarget $target,
105 $content,
106 $summary,
107 User $patrollingUser
109 $summary = CommentStoreComment::newUnsavedComment( trim( $summary ) );
110 $page = $this->getServiceContainer()->getWikiPageFactory()->newFromLinkTarget( $target );
112 $updater = $page->newPageUpdater( $user );
113 $updater->setContent( SlotRecord::MAIN, $page->getContentHandler()->unserializeContent( $content ) );
114 $rev = $updater->saveRevision( $summary );
116 $rc = $this->getServiceContainer()->getRevisionStore()->getRecentChange( $rev );
117 $rc->markPatrolled( $patrollingUser, [] );
121 * Performs a batch of page edits as a specified user
122 * @param User $user
123 * @param array $editData associative array, keys:
124 * - target => LinkTarget page to edit
125 * - content => string new content
126 * - summary => string edit summary
127 * - minorEdit => bool mark as minor edit if true (defaults to false)
128 * - botEdit => bool mark as bot edit if true (defaults to false)
130 private function doPageEdits( User $user, array $editData ) {
131 foreach ( $editData as $singleEditData ) {
132 if ( array_key_exists( 'minorEdit', $singleEditData ) && $singleEditData['minorEdit'] ) {
133 $this->doMinorPageEdit(
134 $user,
135 $singleEditData['target'],
136 $singleEditData['content'],
137 $singleEditData['summary']
139 continue;
141 if ( array_key_exists( 'botEdit', $singleEditData ) && $singleEditData['botEdit'] ) {
142 $this->doBotPageEdit(
143 $user,
144 $singleEditData['target'],
145 $singleEditData['content'],
146 $singleEditData['summary']
148 continue;
150 $this->doPageEdit(
151 $user,
152 $singleEditData['target'],
153 $singleEditData['content'],
154 $singleEditData['summary']
159 private function getWatchedItemStore() {
160 return $this->getServiceContainer()->getWatchedItemStore();
164 * @param User $user
165 * @param LinkTarget[] $targets
167 private function watchPages( User $user, array $targets ) {
168 $store = $this->getWatchedItemStore();
169 $store->addWatchBatchForUser( $user, $targets );
172 private function doListWatchlistRequest( array $params = [], $user = null ) {
173 $user ??= $this->getLoggedInTestUser();
174 return $this->doApiRequest(
175 array_merge(
176 [ 'action' => 'query', 'list' => 'watchlist' ],
177 $params
178 ), null, false, $user
182 private function doGeneratorWatchlistRequest( array $params = [] ) {
183 return $this->doApiRequest(
184 array_merge(
185 [ 'action' => 'query', 'generator' => 'watchlist' ],
186 $params
187 ), null, false, $this->getLoggedInTestUser()
191 private function getItemsFromApiResponse( array $response ) {
192 return $response[0]['query']['watchlist'];
196 * Convenience method to assert that actual items array fetched from API is equal to the expected
197 * array, Unlike assertEquals this only checks if values of specified keys are equal in both
198 * arrays. This could be used e.g. not to compare IDs that could change between test run
199 * but only stable keys.
200 * Optionally this also checks that specified keys are present in the actual item without
201 * performing any checks on the related values.
203 * @param array $actualItems array of actual items (associative arrays)
204 * @param array $expectedItems array of expected items (associative arrays),
205 * those items have less keys than actual items
206 * @param array $keysUsedInValueComparison list of keys of the actual item that will be used
207 * in the comparison of values
208 * @param array $requiredKeys optional, list of keys that must be present in the
209 * actual items. Values of those keys are not checked.
211 private function assertArraySubsetsEqual(
212 array $actualItems,
213 array $expectedItems,
214 array $keysUsedInValueComparison,
215 array $requiredKeys = []
217 $this->assertSameSize( $expectedItems, $actualItems );
219 // not checking values of all keys of the actual item, so removing unwanted keys from comparison
220 $actualItemsOnlyComparedValues = array_map(
221 static function ( array $item ) use ( $keysUsedInValueComparison ) {
222 return array_intersect_key( $item,
223 array_fill_keys( $keysUsedInValueComparison, true ) );
225 $actualItems
228 $this->assertEquals(
229 $expectedItems,
230 $actualItemsOnlyComparedValues
233 // Check that each item in $actualItems contains all of keys specified in $requiredKeys
234 $actualItemsKeysOnly = array_map( 'array_keys', $actualItems );
235 foreach ( $actualItemsKeysOnly as $keysOfTheItem ) {
236 $this->assertSame( [], array_diff( $requiredKeys, $keysOfTheItem ) );
240 private function getPrefixedText( LinkTarget $target ) {
241 return $this->getServiceContainer()->getTitleFormatter()->getPrefixedText( $target );
244 private function cleanTestUsersWatchlist() {
245 $user = $this->getLoggedInTestUser();
246 $store = $this->getWatchedItemStore();
247 $items = $store->getWatchedItemsForUser( $user );
248 foreach ( $items as $item ) {
249 $store->removeWatch( $user, $item->getTarget() );
253 public function testListWatchlist_returnsWatchedItemsWithRCInfo() {
254 // Clean up after previous tests that might have added something to the watchlist of
255 // the user with the same user ID as user used here as the test user
256 $this->cleanTestUsersWatchlist();
258 $user = $this->getLoggedInTestUser();
259 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
260 $this->doPageEdit(
261 $user,
262 $target,
263 'Some Content',
264 'Create the page'
266 $this->watchPages( $user, [ $target ] );
268 $result = $this->doListWatchlistRequest();
270 $this->assertArrayHasKey( 'query', $result[0] );
271 $this->assertArrayHasKey( 'watchlist', $result[0]['query'] );
273 $this->assertArraySubsetsEqual(
274 $this->getItemsFromApiResponse( $result ),
277 'type' => 'new',
278 'ns' => $target->getNamespace(),
279 'title' => $this->getPrefixedText( $target ),
280 'bot' => false,
281 'new' => true,
282 'minor' => false,
285 [ 'type', 'ns', 'title', 'bot', 'new', 'minor' ],
286 [ 'pageid', 'revid', 'old_revid' ]
290 public function testIdsPropParameter() {
291 $user = $this->getLoggedInTestUser();
292 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
293 $this->doPageEdit(
294 $user,
295 $target,
296 'Some Content',
297 'Create the page'
299 $this->watchPages( $user, [ $target ] );
301 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'ids', ] );
302 $items = $this->getItemsFromApiResponse( $result );
304 $this->assertCount( 1, $items );
305 $this->assertArrayHasKey( 'pageid', $items[0] );
306 $this->assertArrayHasKey( 'revid', $items[0] );
307 $this->assertArrayHasKey( 'old_revid', $items[0] );
308 $this->assertEquals( 'new', $items[0]['type'] );
311 public function testTitlePropParameter() {
312 $user = $this->getLoggedInTestUser();
313 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
314 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
315 $this->doPageEdits(
316 $user,
319 'target' => $subjectTarget,
320 'content' => 'Some Content',
321 'summary' => 'Create the page',
324 'target' => $talkTarget,
325 'content' => 'Some Talk Page Content',
326 'summary' => 'Create Talk page',
330 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
332 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', ] );
334 $this->assertEquals(
337 'type' => 'new',
338 'ns' => $talkTarget->getNamespace(),
339 'title' => $this->getPrefixedText( $talkTarget ),
342 'type' => 'new',
343 'ns' => $subjectTarget->getNamespace(),
344 'title' => $this->getPrefixedText( $subjectTarget ),
347 $this->getItemsFromApiResponse( $result )
351 public function testFlagsPropParameter() {
352 $user = $this->getLoggedInTestUser();
353 $normalEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
354 $minorEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPageM' );
355 $botEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPageB' );
356 $this->doPageEdits(
357 $user,
360 'target' => $normalEditTarget,
361 'content' => 'Some Content',
362 'summary' => 'Create the page',
365 'target' => $minorEditTarget,
366 'content' => 'Some Content',
367 'summary' => 'Create the page',
370 'target' => $minorEditTarget,
371 'content' => 'Slightly Better Content',
372 'summary' => 'Change content',
373 'minorEdit' => true,
376 'target' => $botEditTarget,
377 'content' => 'Some Content',
378 'summary' => 'Create the page with a bot',
379 'botEdit' => true,
383 $this->watchPages( $user, [ $normalEditTarget, $minorEditTarget, $botEditTarget ] );
385 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'flags', ] );
387 $this->assertEquals(
390 'type' => 'new',
391 'new' => true,
392 'minor' => false,
393 'bot' => true,
396 'type' => 'edit',
397 'new' => false,
398 'minor' => true,
399 'bot' => false,
402 'type' => 'new',
403 'new' => true,
404 'minor' => false,
405 'bot' => false,
408 $this->getItemsFromApiResponse( $result )
412 public function testUserPropParameter() {
413 $user = $this->getLoggedInTestUser();
414 $userEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
415 $anonEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPageA' );
416 $this->doPageEdit(
417 $user,
418 $userEditTarget,
419 'Some Content',
420 'Create the page'
422 $this->doAnonPageEdit(
423 $anonEditTarget,
424 'Some Content',
425 'Create the page'
427 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
429 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'user', ] );
431 $this->assertEquals(
434 'type' => 'new',
435 'anon' => true,
436 'temp' => false,
437 'user' => $this->getServiceContainer()->getUserFactory()->newAnonymous()->getName(),
440 'type' => 'new',
441 'anon' => false,
442 'temp' => false,
443 'user' => $user->getName(),
446 $this->getItemsFromApiResponse( $result )
450 public function testUserIdPropParameter() {
451 $user = $this->getLoggedInTestUser();
452 $userEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
453 $anonEditTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPageA' );
454 $this->doPageEdit(
455 $user,
456 $userEditTarget,
457 'Some Content',
458 'Create the page'
460 $this->doAnonPageEdit(
461 $anonEditTarget,
462 'Some Content',
463 'Create the page'
465 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
467 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'userid', ] );
469 $this->assertEquals(
472 'type' => 'new',
473 'anon' => true,
474 'user' => 0,
475 'userid' => 0,
478 'type' => 'new',
479 'anon' => false,
480 'user' => $user->getId(),
481 'userid' => $user->getId(),
484 $this->getItemsFromApiResponse( $result )
488 public function testCommentPropParameter() {
489 $user = $this->getLoggedInTestUser();
490 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
491 $this->doPageEdit(
492 $user,
493 $target,
494 'Some Content',
495 'Create the <b>page</b>'
497 $this->watchPages( $user, [ $target ] );
499 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'comment', ] );
501 $this->assertEquals(
504 'type' => 'new',
505 'comment' => 'Create the <b>page</b>',
508 $this->getItemsFromApiResponse( $result )
512 public function testParsedCommentPropParameter() {
513 $user = $this->getLoggedInTestUser();
514 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
515 $this->doPageEdit(
516 $user,
517 $target,
518 'Some Content',
519 'Create the <b>page</b>'
521 $this->watchPages( $user, [ $target ] );
523 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'parsedcomment', ] );
525 $this->assertEquals(
528 'type' => 'new',
529 'parsedcomment' => 'Create the &lt;b&gt;page&lt;/b&gt;',
532 $this->getItemsFromApiResponse( $result )
536 public function testTimestampPropParameter() {
537 $user = $this->getLoggedInTestUser();
538 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
539 $this->doPageEdit(
540 $user,
541 $target,
542 'Some Content',
543 'Create the page'
545 $this->watchPages( $user, [ $target ] );
547 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'timestamp', ] );
548 $items = $this->getItemsFromApiResponse( $result );
550 $this->assertCount( 1, $items );
551 $this->assertArrayHasKey( 'timestamp', $items[0] );
552 $this->assertIsString( $items[0]['timestamp'] );
555 public function testSizesPropParameter() {
556 $user = $this->getLoggedInTestUser();
557 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
558 $this->doPageEdit(
559 $user,
560 $target,
561 'Some Content',
562 'Create the page'
564 $this->watchPages( $user, [ $target ] );
566 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'sizes', ] );
568 $this->assertEquals(
571 'type' => 'new',
572 'oldlen' => 0,
573 'newlen' => 12,
576 $this->getItemsFromApiResponse( $result )
580 public function testNotificationTimestampPropParameter() {
581 $otherUser = $this->getNonLoggedInTestUser();
582 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
583 $this->doPageEdit(
584 $otherUser,
585 $target,
586 'Some Content',
587 'Create the page'
589 $store = $this->getWatchedItemStore();
590 $store->addWatch( $this->getLoggedInTestUser(), $target );
591 $store->updateNotificationTimestamp(
592 $otherUser,
593 $target,
594 '20151212010101'
597 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'notificationtimestamp', ] );
599 $this->assertEquals(
602 'type' => 'new',
603 'notificationtimestamp' => '2015-12-12T01:01:01Z',
606 $this->getItemsFromApiResponse( $result )
610 private function setupPatrolledSpecificFixtures( User $user ) {
611 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
613 $this->doPatrolledPageEdit(
614 $user,
615 $target,
616 'Some Content',
617 'Create the page (this gets patrolled)',
618 $user
621 $this->watchPages( $user, [ $target ] );
624 public function testPatrolPropParameter() {
625 $testUser = static::getTestSysop();
626 $user = $testUser->getUser();
627 $this->setupPatrolledSpecificFixtures( $user );
629 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'patrol', ], $user );
631 $this->assertEquals(
634 'type' => 'new',
635 'patrolled' => true,
636 'unpatrolled' => false,
637 'autopatrolled' => false,
640 $this->getItemsFromApiResponse( $result )
644 private function createPageAndDeleteIt( LinkTarget $target ) {
645 $wikiPage = $this->getServiceContainer()->getWikiPageFactory()->newFromLinkTarget( $target );
646 $this->doPageEdit(
647 $this->getLoggedInTestUser(),
648 $wikiPage,
649 'Some Content',
650 'Create the page that will be deleted'
652 $this->deletePage( $wikiPage, 'Important Reason' );
655 public function testLoginfoPropParameter() {
656 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
657 $this->createPageAndDeleteIt( $target );
659 $this->watchPages( $this->getLoggedInTestUser(), [ $target ] );
661 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'loginfo', ] );
663 $this->assertArraySubsetsEqual(
664 $this->getItemsFromApiResponse( $result ),
667 'type' => 'log',
668 'logtype' => 'delete',
669 'logaction' => 'delete',
670 'logparams' => [],
673 [ 'type', 'logtype', 'logaction', 'logparams' ],
674 [ 'logid' ]
678 public function testEmptyPropParameter() {
679 $user = $this->getLoggedInTestUser();
680 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
681 $this->doPageEdit(
682 $user,
683 $target,
684 'Some Content',
685 'Create the page'
687 $this->watchPages( $user, [ $target ] );
689 $result = $this->doListWatchlistRequest( [ 'wlprop' => '', ] );
691 $this->assertEquals(
694 'type' => 'new',
697 $this->getItemsFromApiResponse( $result )
701 public function testNamespaceParam() {
702 $user = $this->getLoggedInTestUser();
703 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
704 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
705 $this->doPageEdits(
706 $user,
709 'target' => $subjectTarget,
710 'content' => 'Some Content',
711 'summary' => 'Create the page',
714 'target' => $talkTarget,
715 'content' => 'Some Content',
716 'summary' => 'Create the talk page',
720 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
722 $result = $this->doListWatchlistRequest( [ 'wlnamespace' => NS_MAIN, ] );
724 $this->assertArraySubsetsEqual(
725 $this->getItemsFromApiResponse( $result ),
728 'ns' => $subjectTarget->getNamespace(),
729 'title' => $this->getPrefixedText( $subjectTarget ),
732 [ 'ns', 'title' ]
736 public function testUserParam() {
737 $user = $this->getLoggedInTestUser();
738 $otherUser = $this->getNonLoggedInTestUser();
739 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
740 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
741 $this->doPageEdit(
742 $user,
743 $subjectTarget,
744 'Some Content',
745 'Create the page'
747 $this->doPageEdit(
748 $otherUser,
749 $talkTarget,
750 'What is this page about?',
751 'Create the talk page'
753 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
755 $result = $this->doListWatchlistRequest( [
756 'wlprop' => 'user|title',
757 'wluser' => $otherUser->getName(),
758 ] );
760 $this->assertEquals(
763 'type' => 'new',
764 'ns' => $talkTarget->getNamespace(),
765 'title' => $this->getPrefixedText( $talkTarget ),
766 'user' => $otherUser->getName(),
767 'anon' => false,
768 'temp' => false,
771 $this->getItemsFromApiResponse( $result )
775 public function testExcludeUserParam() {
776 $user = $this->getLoggedInTestUser();
777 $otherUser = $this->getNonLoggedInTestUser();
778 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
779 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
780 $this->doPageEdit(
781 $user,
782 $subjectTarget,
783 'Some Content',
784 'Create the page'
786 $this->doPageEdit(
787 $otherUser,
788 $talkTarget,
789 'What is this page about?',
790 'Create the talk page'
792 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
794 $result = $this->doListWatchlistRequest( [
795 'wlprop' => 'user|title',
796 'wlexcludeuser' => $otherUser->getName(),
797 ] );
799 $this->assertEquals(
802 'type' => 'new',
803 'ns' => $subjectTarget->getNamespace(),
804 'title' => $this->getPrefixedText( $subjectTarget ),
805 'user' => $user->getName(),
806 'anon' => false,
807 'temp' => false,
810 $this->getItemsFromApiResponse( $result )
814 public function testShowMinorParams() {
815 $user = $this->getLoggedInTestUser();
816 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
817 $this->doPageEdits(
818 $user,
821 'target' => $target,
822 'content' => 'Some Content',
823 'summary' => 'Create the page',
826 'target' => $target,
827 'content' => 'Slightly Better Content',
828 'summary' => 'Change content',
829 'minorEdit' => true,
833 $this->watchPages( $user, [ $target ] );
835 $resultMinor = $this->doListWatchlistRequest( [
836 'wlshow' => WatchedItemQueryService::FILTER_MINOR,
837 'wlprop' => 'flags'
838 ] );
839 $resultNotMinor = $this->doListWatchlistRequest( [
840 'wlshow' => WatchedItemQueryService::FILTER_NOT_MINOR, 'wlprop' => 'flags'
841 ] );
843 $this->assertArraySubsetsEqual(
844 $this->getItemsFromApiResponse( $resultMinor ),
846 [ 'minor' => true, ]
848 [ 'minor' ]
850 $this->assertSame( [], $this->getItemsFromApiResponse( $resultNotMinor ) );
853 public function testShowBotParams() {
854 $user = $this->getLoggedInTestUser();
855 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
856 $this->doBotPageEdit(
857 $user,
858 $target,
859 'Some Content',
860 'Create the page'
862 $this->watchPages( $user, [ $target ] );
864 $resultBot = $this->doListWatchlistRequest( [
865 'wlshow' => WatchedItemQueryService::FILTER_BOT
866 ] );
867 $resultNotBot = $this->doListWatchlistRequest( [
868 'wlshow' => WatchedItemQueryService::FILTER_NOT_BOT
869 ] );
871 $this->assertArraySubsetsEqual(
872 $this->getItemsFromApiResponse( $resultBot ),
874 [ 'bot' => true ],
876 [ 'bot' ]
878 $this->assertSame( [], $this->getItemsFromApiResponse( $resultNotBot ) );
881 public function testShowAnonParams() {
882 $user = $this->getLoggedInTestUser();
883 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
884 $this->doAnonPageEdit(
885 $target,
886 'Some Content',
887 'Create the page'
889 $this->watchPages( $user, [ $target ] );
891 $resultAnon = $this->doListWatchlistRequest( [
892 'wlprop' => 'user',
893 'wlshow' => WatchedItemQueryService::FILTER_ANON
894 ] );
895 $resultNotAnon = $this->doListWatchlistRequest( [
896 'wlprop' => 'user',
897 'wlshow' => WatchedItemQueryService::FILTER_NOT_ANON
898 ] );
900 $this->assertArraySubsetsEqual(
901 $this->getItemsFromApiResponse( $resultAnon ),
904 'anon' => true,
905 'temp' => false,
908 [ 'anon', 'temp' ]
910 $this->assertSame( [], $this->getItemsFromApiResponse( $resultNotAnon ) );
913 public function testShowAnonParamsTemp() {
914 $user = $this->getLoggedInTestUser();
915 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
916 $this->doTempPageEdit(
917 $target,
918 'Some more content',
919 'Add more content'
921 $this->watchPages( $user, [ $target ] );
923 $resultAnon = $this->doListWatchlistRequest( [
924 'wlprop' => 'user',
925 'wlshow' => WatchedItemQueryService::FILTER_ANON
926 ] );
927 $resultNotAnon = $this->doListWatchlistRequest( [
928 'wlprop' => 'user',
929 'wlshow' => WatchedItemQueryService::FILTER_NOT_ANON
930 ] );
932 $this->assertArraySubsetsEqual(
933 $this->getItemsFromApiResponse( $resultAnon ),
936 'anon' => false,
937 'temp' => true
940 [ 'anon', 'temp' ]
942 $this->assertSame( [], $this->getItemsFromApiResponse( $resultNotAnon ) );
945 public function testShowUnreadParams() {
946 $user = $this->getLoggedInTestUser();
947 $otherUser = $this->getNonLoggedInTestUser();
948 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
949 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
950 $this->doPageEdit(
951 $user,
952 $subjectTarget,
953 'Some Content',
954 'Create the page'
956 $this->doPageEdit(
957 $otherUser,
958 $talkTarget,
959 'Some Content',
960 'Create the talk page'
962 $store = $this->getWatchedItemStore();
963 $store->addWatchBatchForUser( $user, [ $subjectTarget, $talkTarget ] );
964 $store->updateNotificationTimestamp(
965 $otherUser,
966 $talkTarget,
967 '20151212010101'
970 $resultUnread = $this->doListWatchlistRequest( [
971 'wlprop' => 'notificationtimestamp|title',
972 'wlshow' => WatchedItemQueryService::FILTER_UNREAD
973 ] );
974 $resultNotUnread = $this->doListWatchlistRequest( [
975 'wlprop' => 'notificationtimestamp|title',
976 'wlshow' => WatchedItemQueryService::FILTER_NOT_UNREAD
977 ] );
979 $this->assertEquals(
982 'type' => 'new',
983 'notificationtimestamp' => '2015-12-12T01:01:01Z',
984 'ns' => $talkTarget->getNamespace(),
985 'title' => $this->getPrefixedText( $talkTarget )
988 $this->getItemsFromApiResponse( $resultUnread )
990 $this->assertEquals(
993 'type' => 'new',
994 'notificationtimestamp' => '',
995 'ns' => $subjectTarget->getNamespace(),
996 'title' => $this->getPrefixedText( $subjectTarget )
999 $this->getItemsFromApiResponse( $resultNotUnread )
1003 public function testShowPatrolledParams() {
1004 $user = static::getTestSysop()->getUser();
1005 $this->setupPatrolledSpecificFixtures( $user );
1007 $resultPatrolled = $this->doListWatchlistRequest( [
1008 'wlprop' => 'patrol',
1009 'wlshow' => WatchedItemQueryService::FILTER_PATROLLED
1010 ], $user );
1011 $resultNotPatrolled = $this->doListWatchlistRequest( [
1012 'wlprop' => 'patrol',
1013 'wlshow' => WatchedItemQueryService::FILTER_NOT_PATROLLED
1014 ], $user );
1016 $this->assertEquals(
1019 'type' => 'new',
1020 'patrolled' => true,
1021 'unpatrolled' => false,
1022 'autopatrolled' => false,
1025 $this->getItemsFromApiResponse( $resultPatrolled )
1027 $this->assertSame( [], $this->getItemsFromApiResponse( $resultNotPatrolled ) );
1030 public function testNewAndEditTypeParameters() {
1031 $user = $this->getLoggedInTestUser();
1032 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1033 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1034 $this->doPageEdits(
1035 $user,
1038 'target' => $subjectTarget,
1039 'content' => 'Some Content',
1040 'summary' => 'Create the page',
1043 'target' => $subjectTarget,
1044 'content' => 'Some Other Content',
1045 'summary' => 'Change the content',
1048 'target' => $talkTarget,
1049 'content' => 'Some Talk Page Content',
1050 'summary' => 'Create Talk page',
1054 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1056 $resultNew = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'new' ] );
1057 $resultEdit = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'edit' ] );
1059 $this->assertEquals(
1062 'type' => 'new',
1063 'ns' => $talkTarget->getNamespace(),
1064 'title' => $this->getPrefixedText( $talkTarget ),
1067 $this->getItemsFromApiResponse( $resultNew )
1069 $this->assertEquals(
1072 'type' => 'edit',
1073 'ns' => $subjectTarget->getNamespace(),
1074 'title' => $this->getPrefixedText( $subjectTarget ),
1077 $this->getItemsFromApiResponse( $resultEdit )
1081 public function testLogTypeParameters() {
1082 $user = $this->getLoggedInTestUser();
1083 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1084 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1085 $this->createPageAndDeleteIt( $subjectTarget );
1086 $this->doPageEdit(
1087 $user,
1088 $talkTarget,
1089 'Some Talk Page Content',
1090 'Create Talk page'
1092 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1094 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'log' ] );
1096 $this->assertEquals(
1099 'type' => 'log',
1100 'ns' => $subjectTarget->getNamespace(),
1101 'title' => $this->getPrefixedText( $subjectTarget ),
1104 $this->getItemsFromApiResponse( $result )
1108 private function getExternalRC( LinkTarget $target ) {
1109 $title = $this->getServiceContainer()->getTitleFactory()->newFromLinkTarget( $target );
1111 $rc = new RecentChange;
1112 $rc->mAttribs = [
1113 'rc_timestamp' => wfTimestamp( TS_MW ),
1114 'rc_namespace' => $title->getNamespace(),
1115 'rc_title' => $title->getDBkey(),
1116 'rc_type' => RC_EXTERNAL,
1117 'rc_source' => 'foo',
1118 'rc_minor' => 0,
1119 'rc_cur_id' => $title->getArticleID(),
1120 'rc_user' => 0,
1121 'rc_user_text' => 'ext>External User',
1122 'rc_comment' => '',
1123 'rc_comment_text' => '',
1124 'rc_comment_data' => null,
1125 'rc_this_oldid' => $title->getLatestRevID(),
1126 'rc_last_oldid' => $title->getLatestRevID(),
1127 'rc_bot' => 0,
1128 'rc_ip' => '',
1129 'rc_patrolled' => 0,
1130 'rc_new' => 0,
1131 'rc_old_len' => $title->getLength(),
1132 'rc_new_len' => $title->getLength(),
1133 'rc_deleted' => 0,
1134 'rc_logid' => 0,
1135 'rc_log_type' => null,
1136 'rc_log_action' => '',
1137 'rc_params' => '',
1139 $rc->mExtra = [
1140 'prefixedDBkey' => $title->getPrefixedDBkey(),
1141 'lastTimestamp' => 0,
1142 'oldSize' => $title->getLength(),
1143 'newSize' => $title->getLength(),
1144 'pageStatus' => 'changed'
1147 return $rc;
1150 public function testExternalTypeParameters() {
1151 $user = $this->getLoggedInTestUser();
1152 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1153 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1154 $this->doPageEdit(
1155 $user,
1156 $subjectTarget,
1157 'Some Content',
1158 'Create the page'
1160 $this->doPageEdit(
1161 $user,
1162 $talkTarget,
1163 'Some Talk Page Content',
1164 'Create Talk page'
1167 $rc = $this->getExternalRC( $subjectTarget );
1168 $rc->save();
1170 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1172 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'external' ] );
1174 $this->assertEquals(
1177 'type' => 'external',
1178 'ns' => $subjectTarget->getNamespace(),
1179 'title' => $this->getPrefixedText( $subjectTarget ),
1182 $this->getItemsFromApiResponse( $result )
1186 public function testCategorizeTypeParameter() {
1187 $user = $this->getLoggedInTestUser();
1188 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1189 $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryWatchlistIntegrationTestCategory' );
1190 $this->doPageEdits(
1191 $user,
1194 'target' => $categoryTarget,
1195 'content' => 'Some Content',
1196 'summary' => 'Create the category',
1199 'target' => $subjectTarget,
1200 'content' => 'Some Content [[Category:ApiQueryWatchlistIntegrationTestCategory]]t',
1201 'summary' => 'Create the page and add it to the category',
1205 $title = $this->getServiceContainer()->getTitleFactory()->newFromLinkTarget( $subjectTarget );
1206 $revision = $this->getServiceContainer()
1207 ->getRevisionLookup()
1208 ->getRevisionByTitle( $title );
1210 $comment = $revision->getComment();
1211 $rc = RecentChange::newForCategorization(
1212 $revision->getTimestamp(),
1213 $this->getServiceContainer()->getTitleFactory()->newFromLinkTarget( $categoryTarget ),
1214 $user,
1215 $comment ? $comment->text : '',
1216 $title,
1218 $revision->getId(),
1219 null,
1220 false
1222 $rc->save();
1224 $this->watchPages( $user, [ $subjectTarget, $categoryTarget ] );
1226 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'categorize' ] );
1228 $this->assertEquals(
1231 'type' => 'categorize',
1232 'ns' => $categoryTarget->getNamespace(),
1233 'title' => $this->getPrefixedText( $categoryTarget ),
1236 $this->getItemsFromApiResponse( $result )
1240 public function testLimitParam() {
1241 $user = $this->getLoggedInTestUser();
1242 $target1 = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1243 $target2 = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1244 $target3 = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage2' );
1245 $this->doPageEdits(
1246 $user,
1249 'target' => $target1,
1250 'content' => 'Some Content',
1251 'summary' => 'Create the page',
1254 'target' => $target2,
1255 'content' => 'Some Talk Page Content',
1256 'summary' => 'Create Talk page',
1259 'target' => $target3,
1260 'content' => 'Some Other Content',
1261 'summary' => 'Create the page',
1265 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1267 $resultWithoutLimit = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1268 $resultWithLimit = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1270 $this->assertEquals(
1273 'type' => 'new',
1274 'ns' => $target3->getNamespace(),
1275 'title' => $this->getPrefixedText( $target3 )
1278 'type' => 'new',
1279 'ns' => $target2->getNamespace(),
1280 'title' => $this->getPrefixedText( $target2 )
1283 'type' => 'new',
1284 'ns' => $target1->getNamespace(),
1285 'title' => $this->getPrefixedText( $target1 )
1288 $this->getItemsFromApiResponse( $resultWithoutLimit )
1290 $this->assertEquals(
1293 'type' => 'new',
1294 'ns' => $target3->getNamespace(),
1295 'title' => $this->getPrefixedText( $target3 )
1298 'type' => 'new',
1299 'ns' => $target2->getNamespace(),
1300 'title' => $this->getPrefixedText( $target2 )
1303 $this->getItemsFromApiResponse( $resultWithLimit )
1305 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
1306 $this->assertArrayHasKey( 'wlcontinue', $resultWithLimit[0]['continue'] );
1309 public function testAllRevParam() {
1310 $user = $this->getLoggedInTestUser();
1311 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1312 $this->doPageEdits(
1313 $user,
1316 'target' => $target,
1317 'content' => 'Some Content',
1318 'summary' => 'Create the page',
1321 'target' => $target,
1322 'content' => 'Some Other Content',
1323 'summary' => 'Change the content',
1327 $this->watchPages( $user, [ $target ] );
1329 $resultAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wlallrev' => '', ] );
1330 $resultNoAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1332 $this->assertEquals(
1335 'type' => 'edit',
1336 'ns' => $target->getNamespace(),
1337 'title' => $this->getPrefixedText( $target ),
1340 $this->getItemsFromApiResponse( $resultNoAllRev )
1342 $this->assertEquals(
1345 'type' => 'edit',
1346 'ns' => $target->getNamespace(),
1347 'title' => $this->getPrefixedText( $target ),
1350 'type' => 'new',
1351 'ns' => $target->getNamespace(),
1352 'title' => $this->getPrefixedText( $target ),
1355 $this->getItemsFromApiResponse( $resultAllRev )
1359 public function testDirParams() {
1360 $user = $this->getLoggedInTestUser();
1361 $subjectTarget = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1362 $talkTarget = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1363 $this->doPageEdits(
1364 $user,
1367 'target' => $subjectTarget,
1368 'content' => 'Some Content',
1369 'summary' => 'Create the page',
1372 'target' => $talkTarget,
1373 'content' => 'Some Talk Page Content',
1374 'summary' => 'Create Talk page',
1378 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1380 $resultDirOlder = $this->doListWatchlistRequest( [ 'wldir' => 'older', 'wlprop' => 'title' ] );
1381 $resultDirNewer = $this->doListWatchlistRequest( [ 'wldir' => 'newer', 'wlprop' => 'title' ] );
1383 $this->assertEquals(
1386 'type' => 'new',
1387 'ns' => $talkTarget->getNamespace(),
1388 'title' => $this->getPrefixedText( $talkTarget )
1391 'type' => 'new',
1392 'ns' => $subjectTarget->getNamespace(),
1393 'title' => $this->getPrefixedText( $subjectTarget )
1396 $this->getItemsFromApiResponse( $resultDirOlder )
1398 $this->assertEquals(
1401 'type' => 'new',
1402 'ns' => $subjectTarget->getNamespace(),
1403 'title' => $this->getPrefixedText( $subjectTarget )
1406 'type' => 'new',
1407 'ns' => $talkTarget->getNamespace(),
1408 'title' => $this->getPrefixedText( $talkTarget )
1411 $this->getItemsFromApiResponse( $resultDirNewer )
1415 public function testStartEndParams() {
1416 $user = $this->getLoggedInTestUser();
1417 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1418 $this->doPageEdit(
1419 $user,
1420 $target,
1421 'Some Content',
1422 'Create the page'
1424 $this->watchPages( $user, [ $target ] );
1426 $resultStart = $this->doListWatchlistRequest( [
1427 'wlstart' => '20010115000000',
1428 'wldir' => 'newer',
1429 'wlprop' => 'title',
1430 ] );
1431 $resultEnd = $this->doListWatchlistRequest( [
1432 'wlend' => '20010115000000',
1433 'wldir' => 'newer',
1434 'wlprop' => 'title',
1435 ] );
1437 $this->assertEquals(
1440 'type' => 'new',
1441 'ns' => $target->getNamespace(),
1442 'title' => $this->getPrefixedText( $target ),
1445 $this->getItemsFromApiResponse( $resultStart )
1447 $this->assertSame( [], $this->getItemsFromApiResponse( $resultEnd ) );
1450 public function testContinueParam() {
1451 $user = $this->getLoggedInTestUser();
1452 $target1 = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1453 $target2 = new TitleValue( NS_TALK, 'ApiQueryWatchlistIntegrationTestPage' );
1454 $target3 = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage2' );
1455 $this->doPageEdits(
1456 $user,
1459 'target' => $target1,
1460 'content' => 'Some Content',
1461 'summary' => 'Create the page',
1464 'target' => $target2,
1465 'content' => 'Some Talk Page Content',
1466 'summary' => 'Create Talk page',
1469 'target' => $target3,
1470 'content' => 'Some Other Content',
1471 'summary' => 'Create the page',
1475 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1477 $firstResult = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1478 $this->assertArrayHasKey( 'continue', $firstResult[0] );
1479 $this->assertArrayHasKey( 'wlcontinue', $firstResult[0]['continue'] );
1481 $continuationParam = $firstResult[0]['continue']['wlcontinue'];
1483 $continuedResult = $this->doListWatchlistRequest(
1484 [ 'wlcontinue' => $continuationParam, 'wlprop' => 'title' ]
1487 $this->assertEquals(
1490 'type' => 'new',
1491 'ns' => $target3->getNamespace(),
1492 'title' => $this->getPrefixedText( $target3 ),
1495 'type' => 'new',
1496 'ns' => $target2->getNamespace(),
1497 'title' => $this->getPrefixedText( $target2 ),
1500 $this->getItemsFromApiResponse( $firstResult )
1502 $this->assertEquals(
1505 'type' => 'new',
1506 'ns' => $target1->getNamespace(),
1507 'title' => $this->getPrefixedText( $target1 )
1510 $this->getItemsFromApiResponse( $continuedResult )
1514 public function testOwnerAndTokenParams() {
1515 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1516 $this->doPageEdit(
1517 $this->getLoggedInTestUser(),
1518 $target,
1519 'Some Content',
1520 'Create the page'
1523 $userOptionsManager = $this->getServiceContainer()->getUserOptionsManager();
1525 $otherUser = $this->getNonLoggedInTestUser();
1526 $userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
1527 $otherUser->saveSettings();
1529 $this->watchPages( $otherUser, [ $target ] );
1531 $reloadedUser = $this->getServiceContainer()->getUserFactory()->newFromName( $otherUser->getName() );
1532 $option = $userOptionsManager->getOption( $reloadedUser, 'watchlisttoken' );
1533 $this->assertSame( '1234567890', $option );
1535 $result = $this->doListWatchlistRequest( [
1536 'wlowner' => $otherUser->getName(),
1537 'wltoken' => '1234567890',
1538 'wlprop' => 'title',
1539 ] );
1541 $this->assertEquals(
1544 'type' => 'new',
1545 'ns' => $target->getNamespace(),
1546 'title' => $this->getPrefixedText( $target )
1549 $this->getItemsFromApiResponse( $result )
1553 public function testOwnerAndTokenParams_wrongToken() {
1554 $userOptionsManager = $this->getServiceContainer()->getUserOptionsManager();
1556 $otherUser = $this->getNonLoggedInTestUser();
1557 $userOptionsManager->setOption( $otherUser, 'watchlisttoken', '1234567890' );
1558 $otherUser->saveSettings();
1560 $this->expectApiErrorCode( 'bad_wltoken' );
1562 $this->doListWatchlistRequest( [
1563 'wlowner' => $otherUser->getName(),
1564 'wltoken' => 'wrong-token',
1565 ] );
1568 public function testOwnerAndTokenParams_noWatchlistTokenSet() {
1569 $this->expectApiErrorCode( 'bad_wltoken' );
1571 $this->doListWatchlistRequest( [
1572 'wlowner' => $this->getNonLoggedInTestUser()->getName(),
1573 'wltoken' => 'some-token',
1574 ] );
1577 public function testGeneratorWatchlistPropInfo_returnsWatchedPages() {
1578 $user = $this->getLoggedInTestUser();
1579 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1580 $this->doPageEdit(
1581 $user,
1582 $target,
1583 'Some Content',
1584 'Create the page'
1586 $this->watchPages( $user, [ $target ] );
1588 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'info' ] );
1590 $this->assertArrayHasKey( 'query', $result[0] );
1591 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1593 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1594 $pages = array_values( $result[0]['query']['pages'] );
1596 $this->assertArraySubsetsEqual(
1597 $pages,
1600 'ns' => $target->getNamespace(),
1601 'title' => $this->getPrefixedText( $target ),
1602 'new' => true,
1605 [ 'ns', 'title', 'new' ]
1609 public function testGeneratorWatchlistPropRevisions_returnsWatchedItemsRevisions() {
1610 $user = $this->getLoggedInTestUser();
1611 $target = new TitleValue( NS_MAIN, 'ApiQueryWatchlistIntegrationTestPage' );
1612 $this->doPageEdits(
1613 $user,
1616 'target' => $target,
1617 'content' => 'Some Content',
1618 'summary' => 'Create the page',
1621 'target' => $target,
1622 'content' => 'Some Other Content',
1623 'summary' => 'Change the content',
1627 $this->watchPages( $user, [ $target ] );
1629 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'revisions', 'gwlallrev' => '' ] );
1631 $this->assertArrayHasKey( 'query', $result[0] );
1632 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1634 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1635 $pages = array_values( $result[0]['query']['pages'] );
1637 $this->assertCount( 1, $pages );
1638 $this->assertSame( $target->getNamespace(), $pages[0]['ns'] );
1639 $this->assertEquals( $this->getPrefixedText( $target ), $pages[0]['title'] );
1640 $this->assertArraySubsetsEqual(
1641 $pages[0]['revisions'],
1644 'comment' => 'Create the page',
1645 'user' => $user->getName(),
1646 'minor' => false,
1649 'comment' => 'Change the content',
1650 'user' => $user->getName(),
1651 'minor' => false,
1654 [ 'comment', 'user', 'minor' ]