API: Migrate Title::userCan() calls to PermissionManager
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiQueryRecentChangesIntegrationTest.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 ApiQueryRecentChanges
12 */
13 class ApiQueryRecentChangesIntegrationTest extends ApiTestCase {
14
15 public function __construct( $name = null, array $data = [], $dataName = '' ) {
16 parent::__construct( $name, $data, $dataName );
17
18 $this->tablesUsed[] = 'recentchanges';
19 $this->tablesUsed[] = 'page';
20 }
21
22 protected function setUp() {
23 parent::setUp();
24
25 self::$users['ApiQueryRecentChangesIntegrationTestUser'] = $this->getMutableTestUser();
26 wfGetDB( DB_MASTER )->delete( 'recentchanges', '*', __METHOD__ );
27 }
28
29 private function getLoggedInTestUser() {
30 return self::$users['ApiQueryRecentChangesIntegrationTestUser']->getUser();
31 }
32
33 private function doPageEdit( User $user, LinkTarget $target, $summary ) {
34 static $i = 0;
35
36 $title = Title::newFromLinkTarget( $target );
37 $page = WikiPage::factory( $title );
38 $page->doEditContent(
39 ContentHandler::makeContent( __CLASS__ . $i++, $title ),
40 $summary,
41 0,
42 false,
43 $user
44 );
45 }
46
47 private function doMinorPageEdit( User $user, LinkTarget $target, $summary ) {
48 $title = Title::newFromLinkTarget( $target );
49 $page = WikiPage::factory( $title );
50 $page->doEditContent(
51 ContentHandler::makeContent( __CLASS__, $title ),
52 $summary,
53 EDIT_MINOR,
54 false,
55 $user
56 );
57 }
58
59 private function doBotPageEdit( User $user, LinkTarget $target, $summary ) {
60 $title = Title::newFromLinkTarget( $target );
61 $page = WikiPage::factory( $title );
62 $page->doEditContent(
63 ContentHandler::makeContent( __CLASS__, $title ),
64 $summary,
65 EDIT_FORCE_BOT,
66 false,
67 $user
68 );
69 }
70
71 private function doAnonPageEdit( LinkTarget $target, $summary ) {
72 $title = Title::newFromLinkTarget( $target );
73 $page = WikiPage::factory( $title );
74 $page->doEditContent(
75 ContentHandler::makeContent( __CLASS__, $title ),
76 $summary,
77 0,
78 false,
79 User::newFromId( 0 )
80 );
81 }
82
83 private function deletePage( LinkTarget $target, $reason ) {
84 $title = Title::newFromLinkTarget( $target );
85 $page = WikiPage::factory( $title );
86 $page->doDeleteArticleReal( $reason );
87 }
88
89 /**
90 * Performs a batch of page edits as a specified user
91 * @param User $user
92 * @param array $editData associative array, keys:
93 * - target => LinkTarget page to edit
94 * - summary => string edit summary
95 * - minorEdit => bool mark as minor edit if true (defaults to false)
96 * - botEdit => bool mark as bot edit if true (defaults to false)
97 */
98 private function doPageEdits( User $user, array $editData ) {
99 foreach ( $editData as $singleEditData ) {
100 if ( array_key_exists( 'minorEdit', $singleEditData ) && $singleEditData['minorEdit'] ) {
101 $this->doMinorPageEdit(
102 $user,
103 $singleEditData['target'],
104 $singleEditData['summary']
105 );
106 continue;
107 }
108 if ( array_key_exists( 'botEdit', $singleEditData ) && $singleEditData['botEdit'] ) {
109 $this->doBotPageEdit(
110 $user,
111 $singleEditData['target'],
112 $singleEditData['summary']
113 );
114 continue;
115 }
116 $this->doPageEdit(
117 $user,
118 $singleEditData['target'],
119 $singleEditData['summary']
120 );
121 }
122 }
123
124 private function doListRecentChangesRequest( array $params = [] ) {
125 return $this->doApiRequest(
126 array_merge(
127 [ 'action' => 'query', 'list' => 'recentchanges' ],
128 $params
129 ),
130 null,
131 false,
132 $this->getLoggedInTestUser()
133 );
134 }
135
136 private function doGeneratorRecentChangesRequest( array $params = [] ) {
137 return $this->doApiRequest(
138 array_merge(
139 [ 'action' => 'query', 'generator' => 'recentchanges' ],
140 $params
141 ),
142 null,
143 false,
144 $this->getLoggedInTestUser()
145 );
146 }
147
148 private function getItemsFromApiResponse( array $response ) {
149 return $response[0]['query']['recentchanges'];
150 }
151
152 private function getPrefixedText( LinkTarget $target ) {
153 return MediaWikiServices::getInstance()->getTitleFormatter()->getPrefixedText( $target );
154 }
155
156 public function testListRecentChanges_returnsRCInfo() {
157 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
158 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
159
160 $result = $this->doListRecentChangesRequest();
161
162 $this->assertArrayHasKey( 'query', $result[0] );
163 $this->assertArrayHasKey( 'recentchanges', $result[0]['query'] );
164
165 $items = $this->getItemsFromApiResponse( $result );
166 $this->assertCount( 1, $items );
167 $item = $items[0];
168 $this->assertArraySubset(
169 [
170 'type' => 'new',
171 'ns' => $target->getNamespace(),
172 'title' => $this->getPrefixedText( $target ),
173 ],
174 $item
175 );
176 $this->assertArrayNotHasKey( 'bot', $item );
177 $this->assertArrayNotHasKey( 'new', $item );
178 $this->assertArrayNotHasKey( 'minor', $item );
179 $this->assertArrayHasKey( 'pageid', $item );
180 $this->assertArrayHasKey( 'revid', $item );
181 $this->assertArrayHasKey( 'old_revid', $item );
182 }
183
184 public function testIdsPropParameter() {
185 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
186 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
187
188 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'ids', ] );
189 $items = $this->getItemsFromApiResponse( $result );
190
191 $this->assertCount( 1, $items );
192 $this->assertArrayHasKey( 'pageid', $items[0] );
193 $this->assertArrayHasKey( 'revid', $items[0] );
194 $this->assertArrayHasKey( 'old_revid', $items[0] );
195 $this->assertEquals( 'new', $items[0]['type'] );
196 }
197
198 public function testTitlePropParameter() {
199 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
200 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
201 $this->doPageEdits(
202 $this->getLoggedInTestUser(),
203 [
204 [
205 'target' => $subjectTarget,
206 'summary' => 'Create the page',
207 ],
208 [
209 'target' => $talkTarget,
210 'summary' => 'Create Talk page',
211 ],
212 ]
213 );
214
215 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', ] );
216
217 $this->assertEquals(
218 [
219 [
220 'type' => 'new',
221 'ns' => $talkTarget->getNamespace(),
222 'title' => $this->getPrefixedText( $talkTarget ),
223 ],
224 [
225 'type' => 'new',
226 'ns' => $subjectTarget->getNamespace(),
227 'title' => $this->getPrefixedText( $subjectTarget ),
228 ],
229 ],
230 $this->getItemsFromApiResponse( $result )
231 );
232 }
233
234 public function testFlagsPropParameter() {
235 $normalEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
236 $minorEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPageM' );
237 $botEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPageB' );
238 $this->doPageEdits(
239 $this->getLoggedInTestUser(),
240 [
241 [
242 'target' => $normalEditTarget,
243 'summary' => 'Create the page',
244 ],
245 [
246 'target' => $minorEditTarget,
247 'summary' => 'Create the page',
248 ],
249 [
250 'target' => $minorEditTarget,
251 'summary' => 'Change content',
252 'minorEdit' => true,
253 ],
254 [
255 'target' => $botEditTarget,
256 'summary' => 'Create the page with a bot',
257 'botEdit' => true,
258 ],
259 ]
260 );
261
262 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'flags', ] );
263
264 $this->assertEquals(
265 [
266 [
267 'type' => 'new',
268 'new' => true,
269 'minor' => false,
270 'bot' => true,
271 ],
272 [
273 'type' => 'edit',
274 'new' => false,
275 'minor' => true,
276 'bot' => false,
277 ],
278 [
279 'type' => 'new',
280 'new' => true,
281 'minor' => false,
282 'bot' => false,
283 ],
284 [
285 'type' => 'new',
286 'new' => true,
287 'minor' => false,
288 'bot' => false,
289 ],
290 ],
291 $this->getItemsFromApiResponse( $result )
292 );
293 }
294
295 public function testUserPropParameter() {
296 $userEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
297 $anonEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPageA' );
298 $this->doPageEdit( $this->getLoggedInTestUser(), $userEditTarget, 'Create the page' );
299 $this->doAnonPageEdit( $anonEditTarget, 'Create the page' );
300
301 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'user', ] );
302
303 $this->assertEquals(
304 [
305 [
306 'type' => 'new',
307 'anon' => true,
308 'user' => User::newFromId( 0 )->getName(),
309 ],
310 [
311 'type' => 'new',
312 'user' => $this->getLoggedInTestUser()->getName(),
313 ],
314 ],
315 $this->getItemsFromApiResponse( $result )
316 );
317 }
318
319 public function testUserIdPropParameter() {
320 $user = $this->getLoggedInTestUser();
321 $userEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
322 $anonEditTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPageA' );
323 $this->doPageEdit( $user, $userEditTarget, 'Create the page' );
324 $this->doAnonPageEdit( $anonEditTarget, 'Create the page' );
325
326 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'userid', ] );
327
328 $this->assertEquals(
329 [
330 [
331 'type' => 'new',
332 'anon' => true,
333 'userid' => 0,
334 ],
335 [
336 'type' => 'new',
337 'userid' => $user->getId(),
338 ],
339 ],
340 $this->getItemsFromApiResponse( $result )
341 );
342 }
343
344 public function testCommentPropParameter() {
345 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
346 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the <b>page</b>' );
347
348 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'comment', ] );
349
350 $this->assertEquals(
351 [
352 [
353 'type' => 'new',
354 'comment' => 'Create the <b>page</b>',
355 ],
356 ],
357 $this->getItemsFromApiResponse( $result )
358 );
359 }
360
361 public function testParsedCommentPropParameter() {
362 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
363 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the <b>page</b>' );
364
365 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'parsedcomment', ] );
366
367 $this->assertEquals(
368 [
369 [
370 'type' => 'new',
371 'parsedcomment' => 'Create the &lt;b&gt;page&lt;/b&gt;',
372 ],
373 ],
374 $this->getItemsFromApiResponse( $result )
375 );
376 }
377
378 public function testTimestampPropParameter() {
379 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
380 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
381
382 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'timestamp', ] );
383 $items = $this->getItemsFromApiResponse( $result );
384
385 $this->assertCount( 1, $items );
386 $this->assertArrayHasKey( 'timestamp', $items[0] );
387 $this->assertInternalType( 'string', $items[0]['timestamp'] );
388 }
389
390 public function testSizesPropParameter() {
391 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
392 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
393
394 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'sizes', ] );
395
396 $this->assertEquals(
397 [
398 [
399 'type' => 'new',
400 'oldlen' => 0,
401 'newlen' => 38,
402 ],
403 ],
404 $this->getItemsFromApiResponse( $result )
405 );
406 }
407
408 private function createPageAndDeleteIt( LinkTarget $target ) {
409 $this->doPageEdit( $this->getLoggedInTestUser(),
410 $target,
411 'Create the page that will be deleted'
412 );
413 $this->deletePage( $target, 'Important Reason' );
414 }
415
416 public function testLoginfoPropParameter() {
417 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
418 $this->createPageAndDeleteIt( $target );
419
420 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'loginfo', ] );
421
422 $items = $this->getItemsFromApiResponse( $result );
423 $this->assertCount( 1, $items );
424 $this->assertArraySubset(
425 [
426 'type' => 'log',
427 'logtype' => 'delete',
428 'logaction' => 'delete',
429 'logparams' => [],
430 ],
431 $items[0]
432 );
433 $this->assertArrayHasKey( 'logid', $items[0] );
434 }
435
436 public function testEmptyPropParameter() {
437 $user = $this->getLoggedInTestUser();
438 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
439 $this->doPageEdit( $user, $target, 'Create the page' );
440
441 $result = $this->doListRecentChangesRequest( [ 'rcprop' => '', ] );
442
443 $this->assertEquals(
444 [
445 [
446 'type' => 'new',
447 ]
448 ],
449 $this->getItemsFromApiResponse( $result )
450 );
451 }
452
453 public function testNamespaceParam() {
454 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
455 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
456 $this->doPageEdits(
457 $this->getLoggedInTestUser(),
458 [
459 [
460 'target' => $subjectTarget,
461 'summary' => 'Create the page',
462 ],
463 [
464 'target' => $talkTarget,
465 'summary' => 'Create the talk page',
466 ],
467 ]
468 );
469
470 $result = $this->doListRecentChangesRequest( [ 'rcnamespace' => '0', ] );
471
472 $items = $this->getItemsFromApiResponse( $result );
473 $this->assertCount( 1, $items );
474 $this->assertArraySubset(
475 [
476 'ns' => 0,
477 'title' => $this->getPrefixedText( $subjectTarget ),
478 ],
479 $items[0]
480 );
481 }
482
483 public function testShowAnonParams() {
484 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
485 $this->doAnonPageEdit( $target, 'Create the page' );
486
487 $resultAnon = $this->doListRecentChangesRequest( [
488 'rcprop' => 'user',
489 'rcshow' => WatchedItemQueryService::FILTER_ANON
490 ] );
491 $resultNotAnon = $this->doListRecentChangesRequest( [
492 'rcprop' => 'user',
493 'rcshow' => WatchedItemQueryService::FILTER_NOT_ANON
494 ] );
495
496 $items = $this->getItemsFromApiResponse( $resultAnon );
497 $this->assertCount( 1, $items );
498 $this->assertArraySubset( [ 'anon' => true ], $items[0] );
499 $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotAnon ) );
500 }
501
502 public function testNewAndEditTypeParameters() {
503 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
504 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
505 $this->doPageEdits(
506 $this->getLoggedInTestUser(),
507 [
508 [
509 'target' => $subjectTarget,
510 'summary' => 'Create the page',
511 ],
512 [
513 'target' => $subjectTarget,
514 'summary' => 'Change the content',
515 ],
516 [
517 'target' => $talkTarget,
518 'summary' => 'Create Talk page',
519 ],
520 ]
521 );
522
523 $resultNew = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rctype' => 'new' ] );
524 $resultEdit = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rctype' => 'edit' ] );
525
526 $this->assertEquals(
527 [
528 [
529 'type' => 'new',
530 'ns' => $talkTarget->getNamespace(),
531 'title' => $this->getPrefixedText( $talkTarget ),
532 ],
533 [
534 'type' => 'new',
535 'ns' => $subjectTarget->getNamespace(),
536 'title' => $this->getPrefixedText( $subjectTarget ),
537 ],
538 ],
539 $this->getItemsFromApiResponse( $resultNew )
540 );
541 $this->assertEquals(
542 [
543 [
544 'type' => 'edit',
545 'ns' => $subjectTarget->getNamespace(),
546 'title' => $this->getPrefixedText( $subjectTarget ),
547 ],
548 ],
549 $this->getItemsFromApiResponse( $resultEdit )
550 );
551 }
552
553 public function testLogTypeParameters() {
554 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
555 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
556 $this->createPageAndDeleteIt( $subjectTarget );
557 $this->doPageEdit( $this->getLoggedInTestUser(), $talkTarget, 'Create Talk page' );
558
559 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rctype' => 'log' ] );
560
561 $this->assertEquals(
562 [
563 [
564 'type' => 'log',
565 'ns' => $subjectTarget->getNamespace(),
566 'title' => $this->getPrefixedText( $subjectTarget ),
567 ],
568 ],
569 $this->getItemsFromApiResponse( $result )
570 );
571 }
572
573 private function getExternalRC( LinkTarget $target ) {
574 $title = Title::newFromLinkTarget( $target );
575
576 $rc = new RecentChange;
577 $rc->mTitle = $title;
578 $rc->mAttribs = [
579 'rc_timestamp' => wfTimestamp( TS_MW ),
580 'rc_namespace' => $title->getNamespace(),
581 'rc_title' => $title->getDBkey(),
582 'rc_type' => RC_EXTERNAL,
583 'rc_source' => 'foo',
584 'rc_minor' => 0,
585 'rc_cur_id' => $title->getArticleID(),
586 'rc_user' => 0,
587 'rc_user_text' => 'm>External User',
588 'rc_comment' => '',
589 'rc_comment_text' => '',
590 'rc_comment_data' => null,
591 'rc_this_oldid' => $title->getLatestRevID(),
592 'rc_last_oldid' => $title->getLatestRevID(),
593 'rc_bot' => 0,
594 'rc_ip' => '',
595 'rc_patrolled' => 0,
596 'rc_new' => 0,
597 'rc_old_len' => $title->getLength(),
598 'rc_new_len' => $title->getLength(),
599 'rc_deleted' => 0,
600 'rc_logid' => 0,
601 'rc_log_type' => null,
602 'rc_log_action' => '',
603 'rc_params' => '',
604 ];
605 $rc->mExtra = [
606 'prefixedDBkey' => $title->getPrefixedDBkey(),
607 'lastTimestamp' => 0,
608 'oldSize' => $title->getLength(),
609 'newSize' => $title->getLength(),
610 'pageStatus' => 'changed'
611 ];
612
613 return $rc;
614 }
615
616 public function testExternalTypeParameters() {
617 $user = $this->getLoggedInTestUser();
618 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
619 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
620 $this->doPageEdit( $user, $subjectTarget, 'Create the page' );
621 $this->doPageEdit( $user, $talkTarget, 'Create Talk page' );
622
623 $rc = $this->getExternalRC( $subjectTarget );
624 $rc->save();
625
626 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rctype' => 'external' ] );
627
628 $this->assertEquals(
629 [
630 [
631 'type' => 'external',
632 'ns' => $subjectTarget->getNamespace(),
633 'title' => $this->getPrefixedText( $subjectTarget ),
634 ],
635 ],
636 $this->getItemsFromApiResponse( $result )
637 );
638 }
639
640 public function testCategorizeTypeParameter() {
641 $user = $this->getLoggedInTestUser();
642 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
643 $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryRecentChangesIntegrationTestCategory' );
644 $this->doPageEdits(
645 $user,
646 [
647 [
648 'target' => $categoryTarget,
649 'summary' => 'Create the category',
650 ],
651 [
652 'target' => $subjectTarget,
653 'summary' => 'Create the page and add it to the category',
654 ],
655 ]
656 );
657 $title = Title::newFromLinkTarget( $subjectTarget );
658 $revision = Revision::newFromTitle( $title );
659
660 $rc = RecentChange::newForCategorization(
661 $revision->getTimestamp(),
662 Title::newFromLinkTarget( $categoryTarget ),
663 $user,
664 $revision->getComment(),
665 $title,
666 0,
667 $revision->getId(),
668 null,
669 false
670 );
671 $rc->save();
672
673 $result = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rctype' => 'categorize' ] );
674
675 $this->assertEquals(
676 [
677 [
678 'type' => 'categorize',
679 'ns' => $categoryTarget->getNamespace(),
680 'title' => $this->getPrefixedText( $categoryTarget ),
681 ],
682 ],
683 $this->getItemsFromApiResponse( $result )
684 );
685 }
686
687 public function testLimitParam() {
688 $target1 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
689 $target2 = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
690 $target3 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage2' );
691 $this->doPageEdits(
692 $this->getLoggedInTestUser(),
693 [
694 [
695 'target' => $target1,
696 'summary' => 'Create the page',
697 ],
698 [
699 'target' => $target2,
700 'summary' => 'Create Talk page',
701 ],
702 [
703 'target' => $target3,
704 'summary' => 'Create the page',
705 ],
706 ]
707 );
708
709 $resultWithoutLimit = $this->doListRecentChangesRequest( [ 'rcprop' => 'title' ] );
710 $resultWithLimit = $this->doListRecentChangesRequest( [ 'rclimit' => 2, 'rcprop' => 'title' ] );
711
712 $this->assertEquals(
713 [
714 [
715 'type' => 'new',
716 'ns' => $target3->getNamespace(),
717 'title' => $this->getPrefixedText( $target3 )
718 ],
719 [
720 'type' => 'new',
721 'ns' => $target2->getNamespace(),
722 'title' => $this->getPrefixedText( $target2 )
723 ],
724 [
725 'type' => 'new',
726 'ns' => $target1->getNamespace(),
727 'title' => $this->getPrefixedText( $target1 )
728 ],
729 ],
730 $this->getItemsFromApiResponse( $resultWithoutLimit )
731 );
732 $this->assertEquals(
733 [
734 [
735 'type' => 'new',
736 'ns' => $target3->getNamespace(),
737 'title' => $this->getPrefixedText( $target3 )
738 ],
739 [
740 'type' => 'new',
741 'ns' => $target2->getNamespace(),
742 'title' => $this->getPrefixedText( $target2 )
743 ],
744 ],
745 $this->getItemsFromApiResponse( $resultWithLimit )
746 );
747 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
748 $this->assertArrayHasKey( 'rccontinue', $resultWithLimit[0]['continue'] );
749 }
750
751 public function testAllRevParam() {
752 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
753 $this->doPageEdits(
754 $this->getLoggedInTestUser(),
755 [
756 [
757 'target' => $target,
758 'summary' => 'Create the page',
759 ],
760 [
761 'target' => $target,
762 'summary' => 'Change the content',
763 ],
764 ]
765 );
766
767 $resultAllRev = $this->doListRecentChangesRequest( [ 'rcprop' => 'title', 'rcallrev' => '', ] );
768 $resultNoAllRev = $this->doListRecentChangesRequest( [ 'rcprop' => 'title' ] );
769
770 $this->assertEquals(
771 [
772 [
773 'type' => 'edit',
774 'ns' => $target->getNamespace(),
775 'title' => $this->getPrefixedText( $target ),
776 ],
777 [
778 'type' => 'new',
779 'ns' => $target->getNamespace(),
780 'title' => $this->getPrefixedText( $target ),
781 ],
782 ],
783 $this->getItemsFromApiResponse( $resultNoAllRev )
784 );
785 $this->assertEquals(
786 [
787 [
788 'type' => 'edit',
789 'ns' => $target->getNamespace(),
790 'title' => $this->getPrefixedText( $target ),
791 ],
792 [
793 'type' => 'new',
794 'ns' => $target->getNamespace(),
795 'title' => $this->getPrefixedText( $target ),
796 ],
797 ],
798 $this->getItemsFromApiResponse( $resultAllRev )
799 );
800 }
801
802 public function testDirParams() {
803 $subjectTarget = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
804 $talkTarget = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
805 $this->doPageEdits(
806 $this->getLoggedInTestUser(),
807 [
808 [
809 'target' => $subjectTarget,
810 'summary' => 'Create the page',
811 ],
812 [
813 'target' => $talkTarget,
814 'summary' => 'Create Talk page',
815 ],
816 ]
817 );
818
819 $resultDirOlder = $this->doListRecentChangesRequest(
820 [ 'rcdir' => 'older', 'rcprop' => 'title' ]
821 );
822 $resultDirNewer = $this->doListRecentChangesRequest(
823 [ 'rcdir' => 'newer', 'rcprop' => 'title' ]
824 );
825
826 $this->assertEquals(
827 [
828 [
829 'type' => 'new',
830 'ns' => $talkTarget->getNamespace(),
831 'title' => $this->getPrefixedText( $talkTarget )
832 ],
833 [
834 'type' => 'new',
835 'ns' => $subjectTarget->getNamespace(),
836 'title' => $this->getPrefixedText( $subjectTarget )
837 ],
838 ],
839 $this->getItemsFromApiResponse( $resultDirOlder )
840 );
841 $this->assertEquals(
842 [
843 [
844 'type' => 'new',
845 'ns' => $subjectTarget->getNamespace(),
846 'title' => $this->getPrefixedText( $subjectTarget )
847 ],
848 [
849 'type' => 'new',
850 'ns' => $talkTarget->getNamespace(),
851 'title' => $this->getPrefixedText( $talkTarget )
852 ],
853 ],
854 $this->getItemsFromApiResponse( $resultDirNewer )
855 );
856 }
857
858 public function testTitleParams() {
859 $page1 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
860 $page2 = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage2' );
861 $page3 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage3' );
862 $this->doPageEdits(
863 $this->getLoggedInTestUser(),
864 [
865 [
866 'target' => $page1,
867 'summary' => 'Create the page',
868 ],
869 [
870 'target' => $page2,
871 'summary' => 'Create the page',
872 ],
873 [
874 'target' => $page3,
875 'summary' => 'Create the page',
876 ],
877 ]
878 );
879
880 $result = $this->doListRecentChangesRequest(
881 [
882 'rctitle' => 'ApiQueryRecentChangesIntegrationTestPage',
883 'rcprop' => 'title'
884 ]
885 );
886
887 $result2 = $this->doListRecentChangesRequest(
888 [
889 'rctitle' => 'Talk:ApiQueryRecentChangesIntegrationTestPage2',
890 'rcprop' => 'title'
891 ]
892 );
893
894 $this->assertEquals(
895 [
896 [
897 'type' => 'new',
898 'ns' => $page1->getNamespace(),
899 'title' => $this->getPrefixedText( $page1 )
900 ],
901 ],
902 $this->getItemsFromApiResponse( $result )
903 );
904
905 $this->assertEquals(
906 [
907 [
908 'type' => 'new',
909 'ns' => $page2->getNamespace(),
910 'title' => $this->getPrefixedText( $page2 )
911 ],
912 ],
913 $this->getItemsFromApiResponse( $result2 )
914 );
915 }
916
917 public function testStartEndParams() {
918 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
919 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
920
921 $resultStart = $this->doListRecentChangesRequest( [
922 'rcstart' => '20010115000000',
923 'rcdir' => 'newer',
924 'rcprop' => 'title',
925 ] );
926 $resultEnd = $this->doListRecentChangesRequest( [
927 'rcend' => '20010115000000',
928 'rcdir' => 'newer',
929 'rcprop' => 'title',
930 ] );
931
932 $this->assertEquals(
933 [
934 [
935 'type' => 'new',
936 'ns' => $target->getNamespace(),
937 'title' => $this->getPrefixedText( $target ),
938 ]
939 ],
940 $this->getItemsFromApiResponse( $resultStart )
941 );
942 $this->assertEmpty( $this->getItemsFromApiResponse( $resultEnd ) );
943 }
944
945 public function testContinueParam() {
946 $target1 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
947 $target2 = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage' );
948 $target3 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage2' );
949 $this->doPageEdits(
950 $this->getLoggedInTestUser(),
951 [
952 [
953 'target' => $target1,
954 'summary' => 'Create the page',
955 ],
956 [
957 'target' => $target2,
958 'summary' => 'Create Talk page',
959 ],
960 [
961 'target' => $target3,
962 'summary' => 'Create the page',
963 ],
964 ]
965 );
966
967 $firstResult = $this->doListRecentChangesRequest( [ 'rclimit' => 2, 'rcprop' => 'title' ] );
968 $this->assertArrayHasKey( 'continue', $firstResult[0] );
969 $this->assertArrayHasKey( 'rccontinue', $firstResult[0]['continue'] );
970
971 $continuationParam = $firstResult[0]['continue']['rccontinue'];
972
973 $continuedResult = $this->doListRecentChangesRequest(
974 [ 'rccontinue' => $continuationParam, 'rcprop' => 'title' ]
975 );
976
977 $this->assertEquals(
978 [
979 [
980 'type' => 'new',
981 'ns' => $target3->getNamespace(),
982 'title' => $this->getPrefixedText( $target3 ),
983 ],
984 [
985 'type' => 'new',
986 'ns' => $target2->getNamespace(),
987 'title' => $this->getPrefixedText( $target2 ),
988 ],
989 ],
990 $this->getItemsFromApiResponse( $firstResult )
991 );
992 $this->assertEquals(
993 [
994 [
995 'type' => 'new',
996 'ns' => $target1->getNamespace(),
997 'title' => $this->getPrefixedText( $target1 )
998 ]
999 ],
1000 $this->getItemsFromApiResponse( $continuedResult )
1001 );
1002 }
1003
1004 public function testGeneratorRecentChangesPropInfo_returnsRCPages() {
1005 $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
1006 $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
1007
1008 $result = $this->doGeneratorRecentChangesRequest( [ 'prop' => 'info' ] );
1009
1010 $this->assertArrayHasKey( 'query', $result[0] );
1011 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
1012
1013 // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
1014 $pages = array_values( $result[0]['query']['pages'] );
1015
1016 $this->assertCount( 1, $pages );
1017 $this->assertArraySubset(
1018 [
1019 'ns' => $target->getNamespace(),
1020 'title' => $this->getPrefixedText( $target ),
1021 'new' => true,
1022 ],
1023 $pages[0]
1024 );
1025 }
1026
1027 }