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