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