Merge "Add phpdoc for some ApiQueryInfo properties"
[lhc/web/wiklou.git] / tests / phpunit / includes / page / WikiPageTest.php
1 <?php
2
3 /**
4 * @group ContentHandler
5 * @group Database
6 * ^--- important, causes temporary tables to be used instead of the real database
7 * @group medium
8 **/
9 class WikiPageTest extends MediaWikiLangTestCase {
10
11 protected $pages_to_delete;
12
13 function __construct( $name = null, array $data = array(), $dataName = '' ) {
14 parent::__construct( $name, $data, $dataName );
15
16 $this->tablesUsed = array_merge(
17 $this->tablesUsed,
18 array( 'page',
19 'revision',
20 'text',
21
22 'recentchanges',
23 'logging',
24
25 'page_props',
26 'pagelinks',
27 'categorylinks',
28 'langlinks',
29 'externallinks',
30 'imagelinks',
31 'templatelinks',
32 'iwlinks' ) );
33 }
34
35 protected function setUp() {
36 parent::setUp();
37 $this->pages_to_delete = array();
38
39 LinkCache::singleton()->clear(); # avoid cached redirect status, etc
40 }
41
42 protected function tearDown() {
43 foreach ( $this->pages_to_delete as $p ) {
44 /* @var $p WikiPage */
45
46 try {
47 if ( $p->exists() ) {
48 $p->doDeleteArticle( "testing done." );
49 }
50 } catch ( MWException $ex ) {
51 // fail silently
52 }
53 }
54 parent::tearDown();
55 }
56
57 /**
58 * @param Title|string $title
59 * @param string|null $model
60 * @return WikiPage
61 */
62 protected function newPage( $title, $model = null ) {
63 if ( is_string( $title ) ) {
64 $ns = $this->getDefaultWikitextNS();
65 $title = Title::newFromText( $title, $ns );
66 }
67
68 $p = new WikiPage( $title );
69
70 $this->pages_to_delete[] = $p;
71
72 return $p;
73 }
74
75 /**
76 * @param string|Title|WikiPage $page
77 * @param string $text
78 * @param int $model
79 *
80 * @return WikiPage
81 */
82 protected function createPage( $page, $text, $model = null ) {
83 if ( is_string( $page ) || $page instanceof Title ) {
84 $page = $this->newPage( $page, $model );
85 }
86
87 $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
88 $page->doEditContent( $content, "testing", EDIT_NEW );
89
90 return $page;
91 }
92
93 /**
94 * @covers WikiPage::doEditContent
95 */
96 public function testDoEditContent() {
97 $page = $this->newPage( "WikiPageTest_testDoEditContent" );
98 $title = $page->getTitle();
99
100 $content = ContentHandler::makeContent(
101 "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
102 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
103 $title,
104 CONTENT_MODEL_WIKITEXT
105 );
106
107 $page->doEditContent( $content, "[[testing]] 1" );
108
109 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
110 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
111 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
112 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
113
114 $id = $page->getId();
115
116 # ------------------------
117 $dbr = wfGetDB( DB_SLAVE );
118 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
119 $n = $res->numRows();
120 $res->free();
121
122 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
123
124 # ------------------------
125 $page = new WikiPage( $title );
126
127 $retrieved = $page->getContent();
128 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
129
130 # ------------------------
131 $content = ContentHandler::makeContent(
132 "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
133 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
134 $title,
135 CONTENT_MODEL_WIKITEXT
136 );
137
138 $page->doEditContent( $content, "testing 2" );
139
140 # ------------------------
141 $page = new WikiPage( $title );
142
143 $retrieved = $page->getContent();
144 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
145
146 # ------------------------
147 $dbr = wfGetDB( DB_SLAVE );
148 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
149 $n = $res->numRows();
150 $res->free();
151
152 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
153 }
154
155 /**
156 * @covers WikiPage::doEdit
157 */
158 public function testDoEdit() {
159 $this->hideDeprecated( "WikiPage::doEdit" );
160 $this->hideDeprecated( "WikiPage::getText" );
161 $this->hideDeprecated( "Revision::getText" );
162
163 // NOTE: assume help namespace will default to wikitext
164 $title = Title::newFromText( "Help:WikiPageTest_testDoEdit" );
165
166 $page = $this->newPage( $title );
167
168 $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
169 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
170
171 $page->doEdit( $text, "[[testing]] 1" );
172
173 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
174 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
175 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
176 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
177
178 $id = $page->getId();
179
180 # ------------------------
181 $dbr = wfGetDB( DB_SLAVE );
182 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
183 $n = $res->numRows();
184 $res->free();
185
186 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
187
188 # ------------------------
189 $page = new WikiPage( $title );
190
191 $retrieved = $page->getText();
192 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
193
194 # ------------------------
195 $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
196 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
197
198 $page->doEdit( $text, "testing 2" );
199
200 # ------------------------
201 $page = new WikiPage( $title );
202
203 $retrieved = $page->getText();
204 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
205
206 # ------------------------
207 $dbr = wfGetDB( DB_SLAVE );
208 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
209 $n = $res->numRows();
210 $res->free();
211
212 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
213 }
214
215 /**
216 * @covers WikiPage::doQuickEditContent
217 */
218 public function testDoQuickEditContent() {
219 global $wgUser;
220
221 $page = $this->createPage(
222 "WikiPageTest_testDoQuickEditContent",
223 "original text",
224 CONTENT_MODEL_WIKITEXT
225 );
226
227 $content = ContentHandler::makeContent(
228 "quick text",
229 $page->getTitle(),
230 CONTENT_MODEL_WIKITEXT
231 );
232 $page->doQuickEditContent( $content, $wgUser, "testing q" );
233
234 # ---------------------
235 $page = new WikiPage( $page->getTitle() );
236 $this->assertTrue( $content->equals( $page->getContent() ) );
237 }
238
239 /**
240 * @covers WikiPage::doDeleteArticle
241 */
242 public function testDoDeleteArticle() {
243 $page = $this->createPage(
244 "WikiPageTest_testDoDeleteArticle",
245 "[[original text]] foo",
246 CONTENT_MODEL_WIKITEXT
247 );
248 $id = $page->getId();
249
250 $page->doDeleteArticle( "testing deletion" );
251
252 $this->assertFalse(
253 $page->getTitle()->getArticleID() > 0,
254 "Title object should now have page id 0"
255 );
256 $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" );
257 $this->assertFalse(
258 $page->exists(),
259 "WikiPage::exists should return false after page was deleted"
260 );
261 $this->assertNull(
262 $page->getContent(),
263 "WikiPage::getContent should return null after page was deleted"
264 );
265 $this->assertFalse(
266 $page->getText(),
267 "WikiPage::getText should return false after page was deleted"
268 );
269
270 $t = Title::newFromText( $page->getTitle()->getPrefixedText() );
271 $this->assertFalse(
272 $t->exists(),
273 "Title::exists should return false after page was deleted"
274 );
275
276 // Run the job queue
277 JobQueueGroup::destroySingletons();
278 $jobs = new RunJobs;
279 $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null );
280 $jobs->execute();
281
282 # ------------------------
283 $dbr = wfGetDB( DB_SLAVE );
284 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
285 $n = $res->numRows();
286 $res->free();
287
288 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
289 }
290
291 /**
292 * @covers WikiPage::doDeleteUpdates
293 */
294 public function testDoDeleteUpdates() {
295 $page = $this->createPage(
296 "WikiPageTest_testDoDeleteArticle",
297 "[[original text]] foo",
298 CONTENT_MODEL_WIKITEXT
299 );
300 $id = $page->getId();
301
302 // Similar to MovePage logic
303 wfGetDB( DB_MASTER )->delete( 'page', array( 'page_id' => $id ), __METHOD__ );
304 $page->doDeleteUpdates( $id );
305
306 // Run the job queue
307 JobQueueGroup::destroySingletons();
308 $jobs = new RunJobs;
309 $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null );
310 $jobs->execute();
311
312 # ------------------------
313 $dbr = wfGetDB( DB_SLAVE );
314 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
315 $n = $res->numRows();
316 $res->free();
317
318 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
319 }
320
321 /**
322 * @covers WikiPage::getRevision
323 */
324 public function testGetRevision() {
325 $page = $this->newPage( "WikiPageTest_testGetRevision" );
326
327 $rev = $page->getRevision();
328 $this->assertNull( $rev );
329
330 # -----------------
331 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
332
333 $rev = $page->getRevision();
334
335 $this->assertEquals( $page->getLatest(), $rev->getId() );
336 $this->assertEquals( "some text", $rev->getContent()->getNativeData() );
337 }
338
339 /**
340 * @covers WikiPage::getContent
341 */
342 public function testGetContent() {
343 $page = $this->newPage( "WikiPageTest_testGetContent" );
344
345 $content = $page->getContent();
346 $this->assertNull( $content );
347
348 # -----------------
349 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
350
351 $content = $page->getContent();
352 $this->assertEquals( "some text", $content->getNativeData() );
353 }
354
355 /**
356 * @covers WikiPage::getText
357 */
358 public function testGetText() {
359 $this->hideDeprecated( "WikiPage::getText" );
360
361 $page = $this->newPage( "WikiPageTest_testGetText" );
362
363 $text = $page->getText();
364 $this->assertFalse( $text );
365
366 # -----------------
367 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
368
369 $text = $page->getText();
370 $this->assertEquals( "some text", $text );
371 }
372
373 /**
374 * @covers WikiPage::getContentModel
375 */
376 public function testGetContentModel() {
377 global $wgContentHandlerUseDB;
378
379 if ( !$wgContentHandlerUseDB ) {
380 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
381 }
382
383 $page = $this->createPage(
384 "WikiPageTest_testGetContentModel",
385 "some text",
386 CONTENT_MODEL_JAVASCRIPT
387 );
388
389 $page = new WikiPage( $page->getTitle() );
390 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
391 }
392
393 /**
394 * @covers WikiPage::getContentHandler
395 */
396 public function testGetContentHandler() {
397 global $wgContentHandlerUseDB;
398
399 if ( !$wgContentHandlerUseDB ) {
400 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
401 }
402
403 $page = $this->createPage(
404 "WikiPageTest_testGetContentHandler",
405 "some text",
406 CONTENT_MODEL_JAVASCRIPT
407 );
408
409 $page = new WikiPage( $page->getTitle() );
410 $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) );
411 }
412
413 /**
414 * @covers WikiPage::exists
415 */
416 public function testExists() {
417 $page = $this->newPage( "WikiPageTest_testExists" );
418 $this->assertFalse( $page->exists() );
419
420 # -----------------
421 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
422 $this->assertTrue( $page->exists() );
423
424 $page = new WikiPage( $page->getTitle() );
425 $this->assertTrue( $page->exists() );
426
427 # -----------------
428 $page->doDeleteArticle( "done testing" );
429 $this->assertFalse( $page->exists() );
430
431 $page = new WikiPage( $page->getTitle() );
432 $this->assertFalse( $page->exists() );
433 }
434
435 public static function provideHasViewableContent() {
436 return array(
437 array( 'WikiPageTest_testHasViewableContent', false, true ),
438 array( 'Special:WikiPageTest_testHasViewableContent', false ),
439 array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ),
440 array( 'Special:Userlogin', true ),
441 array( 'MediaWiki:help', true ),
442 );
443 }
444
445 /**
446 * @dataProvider provideHasViewableContent
447 * @covers WikiPage::hasViewableContent
448 */
449 public function testHasViewableContent( $title, $viewable, $create = false ) {
450 $page = $this->newPage( $title );
451 $this->assertEquals( $viewable, $page->hasViewableContent() );
452
453 if ( $create ) {
454 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
455 $this->assertTrue( $page->hasViewableContent() );
456
457 $page = new WikiPage( $page->getTitle() );
458 $this->assertTrue( $page->hasViewableContent() );
459 }
460 }
461
462 public static function provideGetRedirectTarget() {
463 return array(
464 array( 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT, "hello world", null ),
465 array(
466 'WikiPageTest_testGetRedirectTarget_2',
467 CONTENT_MODEL_WIKITEXT,
468 "#REDIRECT [[hello world]]",
469 "Hello world"
470 ),
471 );
472 }
473
474 /**
475 * @dataProvider provideGetRedirectTarget
476 * @covers WikiPage::getRedirectTarget
477 */
478 public function testGetRedirectTarget( $title, $model, $text, $target ) {
479 $this->setMwGlobals( array(
480 'wgCapitalLinks' => true,
481 ) );
482
483 $page = $this->createPage( $title, $text, $model );
484
485 # sanity check, because this test seems to fail for no reason for some people.
486 $c = $page->getContent();
487 $this->assertEquals( 'WikitextContent', get_class( $c ) );
488
489 # now, test the actual redirect
490 $t = $page->getRedirectTarget();
491 $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() );
492 }
493
494 /**
495 * @dataProvider provideGetRedirectTarget
496 * @covers WikiPage::isRedirect
497 */
498 public function testIsRedirect( $title, $model, $text, $target ) {
499 $page = $this->createPage( $title, $text, $model );
500 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
501 }
502
503 public static function provideIsCountable() {
504 return array(
505
506 // any
507 array( 'WikiPageTest_testIsCountable',
508 CONTENT_MODEL_WIKITEXT,
509 '',
510 'any',
511 true
512 ),
513 array( 'WikiPageTest_testIsCountable',
514 CONTENT_MODEL_WIKITEXT,
515 'Foo',
516 'any',
517 true
518 ),
519
520 // comma
521 array( 'WikiPageTest_testIsCountable',
522 CONTENT_MODEL_WIKITEXT,
523 'Foo',
524 'comma',
525 false
526 ),
527 array( 'WikiPageTest_testIsCountable',
528 CONTENT_MODEL_WIKITEXT,
529 'Foo, bar',
530 'comma',
531 true
532 ),
533
534 // link
535 array( 'WikiPageTest_testIsCountable',
536 CONTENT_MODEL_WIKITEXT,
537 'Foo',
538 'link',
539 false
540 ),
541 array( 'WikiPageTest_testIsCountable',
542 CONTENT_MODEL_WIKITEXT,
543 'Foo [[bar]]',
544 'link',
545 true
546 ),
547
548 // redirects
549 array( 'WikiPageTest_testIsCountable',
550 CONTENT_MODEL_WIKITEXT,
551 '#REDIRECT [[bar]]',
552 'any',
553 false
554 ),
555 array( 'WikiPageTest_testIsCountable',
556 CONTENT_MODEL_WIKITEXT,
557 '#REDIRECT [[bar]]',
558 'comma',
559 false
560 ),
561 array( 'WikiPageTest_testIsCountable',
562 CONTENT_MODEL_WIKITEXT,
563 '#REDIRECT [[bar]]',
564 'link',
565 false
566 ),
567
568 // not a content namespace
569 array( 'Talk:WikiPageTest_testIsCountable',
570 CONTENT_MODEL_WIKITEXT,
571 'Foo',
572 'any',
573 false
574 ),
575 array( 'Talk:WikiPageTest_testIsCountable',
576 CONTENT_MODEL_WIKITEXT,
577 'Foo, bar',
578 'comma',
579 false
580 ),
581 array( 'Talk:WikiPageTest_testIsCountable',
582 CONTENT_MODEL_WIKITEXT,
583 'Foo [[bar]]',
584 'link',
585 false
586 ),
587
588 // not a content namespace, different model
589 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
590 null,
591 'Foo',
592 'any',
593 false
594 ),
595 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
596 null,
597 'Foo, bar',
598 'comma',
599 false
600 ),
601 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
602 null,
603 'Foo [[bar]]',
604 'link',
605 false
606 ),
607 );
608 }
609
610 /**
611 * @dataProvider provideIsCountable
612 * @covers WikiPage::isCountable
613 */
614 public function testIsCountable( $title, $model, $text, $mode, $expected ) {
615 global $wgContentHandlerUseDB;
616
617 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
618
619 $title = Title::newFromText( $title );
620
621 if ( !$wgContentHandlerUseDB
622 && $model
623 && ContentHandler::getDefaultModelFor( $title ) != $model
624 ) {
625 $this->markTestSkipped( "Can not use non-default content model $model for "
626 . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled." );
627 }
628
629 $page = $this->createPage( $title, $text, $model );
630
631 $editInfo = $page->prepareContentForEdit( $page->getContent() );
632
633 $v = $page->isCountable();
634 $w = $page->isCountable( $editInfo );
635
636 $this->assertEquals(
637 $expected,
638 $v,
639 "isCountable( null ) returned unexpected value " . var_export( $v, true )
640 . " instead of " . var_export( $expected, true )
641 . " in mode `$mode` for text \"$text\""
642 );
643
644 $this->assertEquals(
645 $expected,
646 $w,
647 "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
648 . " instead of " . var_export( $expected, true )
649 . " in mode `$mode` for text \"$text\""
650 );
651 }
652
653 public static function provideGetParserOutput() {
654 return array(
655 array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ),
656 // @todo more...?
657 );
658 }
659
660 /**
661 * @dataProvider provideGetParserOutput
662 * @covers WikiPage::getParserOutput
663 */
664 public function testGetParserOutput( $model, $text, $expectedHtml ) {
665 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model );
666
667 $opt = $page->makeParserOptions( 'canonical' );
668 $po = $page->getParserOutput( $opt );
669 $text = $po->getText();
670
671 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
672 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
673
674 $this->assertEquals( $expectedHtml, $text );
675
676 return $po;
677 }
678
679 /**
680 * @covers WikiPage::getParserOutput
681 */
682 public function testGetParserOutput_nonexisting() {
683 static $count = 0;
684 $count++;
685
686 $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
687
688 $opt = new ParserOptions();
689 $po = $page->getParserOutput( $opt );
690
691 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
692 }
693
694 /**
695 * @covers WikiPage::getParserOutput
696 */
697 public function testGetParserOutput_badrev() {
698 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
699
700 $opt = new ParserOptions();
701 $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 );
702
703 // @todo would be neat to also test deleted revision
704
705 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." );
706 }
707
708 public static $sections =
709
710 "Intro
711
712 == stuff ==
713 hello world
714
715 == test ==
716 just a test
717
718 == foo ==
719 more stuff
720 ";
721
722 public function dataReplaceSection() {
723 // NOTE: assume the Help namespace to contain wikitext
724 return array(
725 array( 'Help:WikiPageTest_testReplaceSection',
726 CONTENT_MODEL_WIKITEXT,
727 WikiPageTest::$sections,
728 "0",
729 "No more",
730 null,
731 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
732 ),
733 array( 'Help:WikiPageTest_testReplaceSection',
734 CONTENT_MODEL_WIKITEXT,
735 WikiPageTest::$sections,
736 "",
737 "No more",
738 null,
739 "No more"
740 ),
741 array( 'Help:WikiPageTest_testReplaceSection',
742 CONTENT_MODEL_WIKITEXT,
743 WikiPageTest::$sections,
744 "2",
745 "== TEST ==\nmore fun",
746 null,
747 trim( preg_replace( '/^== test ==.*== foo ==/sm',
748 "== TEST ==\nmore fun\n\n== foo ==",
749 WikiPageTest::$sections ) )
750 ),
751 array( 'Help:WikiPageTest_testReplaceSection',
752 CONTENT_MODEL_WIKITEXT,
753 WikiPageTest::$sections,
754 "8",
755 "No more",
756 null,
757 trim( WikiPageTest::$sections )
758 ),
759 array( 'Help:WikiPageTest_testReplaceSection',
760 CONTENT_MODEL_WIKITEXT,
761 WikiPageTest::$sections,
762 "new",
763 "No more",
764 "New",
765 trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
766 ),
767 );
768 }
769
770 /**
771 * @dataProvider dataReplaceSection
772 * @covers WikiPage::replaceSection
773 */
774 public function testReplaceSection( $title, $model, $text, $section, $with,
775 $sectionTitle, $expected
776 ) {
777 $this->hideDeprecated( "WikiPage::replaceSection" );
778
779 $page = $this->createPage( $title, $text, $model );
780 $text = $page->replaceSection( $section, $with, $sectionTitle );
781 $text = trim( $text );
782
783 $this->assertEquals( $expected, $text );
784 }
785
786 /**
787 * @dataProvider dataReplaceSection
788 * @covers WikiPage::replaceSectionContent
789 */
790 public function testReplaceSectionContent( $title, $model, $text, $section,
791 $with, $sectionTitle, $expected
792 ) {
793 $page = $this->createPage( $title, $text, $model );
794
795 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
796 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
797
798 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
799 }
800
801 /**
802 * @dataProvider dataReplaceSection
803 * @covers WikiPage::replaceSectionAtRev
804 */
805 public function testReplaceSectionAtRev( $title, $model, $text, $section,
806 $with, $sectionTitle, $expected
807 ) {
808 $page = $this->createPage( $title, $text, $model );
809 $baseRevId = $page->getLatest();
810
811 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
812 $c = $page->replaceSectionAtRev( $section, $content, $sectionTitle, $baseRevId );
813
814 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
815 }
816
817 /* @todo FIXME: fix this!
818 public function testGetUndoText() {
819 $this->markTestSkippedIfNoDiff3();
820
821 $text = "one";
822 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
823 $rev1 = $page->getRevision();
824
825 $text .= "\n\ntwo";
826 $page->doEditContent(
827 ContentHandler::makeContent( $text, $page->getTitle() ),
828 "adding section two"
829 );
830 $rev2 = $page->getRevision();
831
832 $text .= "\n\nthree";
833 $page->doEditContent(
834 ContentHandler::makeContent( $text, $page->getTitle() ),
835 "adding section three"
836 );
837 $rev3 = $page->getRevision();
838
839 $text .= "\n\nfour";
840 $page->doEditContent(
841 ContentHandler::makeContent( $text, $page->getTitle() ),
842 "adding section four"
843 );
844 $rev4 = $page->getRevision();
845
846 $text .= "\n\nfive";
847 $page->doEditContent(
848 ContentHandler::makeContent( $text, $page->getTitle() ),
849 "adding section five"
850 );
851 $rev5 = $page->getRevision();
852
853 $text .= "\n\nsix";
854 $page->doEditContent(
855 ContentHandler::makeContent( $text, $page->getTitle() ),
856 "adding section six"
857 );
858 $rev6 = $page->getRevision();
859
860 $undo6 = $page->getUndoText( $rev6 );
861 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
862 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
863
864 $undo3 = $page->getUndoText( $rev4, $rev2 );
865 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
866 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
867
868 $undo2 = $page->getUndoText( $rev2 );
869 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
870 $this->assertEquals( "one\n\nfive", $undo2 );
871 }
872 */
873
874 /**
875 * @todo FIXME: this is a better rollback test than the one below, but it
876 * keeps failing in jenkins for some reason.
877 */
878 public function broken_testDoRollback() {
879 $admin = new User();
880 $admin->setName( "Admin" );
881
882 $text = "one";
883 $page = $this->newPage( "WikiPageTest_testDoRollback" );
884 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
885 "section one", EDIT_NEW, false, $admin );
886
887 $user1 = new User();
888 $user1->setName( "127.0.1.11" );
889 $text .= "\n\ntwo";
890 $page = new WikiPage( $page->getTitle() );
891 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
892 "adding section two", 0, false, $user1 );
893
894 $user2 = new User();
895 $user2->setName( "127.0.2.13" );
896 $text .= "\n\nthree";
897 $page = new WikiPage( $page->getTitle() );
898 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
899 "adding section three", 0, false, $user2 );
900
901 # we are having issues with doRollback spuriously failing. Apparently
902 # the last revision somehow goes missing or not committed under some
903 # circumstances. So, make sure the last revision has the right user name.
904 $dbr = wfGetDB( DB_SLAVE );
905 $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) );
906
907 $page = new WikiPage( $page->getTitle() );
908 $rev3 = $page->getRevision();
909 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
910
911 $rev2 = $rev3->getPrevious();
912 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
913
914 $rev1 = $rev2->getPrevious();
915 $this->assertEquals( 'Admin', $rev1->getUserText() );
916
917 # now, try the actual rollback
918 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
919 $token = $admin->getEditToken(
920 array( $page->getTitle()->getPrefixedText(), $user2->getName() ),
921 null
922 );
923 $errors = $page->doRollback(
924 $user2->getName(),
925 "testing revert",
926 $token,
927 false,
928 $details,
929 $admin
930 );
931
932 if ( $errors ) {
933 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
934 . ";\n" . print_r( $details, true ) );
935 }
936
937 $page = new WikiPage( $page->getTitle() );
938 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
939 "rollback did not revert to the correct revision" );
940 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
941 }
942
943 /**
944 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
945 * @covers WikiPage::doRollback
946 */
947 public function testDoRollback() {
948 $admin = new User();
949 $admin->setName( "Admin" );
950
951 $text = "one";
952 $page = $this->newPage( "WikiPageTest_testDoRollback" );
953 $page->doEditContent(
954 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
955 "section one",
956 EDIT_NEW,
957 false,
958 $admin
959 );
960 $rev1 = $page->getRevision();
961
962 $user1 = new User();
963 $user1->setName( "127.0.1.11" );
964 $text .= "\n\ntwo";
965 $page = new WikiPage( $page->getTitle() );
966 $page->doEditContent(
967 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
968 "adding section two",
969 0,
970 false,
971 $user1
972 );
973
974 # now, try the rollback
975 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
976 $token = $admin->getEditToken(
977 array( $page->getTitle()->getPrefixedText(), $user1->getName() ),
978 null
979 );
980 $errors = $page->doRollback(
981 $user1->getName(),
982 "testing revert",
983 $token,
984 false,
985 $details,
986 $admin
987 );
988
989 if ( $errors ) {
990 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
991 . ";\n" . print_r( $details, true ) );
992 }
993
994 $page = new WikiPage( $page->getTitle() );
995 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
996 "rollback did not revert to the correct revision" );
997 $this->assertEquals( "one", $page->getContent()->getNativeData() );
998 }
999
1000 /**
1001 * @covers WikiPage::doRollback
1002 */
1003 public function testDoRollbackFailureSameContent() {
1004 $admin = new User();
1005 $admin->setName( "Admin" );
1006 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
1007
1008 $text = "one";
1009 $page = $this->newPage( "WikiPageTest_testDoRollback" );
1010 $page->doEditContent(
1011 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
1012 "section one",
1013 EDIT_NEW,
1014 false,
1015 $admin
1016 );
1017 $rev1 = $page->getRevision();
1018
1019 $user1 = new User();
1020 $user1->setName( "127.0.1.11" );
1021 $user1->addGroup( "sysop" ); # XXX: make the test user a sysop...
1022 $text .= "\n\ntwo";
1023 $page = new WikiPage( $page->getTitle() );
1024 $page->doEditContent(
1025 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
1026 "adding section two",
1027 0,
1028 false,
1029 $user1
1030 );
1031
1032 # now, do a the rollback from the same user was doing the edit before
1033 $resultDetails = array();
1034 $token = $user1->getEditToken(
1035 array( $page->getTitle()->getPrefixedText(), $user1->getName() ),
1036 null
1037 );
1038 $errors = $page->doRollback(
1039 $user1->getName(),
1040 "testing revert same user",
1041 $token,
1042 false,
1043 $resultDetails,
1044 $admin
1045 );
1046
1047 $this->assertEquals( array(), $errors, "Rollback failed same user" );
1048
1049 # now, try the rollback
1050 $resultDetails = array();
1051 $token = $admin->getEditToken(
1052 array( $page->getTitle()->getPrefixedText(), $user1->getName() ),
1053 null
1054 );
1055 $errors = $page->doRollback(
1056 $user1->getName(),
1057 "testing revert",
1058 $token,
1059 false,
1060 $resultDetails,
1061 $admin
1062 );
1063
1064 $this->assertEquals( array( array( 'alreadyrolled', 'WikiPageTest testDoRollback',
1065 '127.0.1.11', 'Admin' ) ), $errors, "Rollback not failed" );
1066
1067 $page = new WikiPage( $page->getTitle() );
1068 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
1069 "rollback did not revert to the correct revision" );
1070 $this->assertEquals( "one", $page->getContent()->getNativeData() );
1071 }
1072
1073 public static function provideGetAutosummary() {
1074 return array(
1075 array(
1076 'Hello there, world!',
1077 '#REDIRECT [[Foo]]',
1078 0,
1079 '/^Redirected page .*Foo/'
1080 ),
1081
1082 array(
1083 null,
1084 'Hello world!',
1085 EDIT_NEW,
1086 '/^Created page .*Hello/'
1087 ),
1088
1089 array(
1090 'Hello there, world!',
1091 '',
1092 0,
1093 '/^Blanked/'
1094 ),
1095
1096 array(
1097 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
1098 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
1099 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
1100 clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
1101 'Hello world!',
1102 0,
1103 '/^Replaced .*Hello/'
1104 ),
1105
1106 array(
1107 'foo',
1108 'bar',
1109 0,
1110 '/^$/'
1111 ),
1112 );
1113 }
1114
1115 /**
1116 * @dataProvider provideGetAutoSummary
1117 * @covers WikiPage::getAutosummary
1118 */
1119 public function testGetAutosummary( $old, $new, $flags, $expected ) {
1120 $this->hideDeprecated( "WikiPage::getAutosummary" );
1121
1122 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
1123
1124 $summary = $page->getAutosummary( $old, $new, $flags );
1125
1126 $this->assertTrue( (bool)preg_match( $expected, $summary ),
1127 "Autosummary didn't match expected pattern $expected: $summary" );
1128 }
1129
1130 public static function provideGetAutoDeleteReason() {
1131 return array(
1132 array(
1133 array(),
1134 false,
1135 false
1136 ),
1137
1138 array(
1139 array(
1140 array( "first edit", null ),
1141 ),
1142 "/first edit.*only contributor/",
1143 false
1144 ),
1145
1146 array(
1147 array(
1148 array( "first edit", null ),
1149 array( "second edit", null ),
1150 ),
1151 "/second edit.*only contributor/",
1152 true
1153 ),
1154
1155 array(
1156 array(
1157 array( "first edit", "127.0.2.22" ),
1158 array( "second edit", "127.0.3.33" ),
1159 ),
1160 "/second edit/",
1161 true
1162 ),
1163
1164 array(
1165 array(
1166 array(
1167 "first edit: "
1168 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
1169 . " nonumy eirmod tempor invidunt ut labore et dolore magna "
1170 . "aliquyam erat, sed diam voluptua. At vero eos et accusam "
1171 . "et justo duo dolores et ea rebum. Stet clita kasd gubergren, "
1172 . "no sea takimata sanctus est Lorem ipsum dolor sit amet.'",
1173 null
1174 ),
1175 ),
1176 '/first edit:.*\.\.\."/',
1177 false
1178 ),
1179
1180 array(
1181 array(
1182 array( "first edit", "127.0.2.22" ),
1183 array( "", "127.0.3.33" ),
1184 ),
1185 "/before blanking.*first edit/",
1186 true
1187 ),
1188
1189 );
1190 }
1191
1192 /**
1193 * @dataProvider provideGetAutoDeleteReason
1194 * @covers WikiPage::getAutoDeleteReason
1195 */
1196 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
1197 global $wgUser;
1198
1199 // NOTE: assume Help namespace to contain wikitext
1200 $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" );
1201
1202 $c = 1;
1203
1204 foreach ( $edits as $edit ) {
1205 $user = new User();
1206
1207 if ( !empty( $edit[1] ) ) {
1208 $user->setName( $edit[1] );
1209 } else {
1210 $user = $wgUser;
1211 }
1212
1213 $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
1214
1215 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user );
1216
1217 $c += 1;
1218 }
1219
1220 $reason = $page->getAutoDeleteReason( $hasHistory );
1221
1222 if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) {
1223 $this->assertEquals( $expectedResult, $reason );
1224 } else {
1225 $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
1226 "Autosummary didn't match expected pattern $expectedResult: $reason" );
1227 }
1228
1229 $this->assertEquals( $expectedHistory, $hasHistory,
1230 "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
1231
1232 $page->doDeleteArticle( "done" );
1233 }
1234
1235 public static function providePreSaveTransform() {
1236 return array(
1237 array( 'hello this is ~~~',
1238 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
1239 ),
1240 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1241 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1242 ),
1243 );
1244 }
1245
1246 /**
1247 * @covers WikiPage::factory
1248 */
1249 public function testWikiPageFactory() {
1250 $title = Title::makeTitle( NS_FILE, 'Someimage.png' );
1251 $page = WikiPage::factory( $title );
1252 $this->assertEquals( 'WikiFilePage', get_class( $page ) );
1253
1254 $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
1255 $page = WikiPage::factory( $title );
1256 $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
1257
1258 $title = Title::makeTitle( NS_MAIN, 'SomePage' );
1259 $page = WikiPage::factory( $title );
1260 $this->assertEquals( 'WikiPage', get_class( $page ) );
1261 }
1262 }