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