Merge "Chinese Conversion Table Update 2018-2"
[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 medium
8 * @group API
9 * @group Database
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 }
27
28 private function getLoggedInTestUser() {
29 return self::$users['ApiQueryWatchlistIntegrationTestUser']->getUser();
30 }
31
32 private function getNonLoggedInTestUser() {
33 return self::$users['ApiQueryWatchlistIntegrationTestUser2']->getUser();
34 }
35
36 private function doPageEdit( User $user, LinkTarget $target, $content, $summary ) {
37 $title = Title::newFromLinkTarget( $target );
38 $page = WikiPage::factory( $title );
39 $page->doEditContent(
40 ContentHandler::makeContent( $content, $title ),
41 $summary,
42 0,
43 false,
44 $user
45 );
46 }
47
48 private function doMinorPageEdit( User $user, LinkTarget $target, $content, $summary ) {
49 $title = Title::newFromLinkTarget( $target );
50 $page = WikiPage::factory( $title );
51 $page->doEditContent(
52 ContentHandler::makeContent( $content, $title ),
53 $summary,
54 EDIT_MINOR,
55 false,
56 $user
57 );
58 }
59
60 private function doBotPageEdit( User $user, LinkTarget $target, $content, $summary ) {
61 $title = Title::newFromLinkTarget( $target );
62 $page = WikiPage::factory( $title );
63 $page->doEditContent(
64 ContentHandler::makeContent( $content, $title ),
65 $summary,
66 EDIT_FORCE_BOT,
67 false,
68 $user
69 );
70 }
71
72 private function doAnonPageEdit( LinkTarget $target, $content, $summary ) {
73 $title = Title::newFromLinkTarget( $target );
74 $page = WikiPage::factory( $title );
75 $page->doEditContent(
76 ContentHandler::makeContent( $content, $title ),
77 $summary,
78 0,
79 false,
80 User::newFromId( 0 )
81 );
82 }
83
84 private function doPatrolledPageEdit(
85 User $user,
86 LinkTarget $target,
87 $content,
88 $summary,
89 User $patrollingUser
90 ) {
91 $title = Title::newFromLinkTarget( $target );
92 $summary = CommentStoreComment::newUnsavedComment( trim( $summary ) );
93 $page = WikiPage::factory( $title );
94
95 $updater = $page->newPageUpdater( $user );
96 $updater->setContent( 'main', ContentHandler::makeContent( $content, $title ) );
97 $rev = $updater->saveRevision( $summary );
98
99 $rc = MediaWikiServices::getInstance()->getRevisionStore()->getRecentChange( $rev );
100 $rc->doMarkPatrolled( $patrollingUser, false, [] );
101 }
102
103 private function deletePage( LinkTarget $target, $reason ) {
104 $title = Title::newFromLinkTarget( $target );
105 $page = WikiPage::factory( $title );
106 $page->doDeleteArticleReal( $reason );
107 }
108
109 /**
110 * Performs a batch of page edits as a specified user
111 * @param User $user
112 * @param array $editData associative array, keys:
113 * - target => LinkTarget page to edit
114 * - content => string new content
115 * - summary => string edit summary
116 * - minorEdit => bool mark as minor edit if true (defaults to false)
117 * - botEdit => bool mark as bot edit if true (defaults to false)
118 */
119 private function doPageEdits( User $user, array $editData ) {
120 foreach ( $editData as $singleEditData ) {
121 if ( array_key_exists( 'minorEdit', $singleEditData ) && $singleEditData['minorEdit'] ) {
122 $this->doMinorPageEdit(
123 $user,
124 $singleEditData['target'],
125 $singleEditData['content'],
126 $singleEditData['summary']
127 );
128 continue;
129 }
130 if ( array_key_exists( 'botEdit', $singleEditData ) && $singleEditData['botEdit'] ) {
131 $this->doBotPageEdit(
132 $user,
133 $singleEditData['target'],
134 $singleEditData['content'],
135 $singleEditData['summary']
136 );
137 continue;
138 }
139 $this->doPageEdit(
140 $user,
141 $singleEditData['target'],
142 $singleEditData['content'],
143 $singleEditData['summary']
144 );
145 }
146 }
147
148 private function getWatchedItemStore() {
149 return MediaWikiServices::getInstance()->getWatchedItemStore();
150 }
151
152 /**
153 * @param User $user
154 * @param LinkTarget[] $targets
155 */
156 private function watchPages( User $user, array $targets ) {
157 $store = $this->getWatchedItemStore();
158 $store->addWatchBatchForUser( $user, $targets );
159 }
160
161 private function doListWatchlistRequest( array $params = [], $user = null ) {
162 if ( $user === null ) {
163 $user = $this->getLoggedInTestUser();
164 }
165 return $this->doApiRequest(
166 array_merge(
167 [ 'action' => 'query', 'list' => 'watchlist' ],
168 $params
169 ), null, false, $user
170 );
171 }
172
173 private function doGeneratorWatchlistRequest( array $params = [] ) {
174 return $this->doApiRequest(
175 array_merge(
176 [ 'action' => 'query', 'generator' => 'watchlist' ],
177 $params
178 ), null, false, $this->getLoggedInTestUser()
179 );
180 }
181
182 private function getItemsFromApiResponse( array $response ) {
183 return $response[0]['query']['watchlist'];
184 }
185
186 /**
187 * Convenience method to assert that actual items array fetched from API is equal to the expected
188 * array, Unlike assertEquals this only checks if values of specified keys are equal in both
189 * arrays. This could be used e.g. not to compare IDs that could change between test run
190 * but only stable keys.
191 * Optionally this also checks that specified keys are present in the actual item without
192 * performing any checks on the related values.
193 *
194 * @param array $actualItems array of actual items (associative arrays)
195 * @param array $expectedItems array of expected items (associative arrays),
196 * those items have less keys than actual items
197 * @param array $keysUsedInValueComparison list of keys of the actual item that will be used
198 * in the comparison of values
199 * @param array $requiredKeys optional, list of keys that must be present in the
200 * actual items. Values of those keys are not checked.
201 */
202 private function assertArraySubsetsEqual(
203 array $actualItems,
204 array $expectedItems,
205 array $keysUsedInValueComparison,
206 array $requiredKeys = []
207 ) {
208 $this->assertCount( count( $expectedItems ), $actualItems );
209
210 // not checking values of all keys of the actual item, so removing unwanted keys from comparison
211 $actualItemsOnlyComparedValues = array_map(
212 function ( array $item ) use ( $keysUsedInValueComparison ) {
213 return array_intersect_key( $item, array_flip( $keysUsedInValueComparison ) );
214 },
215 $actualItems
216 );
217
218 $this->assertEquals(
219 $expectedItems,
220 $actualItemsOnlyComparedValues
221 );
222
223 // Check that each item in $actualItems contains all of keys specified in $requiredKeys
224 $actualItemsKeysOnly = array_map( 'array_keys', $actualItems );
225 foreach ( $actualItemsKeysOnly as $keysOfTheItem ) {
226 $this->assertEmpty( array_diff( $requiredKeys, $keysOfTheItem ) );
227 }
228 }
229
230 private function getTitleFormatter() {
231 return new MediaWikiTitleCodec(
232 Language::factory( 'en' ),
233 MediaWikiServices::getInstance()->getGenderCache()
234 );
235 }
236
237 private function getPrefixedText( LinkTarget $target ) {
238 $formatter = $this->getTitleFormatter();
239 return $formatter->getPrefixedText( $target );
240 }
241
242 private function cleanTestUsersWatchlist() {
243 $user = $this->getLoggedInTestUser();
244 $store = $this->getWatchedItemStore();
245 $items = $store->getWatchedItemsForUser( $user );
246 foreach ( $items as $item ) {
247 $store->removeWatch( $user, $item->getLinkTarget() );
248 }
249 }
250
251 public function testListWatchlist_returnsWatchedItemsWithRCInfo() {
252 // Clean up after previous tests that might have added something to the watchlist of
253 // the user with the same user ID as user used here as the test user
254 $this->cleanTestUsersWatchlist();
255
256 $user = $this->getLoggedInTestUser();
257 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
258 $this->doPageEdit(
259 $user,
260 $target,
261 'Some Content',
262 'Create the page'
263 );
264 $this->watchPages( $user, [ $target ] );
265
266 $result = $this->doListWatchlistRequest();
267
268 $this->assertArrayHasKey( 'query', $result[0] );
269 $this->assertArrayHasKey( 'watchlist', $result[0]['query'] );
270
271 $this->assertArraySubsetsEqual(
272 $this->getItemsFromApiResponse( $result ),
273 [
274 [
275 'type' => 'new',
276 'ns' => $target->getNamespace(),
277 'title' => $this->getPrefixedText( $target ),
278 'bot' => false,
279 'new' => true,
280 'minor' => false,
281 ]
282 ],
283 [ 'type', 'ns', 'title', 'bot', 'new', 'minor' ],
284 [ 'pageid', 'revid', 'old_revid' ]
285 );
286 }
287
288 public function testIdsPropParameter() {
289 $user = $this->getLoggedInTestUser();
290 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
291 $this->doPageEdit(
292 $user,
293 $target,
294 'Some Content',
295 'Create the page'
296 );
297 $this->watchPages( $user, [ $target ] );
298
299 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'ids', ] );
300 $items = $this->getItemsFromApiResponse( $result );
301
302 $this->assertCount( 1, $items );
303 $this->assertArrayHasKey( 'pageid', $items[0] );
304 $this->assertArrayHasKey( 'revid', $items[0] );
305 $this->assertArrayHasKey( 'old_revid', $items[0] );
306 $this->assertEquals( 'new', $items[0]['type'] );
307 }
308
309 public function testTitlePropParameter() {
310 $user = $this->getLoggedInTestUser();
311 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
312 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
313 $this->doPageEdits(
314 $user,
315 [
316 [
317 'target' => $subjectTarget,
318 'content' => 'Some Content',
319 'summary' => 'Create the page',
320 ],
321 [
322 'target' => $talkTarget,
323 'content' => 'Some Talk Page Content',
324 'summary' => 'Create Talk page',
325 ],
326 ]
327 );
328 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
329
330 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', ] );
331
332 $this->assertEquals(
333 [
334 [
335 'type' => 'new',
336 'ns' => $talkTarget->getNamespace(),
337 'title' => $this->getPrefixedText( $talkTarget ),
338 ],
339 [
340 'type' => 'new',
341 'ns' => $subjectTarget->getNamespace(),
342 'title' => $this->getPrefixedText( $subjectTarget ),
343 ],
344 ],
345 $this->getItemsFromApiResponse( $result )
346 );
347 }
348
349 public function testFlagsPropParameter() {
350 $user = $this->getLoggedInTestUser();
351 $normalEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
352 $minorEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageM' );
353 $botEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageB' );
354 $this->doPageEdits(
355 $user,
356 [
357 [
358 'target' => $normalEditTarget,
359 'content' => 'Some Content',
360 'summary' => 'Create the page',
361 ],
362 [
363 'target' => $minorEditTarget,
364 'content' => 'Some Content',
365 'summary' => 'Create the page',
366 ],
367 [
368 'target' => $minorEditTarget,
369 'content' => 'Slightly Better Content',
370 'summary' => 'Change content',
371 'minorEdit' => true,
372 ],
373 [
374 'target' => $botEditTarget,
375 'content' => 'Some Content',
376 'summary' => 'Create the page with a bot',
377 'botEdit' => true,
378 ],
379 ]
380 );
381 $this->watchPages( $user, [ $normalEditTarget, $minorEditTarget, $botEditTarget ] );
382
383 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'flags', ] );
384
385 $this->assertEquals(
386 [
387 [
388 'type' => 'new',
389 'new' => true,
390 'minor' => false,
391 'bot' => true,
392 ],
393 [
394 'type' => 'edit',
395 'new' => false,
396 'minor' => true,
397 'bot' => false,
398 ],
399 [
400 'type' => 'new',
401 'new' => true,
402 'minor' => false,
403 'bot' => false,
404 ],
405 ],
406 $this->getItemsFromApiResponse( $result )
407 );
408 }
409
410 public function testUserPropParameter() {
411 $user = $this->getLoggedInTestUser();
412 $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
413 $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
414 $this->doPageEdit(
415 $user,
416 $userEditTarget,
417 'Some Content',
418 'Create the page'
419 );
420 $this->doAnonPageEdit(
421 $anonEditTarget,
422 'Some Content',
423 'Create the page'
424 );
425 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
426
427 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'user', ] );
428
429 $this->assertEquals(
430 [
431 [
432 'type' => 'new',
433 'anon' => true,
434 'user' => User::newFromId( 0 )->getName(),
435 ],
436 [
437 'type' => 'new',
438 'user' => $user->getName(),
439 ],
440 ],
441 $this->getItemsFromApiResponse( $result )
442 );
443 }
444
445 public function testUserIdPropParameter() {
446 $user = $this->getLoggedInTestUser();
447 $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
448 $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
449 $this->doPageEdit(
450 $user,
451 $userEditTarget,
452 'Some Content',
453 'Create the page'
454 );
455 $this->doAnonPageEdit(
456 $anonEditTarget,
457 'Some Content',
458 'Create the page'
459 );
460 $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
461
462 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'userid', ] );
463
464 $this->assertEquals(
465 [
466 [
467 'type' => 'new',
468 'anon' => true,
469 'user' => 0,
470 'userid' => 0,
471 ],
472 [
473 'type' => 'new',
474 'user' => $user->getId(),
475 'userid' => $user->getId(),
476 ],
477 ],
478 $this->getItemsFromApiResponse( $result )
479 );
480 }
481
482 public function testCommentPropParameter() {
483 $user = $this->getLoggedInTestUser();
484 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
485 $this->doPageEdit(
486 $user,
487 $target,
488 'Some Content',
489 'Create the <b>page</b>'
490 );
491 $this->watchPages( $user, [ $target ] );
492
493 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'comment', ] );
494
495 $this->assertEquals(
496 [
497 [
498 'type' => 'new',
499 'comment' => 'Create the <b>page</b>',
500 ],
501 ],
502 $this->getItemsFromApiResponse( $result )
503 );
504 }
505
506 public function testParsedCommentPropParameter() {
507 $user = $this->getLoggedInTestUser();
508 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
509 $this->doPageEdit(
510 $user,
511 $target,
512 'Some Content',
513 'Create the <b>page</b>'
514 );
515 $this->watchPages( $user, [ $target ] );
516
517 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'parsedcomment', ] );
518
519 $this->assertEquals(
520 [
521 [
522 'type' => 'new',
523 'parsedcomment' => 'Create the &lt;b&gt;page&lt;/b&gt;',
524 ],
525 ],
526 $this->getItemsFromApiResponse( $result )
527 );
528 }
529
530 public function testTimestampPropParameter() {
531 $user = $this->getLoggedInTestUser();
532 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
533 $this->doPageEdit(
534 $user,
535 $target,
536 'Some Content',
537 'Create the page'
538 );
539 $this->watchPages( $user, [ $target ] );
540
541 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'timestamp', ] );
542 $items = $this->getItemsFromApiResponse( $result );
543
544 $this->assertCount( 1, $items );
545 $this->assertArrayHasKey( 'timestamp', $items[0] );
546 $this->assertInternalType( 'string', $items[0]['timestamp'] );
547 }
548
549 public function testSizesPropParameter() {
550 $user = $this->getLoggedInTestUser();
551 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
552 $this->doPageEdit(
553 $user,
554 $target,
555 'Some Content',
556 'Create the page'
557 );
558 $this->watchPages( $user, [ $target ] );
559
560 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'sizes', ] );
561
562 $this->assertEquals(
563 [
564 [
565 'type' => 'new',
566 'oldlen' => 0,
567 'newlen' => 12,
568 ],
569 ],
570 $this->getItemsFromApiResponse( $result )
571 );
572 }
573
574 public function testNotificationTimestampPropParameter() {
575 $otherUser = $this->getNonLoggedInTestUser();
576 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
577 $this->doPageEdit(
578 $otherUser,
579 $target,
580 'Some Content',
581 'Create the page'
582 );
583 $store = $this->getWatchedItemStore();
584 $store->addWatch( $this->getLoggedInTestUser(), $target );
585 $store->updateNotificationTimestamp(
586 $otherUser,
587 $target,
588 '20151212010101'
589 );
590
591 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'notificationtimestamp', ] );
592
593 $this->assertEquals(
594 [
595 [
596 'type' => 'new',
597 'notificationtimestamp' => '2015-12-12T01:01:01Z',
598 ],
599 ],
600 $this->getItemsFromApiResponse( $result )
601 );
602 }
603
604 private function setupPatrolledSpecificFixtures( User $user ) {
605 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
606
607 $this->doPatrolledPageEdit(
608 $user,
609 $target,
610 'Some Content',
611 'Create the page (this gets patrolled)',
612 $user
613 );
614
615 $this->watchPages( $user, [ $target ] );
616 }
617
618 public function testPatrolPropParameter() {
619 $testUser = static::getTestSysop();
620 $user = $testUser->getUser();
621 $this->setupPatrolledSpecificFixtures( $user );
622
623 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'patrol', ], $user );
624
625 $this->assertEquals(
626 [
627 [
628 'type' => 'new',
629 'patrolled' => true,
630 'unpatrolled' => false,
631 'autopatrolled' => 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 'autopatrolled' => false,
977 ]
978 ],
979 $this->getItemsFromApiResponse( $resultPatrolled )
980 );
981 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotPatrolled ) );
982 }
983
984 public function testNewAndEditTypeParameters() {
985 $user = $this->getLoggedInTestUser();
986 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
987 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
988 $this->doPageEdits(
989 $user,
990 [
991 [
992 'target' => $subjectTarget,
993 'content' => 'Some Content',
994 'summary' => 'Create the page',
995 ],
996 [
997 'target' => $subjectTarget,
998 'content' => 'Some Other Content',
999 'summary' => 'Change the content',
1000 ],
1001 [
1002 'target' => $talkTarget,
1003 'content' => 'Some Talk Page Content',
1004 'summary' => 'Create Talk page',
1005 ],
1006 ]
1007 );
1008 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1009
1010 $resultNew = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'new' ] );
1011 $resultEdit = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'edit' ] );
1012
1013 $this->assertEquals(
1014 [
1015 [
1016 'type' => 'new',
1017 'ns' => $talkTarget->getNamespace(),
1018 'title' => $this->getPrefixedText( $talkTarget ),
1019 ],
1020 ],
1021 $this->getItemsFromApiResponse( $resultNew )
1022 );
1023 $this->assertEquals(
1024 [
1025 [
1026 'type' => 'edit',
1027 'ns' => $subjectTarget->getNamespace(),
1028 'title' => $this->getPrefixedText( $subjectTarget ),
1029 ],
1030 ],
1031 $this->getItemsFromApiResponse( $resultEdit )
1032 );
1033 }
1034
1035 public function testLogTypeParameters() {
1036 $user = $this->getLoggedInTestUser();
1037 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1038 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1039 $this->createPageAndDeleteIt( $subjectTarget );
1040 $this->doPageEdit(
1041 $user,
1042 $talkTarget,
1043 'Some Talk Page Content',
1044 'Create Talk page'
1045 );
1046 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1047
1048 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'log' ] );
1049
1050 $this->assertEquals(
1051 [
1052 [
1053 'type' => 'log',
1054 'ns' => $subjectTarget->getNamespace(),
1055 'title' => $this->getPrefixedText( $subjectTarget ),
1056 ],
1057 ],
1058 $this->getItemsFromApiResponse( $result )
1059 );
1060 }
1061
1062 private function getExternalRC( LinkTarget $target ) {
1063 $title = Title::newFromLinkTarget( $target );
1064
1065 $rc = new RecentChange;
1066 $rc->mTitle = $title;
1067 $rc->mAttribs = [
1068 'rc_timestamp' => wfTimestamp( TS_MW ),
1069 'rc_namespace' => $title->getNamespace(),
1070 'rc_title' => $title->getDBkey(),
1071 'rc_type' => RC_EXTERNAL,
1072 'rc_source' => 'foo',
1073 'rc_minor' => 0,
1074 'rc_cur_id' => $title->getArticleID(),
1075 'rc_user' => 0,
1076 'rc_user_text' => 'ext>External User',
1077 'rc_comment' => '',
1078 'rc_comment_text' => '',
1079 'rc_comment_data' => null,
1080 'rc_this_oldid' => $title->getLatestRevID(),
1081 'rc_last_oldid' => $title->getLatestRevID(),
1082 'rc_bot' => 0,
1083 'rc_ip' => '',
1084 'rc_patrolled' => 0,
1085 'rc_new' => 0,
1086 'rc_old_len' => $title->getLength(),
1087 'rc_new_len' => $title->getLength(),
1088 'rc_deleted' => 0,
1089 'rc_logid' => 0,
1090 'rc_log_type' => null,
1091 'rc_log_action' => '',
1092 'rc_params' => '',
1093 ];
1094 $rc->mExtra = [
1095 'prefixedDBkey' => $title->getPrefixedDBkey(),
1096 'lastTimestamp' => 0,
1097 'oldSize' => $title->getLength(),
1098 'newSize' => $title->getLength(),
1099 'pageStatus' => 'changed'
1100 ];
1101
1102 return $rc;
1103 }
1104
1105 public function testExternalTypeParameters() {
1106 $user = $this->getLoggedInTestUser();
1107 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1108 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1109 $this->doPageEdit(
1110 $user,
1111 $subjectTarget,
1112 'Some Content',
1113 'Create the page'
1114 );
1115 $this->doPageEdit(
1116 $user,
1117 $talkTarget,
1118 'Some Talk Page Content',
1119 'Create Talk page'
1120 );
1121
1122 $rc = $this->getExternalRC( $subjectTarget );
1123 $rc->save();
1124
1125 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1126
1127 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'external' ] );
1128
1129 $this->assertEquals(
1130 [
1131 [
1132 'type' => 'external',
1133 'ns' => $subjectTarget->getNamespace(),
1134 'title' => $this->getPrefixedText( $subjectTarget ),
1135 ],
1136 ],
1137 $this->getItemsFromApiResponse( $result )
1138 );
1139 }
1140
1141 public function testCategorizeTypeParameter() {
1142 $user = $this->getLoggedInTestUser();
1143 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1144 $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryWatchlistIntegrationTestCategory' );
1145 $this->doPageEdits(
1146 $user,
1147 [
1148 [
1149 'target' => $categoryTarget,
1150 'content' => 'Some Content',
1151 'summary' => 'Create the category',
1152 ],
1153 [
1154 'target' => $subjectTarget,
1155 'content' => 'Some Content [[Category:ApiQueryWatchlistIntegrationTestCategory]]t',
1156 'summary' => 'Create the page and add it to the category',
1157 ],
1158 ]
1159 );
1160 $title = Title::newFromLinkTarget( $subjectTarget );
1161 $revision = Revision::newFromTitle( $title );
1162
1163 $rc = RecentChange::newForCategorization(
1164 $revision->getTimestamp(),
1165 Title::newFromLinkTarget( $categoryTarget ),
1166 $user,
1167 $revision->getComment(),
1168 $title,
1169 0,
1170 $revision->getId(),
1171 null,
1172 false
1173 );
1174 $rc->save();
1175
1176 $this->watchPages( $user, [ $subjectTarget, $categoryTarget ] );
1177
1178 $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'categorize' ] );
1179
1180 $this->assertEquals(
1181 [
1182 [
1183 'type' => 'categorize',
1184 'ns' => $categoryTarget->getNamespace(),
1185 'title' => $this->getPrefixedText( $categoryTarget ),
1186 ],
1187 ],
1188 $this->getItemsFromApiResponse( $result )
1189 );
1190 }
1191
1192 public function testLimitParam() {
1193 $user = $this->getLoggedInTestUser();
1194 $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1195 $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1196 $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
1197 $this->doPageEdits(
1198 $user,
1199 [
1200 [
1201 'target' => $target1,
1202 'content' => 'Some Content',
1203 'summary' => 'Create the page',
1204 ],
1205 [
1206 'target' => $target2,
1207 'content' => 'Some Talk Page Content',
1208 'summary' => 'Create Talk page',
1209 ],
1210 [
1211 'target' => $target3,
1212 'content' => 'Some Other Content',
1213 'summary' => 'Create the page',
1214 ],
1215 ]
1216 );
1217 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1218
1219 $resultWithoutLimit = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1220 $resultWithLimit = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1221
1222 $this->assertEquals(
1223 [
1224 [
1225 'type' => 'new',
1226 'ns' => $target3->getNamespace(),
1227 'title' => $this->getPrefixedText( $target3 )
1228 ],
1229 [
1230 'type' => 'new',
1231 'ns' => $target2->getNamespace(),
1232 'title' => $this->getPrefixedText( $target2 )
1233 ],
1234 [
1235 'type' => 'new',
1236 'ns' => $target1->getNamespace(),
1237 'title' => $this->getPrefixedText( $target1 )
1238 ],
1239 ],
1240 $this->getItemsFromApiResponse( $resultWithoutLimit )
1241 );
1242 $this->assertEquals(
1243 [
1244 [
1245 'type' => 'new',
1246 'ns' => $target3->getNamespace(),
1247 'title' => $this->getPrefixedText( $target3 )
1248 ],
1249 [
1250 'type' => 'new',
1251 'ns' => $target2->getNamespace(),
1252 'title' => $this->getPrefixedText( $target2 )
1253 ],
1254 ],
1255 $this->getItemsFromApiResponse( $resultWithLimit )
1256 );
1257 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
1258 $this->assertArrayHasKey( 'wlcontinue', $resultWithLimit[0]['continue'] );
1259 }
1260
1261 public function testAllRevParam() {
1262 $user = $this->getLoggedInTestUser();
1263 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1264 $this->doPageEdits(
1265 $user,
1266 [
1267 [
1268 'target' => $target,
1269 'content' => 'Some Content',
1270 'summary' => 'Create the page',
1271 ],
1272 [
1273 'target' => $target,
1274 'content' => 'Some Other Content',
1275 'summary' => 'Change the content',
1276 ],
1277 ]
1278 );
1279 $this->watchPages( $user, [ $target ] );
1280
1281 $resultAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wlallrev' => '', ] );
1282 $resultNoAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
1283
1284 $this->assertEquals(
1285 [
1286 [
1287 'type' => 'edit',
1288 'ns' => $target->getNamespace(),
1289 'title' => $this->getPrefixedText( $target ),
1290 ],
1291 ],
1292 $this->getItemsFromApiResponse( $resultNoAllRev )
1293 );
1294 $this->assertEquals(
1295 [
1296 [
1297 'type' => 'edit',
1298 'ns' => $target->getNamespace(),
1299 'title' => $this->getPrefixedText( $target ),
1300 ],
1301 [
1302 'type' => 'new',
1303 'ns' => $target->getNamespace(),
1304 'title' => $this->getPrefixedText( $target ),
1305 ],
1306 ],
1307 $this->getItemsFromApiResponse( $resultAllRev )
1308 );
1309 }
1310
1311 public function testDirParams() {
1312 $user = $this->getLoggedInTestUser();
1313 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1314 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1315 $this->doPageEdits(
1316 $user,
1317 [
1318 [
1319 'target' => $subjectTarget,
1320 'content' => 'Some Content',
1321 'summary' => 'Create the page',
1322 ],
1323 [
1324 'target' => $talkTarget,
1325 'content' => 'Some Talk Page Content',
1326 'summary' => 'Create Talk page',
1327 ],
1328 ]
1329 );
1330 $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
1331
1332 $resultDirOlder = $this->doListWatchlistRequest( [ 'wldir' => 'older', 'wlprop' => 'title' ] );
1333 $resultDirNewer = $this->doListWatchlistRequest( [ 'wldir' => 'newer', 'wlprop' => 'title' ] );
1334
1335 $this->assertEquals(
1336 [
1337 [
1338 'type' => 'new',
1339 'ns' => $talkTarget->getNamespace(),
1340 'title' => $this->getPrefixedText( $talkTarget )
1341 ],
1342 [
1343 'type' => 'new',
1344 'ns' => $subjectTarget->getNamespace(),
1345 'title' => $this->getPrefixedText( $subjectTarget )
1346 ],
1347 ],
1348 $this->getItemsFromApiResponse( $resultDirOlder )
1349 );
1350 $this->assertEquals(
1351 [
1352 [
1353 'type' => 'new',
1354 'ns' => $subjectTarget->getNamespace(),
1355 'title' => $this->getPrefixedText( $subjectTarget )
1356 ],
1357 [
1358 'type' => 'new',
1359 'ns' => $talkTarget->getNamespace(),
1360 'title' => $this->getPrefixedText( $talkTarget )
1361 ],
1362 ],
1363 $this->getItemsFromApiResponse( $resultDirNewer )
1364 );
1365 }
1366
1367 public function testStartEndParams() {
1368 $user = $this->getLoggedInTestUser();
1369 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1370 $this->doPageEdit(
1371 $user,
1372 $target,
1373 'Some Content',
1374 'Create the page'
1375 );
1376 $this->watchPages( $user, [ $target ] );
1377
1378 $resultStart = $this->doListWatchlistRequest( [
1379 'wlstart' => '20010115000000',
1380 'wldir' => 'newer',
1381 'wlprop' => 'title',
1382 ] );
1383 $resultEnd = $this->doListWatchlistRequest( [
1384 'wlend' => '20010115000000',
1385 'wldir' => 'newer',
1386 'wlprop' => 'title',
1387 ] );
1388
1389 $this->assertEquals(
1390 [
1391 [
1392 'type' => 'new',
1393 'ns' => $target->getNamespace(),
1394 'title' => $this->getPrefixedText( $target ),
1395 ]
1396 ],
1397 $this->getItemsFromApiResponse( $resultStart )
1398 );
1399 $this->assertEmpty( $this->getItemsFromApiResponse( $resultEnd ) );
1400 }
1401
1402 public function testContinueParam() {
1403 $user = $this->getLoggedInTestUser();
1404 $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1405 $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
1406 $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
1407 $this->doPageEdits(
1408 $user,
1409 [
1410 [
1411 'target' => $target1,
1412 'content' => 'Some Content',
1413 'summary' => 'Create the page',
1414 ],
1415 [
1416 'target' => $target2,
1417 'content' => 'Some Talk Page Content',
1418 'summary' => 'Create Talk page',
1419 ],
1420 [
1421 'target' => $target3,
1422 'content' => 'Some Other Content',
1423 'summary' => 'Create the page',
1424 ],
1425 ]
1426 );
1427 $this->watchPages( $user, [ $target1, $target2, $target3 ] );
1428
1429 $firstResult = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
1430 $this->assertArrayHasKey( 'continue', $firstResult[0] );
1431 $this->assertArrayHasKey( 'wlcontinue', $firstResult[0]['continue'] );
1432
1433 $continuationParam = $firstResult[0]['continue']['wlcontinue'];
1434
1435 $continuedResult = $this->doListWatchlistRequest(
1436 [ 'wlcontinue' => $continuationParam, 'wlprop' => 'title' ]
1437 );
1438
1439 $this->assertEquals(
1440 [
1441 [
1442 'type' => 'new',
1443 'ns' => $target3->getNamespace(),
1444 'title' => $this->getPrefixedText( $target3 ),
1445 ],
1446 [
1447 'type' => 'new',
1448 'ns' => $target2->getNamespace(),
1449 'title' => $this->getPrefixedText( $target2 ),
1450 ],
1451 ],
1452 $this->getItemsFromApiResponse( $firstResult )
1453 );
1454 $this->assertEquals(
1455 [
1456 [
1457 'type' => 'new',
1458 'ns' => $target1->getNamespace(),
1459 'title' => $this->getPrefixedText( $target1 )
1460 ]
1461 ],
1462 $this->getItemsFromApiResponse( $continuedResult )
1463 );
1464 }
1465
1466 public function testOwnerAndTokenParams() {
1467 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1468 $this->doPageEdit(
1469 $this->getLoggedInTestUser(),
1470 $target,
1471 'Some Content',
1472 'Create the page'
1473 );
1474
1475 $otherUser = $this->getNonLoggedInTestUser();
1476 $otherUser->setOption( 'watchlisttoken', '1234567890' );
1477 $otherUser->saveSettings();
1478
1479 $this->watchPages( $otherUser, [ $target ] );
1480
1481 $reloadedUser = User::newFromName( $otherUser->getName() );
1482 $this->assertEquals( '1234567890', $reloadedUser->getOption( 'watchlisttoken' ) );
1483
1484 $result = $this->doListWatchlistRequest( [
1485 'wlowner' => $otherUser->getName(),
1486 'wltoken' => '1234567890',
1487 'wlprop' => 'title',
1488 ] );
1489
1490 $this->assertEquals(
1491 [
1492 [
1493 'type' => 'new',
1494 'ns' => $target->getNamespace(),
1495 'title' => $this->getPrefixedText( $target )
1496 ]
1497 ],
1498 $this->getItemsFromApiResponse( $result )
1499 );
1500 }
1501
1502 public function testOwnerAndTokenParams_wrongToken() {
1503 $otherUser = $this->getNonLoggedInTestUser();
1504 $otherUser->setOption( 'watchlisttoken', '1234567890' );
1505 $otherUser->saveSettings();
1506
1507 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
1508
1509 $this->doListWatchlistRequest( [
1510 'wlowner' => $otherUser->getName(),
1511 'wltoken' => 'wrong-token',
1512 ] );
1513 }
1514
1515 public function testOwnerAndTokenParams_noWatchlistTokenSet() {
1516 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
1517
1518 $this->doListWatchlistRequest( [
1519 'wlowner' => $this->getNonLoggedInTestUser()->getName(),
1520 'wltoken' => 'some-token',
1521 ] );
1522 }
1523
1524 public function testGeneratorWatchlistPropInfo_returnsWatchedPages() {
1525 $user = $this->getLoggedInTestUser();
1526 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1527 $this->doPageEdit(
1528 $user,
1529 $target,
1530 'Some Content',
1531 'Create the page'
1532 );
1533 $this->watchPages( $user, [ $target ] );
1534
1535 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'info' ] );
1536
1537 $this->assertArrayHasKey( 'query', $result[0] );
1538 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1539
1540 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1541 $pages = array_values( $result[0]['query']['pages'] );
1542
1543 $this->assertArraySubsetsEqual(
1544 $pages,
1545 [
1546 [
1547 'ns' => $target->getNamespace(),
1548 'title' => $this->getPrefixedText( $target ),
1549 'new' => true,
1550 ]
1551 ],
1552 [ 'ns', 'title', 'new' ]
1553 );
1554 }
1555
1556 public function testGeneratorWatchlistPropRevisions_returnsWatchedItemsRevisions() {
1557 $user = $this->getLoggedInTestUser();
1558 $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
1559 $this->doPageEdits(
1560 $user,
1561 [
1562 [
1563 'target' => $target,
1564 'content' => 'Some Content',
1565 'summary' => 'Create the page',
1566 ],
1567 [
1568 'target' => $target,
1569 'content' => 'Some Other Content',
1570 'summary' => 'Change the content',
1571 ],
1572 ]
1573 );
1574 $this->watchPages( $user, [ $target ] );
1575
1576 $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'revisions', 'gwlallrev' => '' ] );
1577
1578 $this->assertArrayHasKey( 'query', $result[0] );
1579 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1580
1581 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1582 $pages = array_values( $result[0]['query']['pages'] );
1583
1584 $this->assertCount( 1, $pages );
1585 $this->assertEquals( 0, $pages[0]['ns'] );
1586 $this->assertEquals( $this->getPrefixedText( $target ), $pages[0]['title'] );
1587 $this->assertArraySubsetsEqual(
1588 $pages[0]['revisions'],
1589 [
1590 [
1591 'comment' => 'Create the page',
1592 'user' => $user->getName(),
1593 'minor' => false,
1594 ],
1595 [
1596 'comment' => 'Change the content',
1597 'user' => $user->getName(),
1598 'minor' => false,
1599 ],
1600 ],
1601 [ 'comment', 'user', 'minor' ]
1602 );
1603 }
1604
1605 }