Fix DatabaseSqlite IDEA warnings
[mediawiki.git] / tests / phpunit / includes / page / WikiPageTest.php
blob4b7ebd3ab323221835e5a6d3c66e10592e8c0f3f
1 <?php
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 {
11 protected $pages_to_delete;
13 function __construct( $name = null, array $data = [], $dataName = '' ) {
14 parent::__construct( $name, $data, $dataName );
16 $this->tablesUsed = array_merge(
17 $this->tablesUsed,
18 [ 'page',
19 'revision',
20 'text',
22 'recentchanges',
23 'logging',
25 'page_props',
26 'pagelinks',
27 'categorylinks',
28 'langlinks',
29 'externallinks',
30 'imagelinks',
31 'templatelinks',
32 'iwlinks' ] );
35 protected function setUp() {
36 parent::setUp();
37 $this->pages_to_delete = [];
39 LinkCache::singleton()->clear(); # avoid cached redirect status, etc
42 protected function tearDown() {
43 foreach ( $this->pages_to_delete as $p ) {
44 /* @var $p WikiPage */
46 try {
47 if ( $p->exists() ) {
48 $p->doDeleteArticle( "testing done." );
50 } catch ( MWException $ex ) {
51 // fail silently
54 parent::tearDown();
57 /**
58 * @param Title|string $title
59 * @param string|null $model
60 * @return WikiPage
62 protected function newPage( $title, $model = null ) {
63 if ( is_string( $title ) ) {
64 $ns = $this->getDefaultWikitextNS();
65 $title = Title::newFromText( $title, $ns );
68 $p = new WikiPage( $title );
70 $this->pages_to_delete[] = $p;
72 return $p;
75 /**
76 * @param string|Title|WikiPage $page
77 * @param string $text
78 * @param int $model
80 * @return WikiPage
82 protected function createPage( $page, $text, $model = null ) {
83 if ( is_string( $page ) || $page instanceof Title ) {
84 $page = $this->newPage( $page, $model );
87 $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
88 $page->doEditContent( $content, "testing", EDIT_NEW );
90 return $page;
93 /**
94 * @covers WikiPage::doEditContent
95 * @covers WikiPage::doModify
96 * @covers WikiPage::doCreate
97 * @covers WikiPage::doEditUpdates
99 public function testDoEditContent() {
100 $page = $this->newPage( "WikiPageTest_testDoEditContent" );
101 $title = $page->getTitle();
103 $content = ContentHandler::makeContent(
104 "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
105 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
106 $title,
107 CONTENT_MODEL_WIKITEXT
110 $page->doEditContent( $content, "[[testing]] 1" );
112 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
113 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
114 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
115 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
117 $id = $page->getId();
119 # ------------------------
120 $dbr = wfGetDB( DB_SLAVE );
121 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
122 $n = $res->numRows();
123 $res->free();
125 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
127 # ------------------------
128 $page = new WikiPage( $title );
130 $retrieved = $page->getContent();
131 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
133 # ------------------------
134 $content = ContentHandler::makeContent(
135 "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
136 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
137 $title,
138 CONTENT_MODEL_WIKITEXT
141 $page->doEditContent( $content, "testing 2" );
143 # ------------------------
144 $page = new WikiPage( $title );
146 $retrieved = $page->getContent();
147 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
149 # ------------------------
150 $dbr = wfGetDB( DB_SLAVE );
151 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
152 $n = $res->numRows();
153 $res->free();
155 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
159 * @covers WikiPage::doEdit
160 * @deprecated since 1.21. Should be removed when WikiPage::doEdit() gets removed
162 public function testDoEdit() {
163 $this->hideDeprecated( "WikiPage::doEdit" );
164 $this->hideDeprecated( "WikiPage::getText" );
165 $this->hideDeprecated( "Revision::getText" );
167 // NOTE: assume help namespace will default to wikitext
168 $title = Title::newFromText( "Help:WikiPageTest_testDoEdit" );
170 $page = $this->newPage( $title );
172 $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
173 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
175 $page->doEdit( $text, "[[testing]] 1" );
177 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
178 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
179 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
180 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
182 $id = $page->getId();
184 # ------------------------
185 $dbr = wfGetDB( DB_SLAVE );
186 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
187 $n = $res->numRows();
188 $res->free();
190 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
192 # ------------------------
193 $page = new WikiPage( $title );
195 $retrieved = $page->getText();
196 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
198 # ------------------------
199 $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
200 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
202 $page->doEdit( $text, "testing 2" );
204 # ------------------------
205 $page = new WikiPage( $title );
207 $retrieved = $page->getText();
208 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
210 # ------------------------
211 $dbr = wfGetDB( DB_SLAVE );
212 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
213 $n = $res->numRows();
214 $res->free();
216 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
220 * @covers WikiPage::doDeleteArticle
222 public function testDoDeleteArticle() {
223 $page = $this->createPage(
224 "WikiPageTest_testDoDeleteArticle",
225 "[[original text]] foo",
226 CONTENT_MODEL_WIKITEXT
228 $id = $page->getId();
230 $page->doDeleteArticle( "testing deletion" );
232 $this->assertFalse(
233 $page->getTitle()->getArticleID() > 0,
234 "Title object should now have page id 0"
236 $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" );
237 $this->assertFalse(
238 $page->exists(),
239 "WikiPage::exists should return false after page was deleted"
241 $this->assertNull(
242 $page->getContent(),
243 "WikiPage::getContent should return null after page was deleted"
245 $this->assertFalse(
246 $page->getText(),
247 "WikiPage::getText should return false after page was deleted"
250 $t = Title::newFromText( $page->getTitle()->getPrefixedText() );
251 $this->assertFalse(
252 $t->exists(),
253 "Title::exists should return false after page was deleted"
256 // Run the job queue
257 JobQueueGroup::destroySingletons();
258 $jobs = new RunJobs;
259 $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
260 $jobs->execute();
262 # ------------------------
263 $dbr = wfGetDB( DB_SLAVE );
264 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
265 $n = $res->numRows();
266 $res->free();
268 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
272 * @covers WikiPage::doDeleteUpdates
274 public function testDoDeleteUpdates() {
275 $page = $this->createPage(
276 "WikiPageTest_testDoDeleteArticle",
277 "[[original text]] foo",
278 CONTENT_MODEL_WIKITEXT
280 $id = $page->getId();
282 // Similar to MovePage logic
283 wfGetDB( DB_MASTER )->delete( 'page', [ 'page_id' => $id ], __METHOD__ );
284 $page->doDeleteUpdates( $id );
286 // Run the job queue
287 JobQueueGroup::destroySingletons();
288 $jobs = new RunJobs;
289 $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
290 $jobs->execute();
292 # ------------------------
293 $dbr = wfGetDB( DB_SLAVE );
294 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
295 $n = $res->numRows();
296 $res->free();
298 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
302 * @covers WikiPage::getRevision
304 public function testGetRevision() {
305 $page = $this->newPage( "WikiPageTest_testGetRevision" );
307 $rev = $page->getRevision();
308 $this->assertNull( $rev );
310 # -----------------
311 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
313 $rev = $page->getRevision();
315 $this->assertEquals( $page->getLatest(), $rev->getId() );
316 $this->assertEquals( "some text", $rev->getContent()->getNativeData() );
320 * @covers WikiPage::getContent
322 public function testGetContent() {
323 $page = $this->newPage( "WikiPageTest_testGetContent" );
325 $content = $page->getContent();
326 $this->assertNull( $content );
328 # -----------------
329 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
331 $content = $page->getContent();
332 $this->assertEquals( "some text", $content->getNativeData() );
336 * @covers WikiPage::getText
338 public function testGetText() {
339 $this->hideDeprecated( "WikiPage::getText" );
341 $page = $this->newPage( "WikiPageTest_testGetText" );
343 $text = $page->getText();
344 $this->assertFalse( $text );
346 # -----------------
347 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
349 $text = $page->getText();
350 $this->assertEquals( "some text", $text );
354 * @covers WikiPage::getContentModel
356 public function testGetContentModel() {
357 global $wgContentHandlerUseDB;
359 if ( !$wgContentHandlerUseDB ) {
360 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
363 $page = $this->createPage(
364 "WikiPageTest_testGetContentModel",
365 "some text",
366 CONTENT_MODEL_JAVASCRIPT
369 $page = new WikiPage( $page->getTitle() );
370 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
374 * @covers WikiPage::getContentHandler
376 public function testGetContentHandler() {
377 global $wgContentHandlerUseDB;
379 if ( !$wgContentHandlerUseDB ) {
380 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
383 $page = $this->createPage(
384 "WikiPageTest_testGetContentHandler",
385 "some text",
386 CONTENT_MODEL_JAVASCRIPT
389 $page = new WikiPage( $page->getTitle() );
390 $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) );
394 * @covers WikiPage::exists
396 public function testExists() {
397 $page = $this->newPage( "WikiPageTest_testExists" );
398 $this->assertFalse( $page->exists() );
400 # -----------------
401 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
402 $this->assertTrue( $page->exists() );
404 $page = new WikiPage( $page->getTitle() );
405 $this->assertTrue( $page->exists() );
407 # -----------------
408 $page->doDeleteArticle( "done testing" );
409 $this->assertFalse( $page->exists() );
411 $page = new WikiPage( $page->getTitle() );
412 $this->assertFalse( $page->exists() );
415 public static function provideHasViewableContent() {
416 return [
417 [ 'WikiPageTest_testHasViewableContent', false, true ],
418 [ 'Special:WikiPageTest_testHasViewableContent', false ],
419 [ 'MediaWiki:WikiPageTest_testHasViewableContent', false ],
420 [ 'Special:Userlogin', true ],
421 [ 'MediaWiki:help', true ],
426 * @dataProvider provideHasViewableContent
427 * @covers WikiPage::hasViewableContent
429 public function testHasViewableContent( $title, $viewable, $create = false ) {
430 $page = $this->newPage( $title );
431 $this->assertEquals( $viewable, $page->hasViewableContent() );
433 if ( $create ) {
434 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
435 $this->assertTrue( $page->hasViewableContent() );
437 $page = new WikiPage( $page->getTitle() );
438 $this->assertTrue( $page->hasViewableContent() );
442 public static function provideGetRedirectTarget() {
443 return [
444 [ 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT, "hello world", null ],
446 'WikiPageTest_testGetRedirectTarget_2',
447 CONTENT_MODEL_WIKITEXT,
448 "#REDIRECT [[hello world]]",
449 "Hello world"
455 * @dataProvider provideGetRedirectTarget
456 * @covers WikiPage::getRedirectTarget
458 public function testGetRedirectTarget( $title, $model, $text, $target ) {
459 $this->setMwGlobals( [
460 'wgCapitalLinks' => true,
461 ] );
463 $page = $this->createPage( $title, $text, $model );
465 # sanity check, because this test seems to fail for no reason for some people.
466 $c = $page->getContent();
467 $this->assertEquals( 'WikitextContent', get_class( $c ) );
469 # now, test the actual redirect
470 $t = $page->getRedirectTarget();
471 $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() );
475 * @dataProvider provideGetRedirectTarget
476 * @covers WikiPage::isRedirect
478 public function testIsRedirect( $title, $model, $text, $target ) {
479 $page = $this->createPage( $title, $text, $model );
480 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
483 public static function provideIsCountable() {
484 return [
486 // any
487 [ 'WikiPageTest_testIsCountable',
488 CONTENT_MODEL_WIKITEXT,
490 'any',
491 true
493 [ 'WikiPageTest_testIsCountable',
494 CONTENT_MODEL_WIKITEXT,
495 'Foo',
496 'any',
497 true
500 // comma
501 [ 'WikiPageTest_testIsCountable',
502 CONTENT_MODEL_WIKITEXT,
503 'Foo',
504 'comma',
505 false
507 [ 'WikiPageTest_testIsCountable',
508 CONTENT_MODEL_WIKITEXT,
509 'Foo, bar',
510 'comma',
511 true
514 // link
515 [ 'WikiPageTest_testIsCountable',
516 CONTENT_MODEL_WIKITEXT,
517 'Foo',
518 'link',
519 false
521 [ 'WikiPageTest_testIsCountable',
522 CONTENT_MODEL_WIKITEXT,
523 'Foo [[bar]]',
524 'link',
525 true
528 // redirects
529 [ 'WikiPageTest_testIsCountable',
530 CONTENT_MODEL_WIKITEXT,
531 '#REDIRECT [[bar]]',
532 'any',
533 false
535 [ 'WikiPageTest_testIsCountable',
536 CONTENT_MODEL_WIKITEXT,
537 '#REDIRECT [[bar]]',
538 'comma',
539 false
541 [ 'WikiPageTest_testIsCountable',
542 CONTENT_MODEL_WIKITEXT,
543 '#REDIRECT [[bar]]',
544 'link',
545 false
548 // not a content namespace
549 [ 'Talk:WikiPageTest_testIsCountable',
550 CONTENT_MODEL_WIKITEXT,
551 'Foo',
552 'any',
553 false
555 [ 'Talk:WikiPageTest_testIsCountable',
556 CONTENT_MODEL_WIKITEXT,
557 'Foo, bar',
558 'comma',
559 false
561 [ 'Talk:WikiPageTest_testIsCountable',
562 CONTENT_MODEL_WIKITEXT,
563 'Foo [[bar]]',
564 'link',
565 false
568 // not a content namespace, different model
569 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
570 null,
571 'Foo',
572 'any',
573 false
575 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
576 null,
577 'Foo, bar',
578 'comma',
579 false
581 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
582 null,
583 'Foo [[bar]]',
584 'link',
585 false
591 * @dataProvider provideIsCountable
592 * @covers WikiPage::isCountable
594 public function testIsCountable( $title, $model, $text, $mode, $expected ) {
595 global $wgContentHandlerUseDB;
597 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
599 $title = Title::newFromText( $title );
601 if ( !$wgContentHandlerUseDB
602 && $model
603 && ContentHandler::getDefaultModelFor( $title ) != $model
605 $this->markTestSkipped( "Can not use non-default content model $model for "
606 . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled." );
609 $page = $this->createPage( $title, $text, $model );
611 $editInfo = $page->prepareContentForEdit( $page->getContent() );
613 $v = $page->isCountable();
614 $w = $page->isCountable( $editInfo );
616 $this->assertEquals(
617 $expected,
619 "isCountable( null ) returned unexpected value " . var_export( $v, true )
620 . " instead of " . var_export( $expected, true )
621 . " in mode `$mode` for text \"$text\""
624 $this->assertEquals(
625 $expected,
627 "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
628 . " instead of " . var_export( $expected, true )
629 . " in mode `$mode` for text \"$text\""
633 public static function provideGetParserOutput() {
634 return [
635 [ CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ],
636 // @todo more...?
641 * @dataProvider provideGetParserOutput
642 * @covers WikiPage::getParserOutput
644 public function testGetParserOutput( $model, $text, $expectedHtml ) {
645 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model );
647 $opt = $page->makeParserOptions( 'canonical' );
648 $po = $page->getParserOutput( $opt );
649 $text = $po->getText();
651 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
652 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
654 $this->assertEquals( $expectedHtml, $text );
656 return $po;
660 * @covers WikiPage::getParserOutput
662 public function testGetParserOutput_nonexisting() {
663 static $count = 0;
664 $count++;
666 $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
668 $opt = new ParserOptions();
669 $po = $page->getParserOutput( $opt );
671 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
675 * @covers WikiPage::getParserOutput
677 public function testGetParserOutput_badrev() {
678 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
680 $opt = new ParserOptions();
681 $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 );
683 // @todo would be neat to also test deleted revision
685 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." );
688 public static $sections =
690 "Intro
692 == stuff ==
693 hello world
695 == test ==
696 just a test
698 == foo ==
699 more stuff
702 public function dataReplaceSection() {
703 // NOTE: assume the Help namespace to contain wikitext
704 return [
705 [ 'Help:WikiPageTest_testReplaceSection',
706 CONTENT_MODEL_WIKITEXT,
707 WikiPageTest::$sections,
708 "0",
709 "No more",
710 null,
711 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
713 [ 'Help:WikiPageTest_testReplaceSection',
714 CONTENT_MODEL_WIKITEXT,
715 WikiPageTest::$sections,
717 "No more",
718 null,
719 "No more"
721 [ 'Help:WikiPageTest_testReplaceSection',
722 CONTENT_MODEL_WIKITEXT,
723 WikiPageTest::$sections,
724 "2",
725 "== TEST ==\nmore fun",
726 null,
727 trim( preg_replace( '/^== test ==.*== foo ==/sm',
728 "== TEST ==\nmore fun\n\n== foo ==",
729 WikiPageTest::$sections ) )
731 [ 'Help:WikiPageTest_testReplaceSection',
732 CONTENT_MODEL_WIKITEXT,
733 WikiPageTest::$sections,
734 "8",
735 "No more",
736 null,
737 trim( WikiPageTest::$sections )
739 [ 'Help:WikiPageTest_testReplaceSection',
740 CONTENT_MODEL_WIKITEXT,
741 WikiPageTest::$sections,
742 "new",
743 "No more",
744 "New",
745 trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
751 * @dataProvider dataReplaceSection
752 * @covers WikiPage::replaceSectionContent
754 public function testReplaceSectionContent( $title, $model, $text, $section,
755 $with, $sectionTitle, $expected
757 $page = $this->createPage( $title, $text, $model );
759 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
760 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
762 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
766 * @dataProvider dataReplaceSection
767 * @covers WikiPage::replaceSectionAtRev
769 public function testReplaceSectionAtRev( $title, $model, $text, $section,
770 $with, $sectionTitle, $expected
772 $page = $this->createPage( $title, $text, $model );
773 $baseRevId = $page->getLatest();
775 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
776 $c = $page->replaceSectionAtRev( $section, $content, $sectionTitle, $baseRevId );
778 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
781 /* @todo FIXME: fix this!
782 public function testGetUndoText() {
783 $this->markTestSkippedIfNoDiff3();
785 $text = "one";
786 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
787 $rev1 = $page->getRevision();
789 $text .= "\n\ntwo";
790 $page->doEditContent(
791 ContentHandler::makeContent( $text, $page->getTitle() ),
792 "adding section two"
794 $rev2 = $page->getRevision();
796 $text .= "\n\nthree";
797 $page->doEditContent(
798 ContentHandler::makeContent( $text, $page->getTitle() ),
799 "adding section three"
801 $rev3 = $page->getRevision();
803 $text .= "\n\nfour";
804 $page->doEditContent(
805 ContentHandler::makeContent( $text, $page->getTitle() ),
806 "adding section four"
808 $rev4 = $page->getRevision();
810 $text .= "\n\nfive";
811 $page->doEditContent(
812 ContentHandler::makeContent( $text, $page->getTitle() ),
813 "adding section five"
815 $rev5 = $page->getRevision();
817 $text .= "\n\nsix";
818 $page->doEditContent(
819 ContentHandler::makeContent( $text, $page->getTitle() ),
820 "adding section six"
822 $rev6 = $page->getRevision();
824 $undo6 = $page->getUndoText( $rev6 );
825 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
826 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
828 $undo3 = $page->getUndoText( $rev4, $rev2 );
829 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
830 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
832 $undo2 = $page->getUndoText( $rev2 );
833 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
834 $this->assertEquals( "one\n\nfive", $undo2 );
839 * @todo FIXME: this is a better rollback test than the one below, but it
840 * keeps failing in jenkins for some reason.
842 public function broken_testDoRollback() {
843 $admin = new User();
844 $admin->setName( "Admin" );
846 $text = "one";
847 $page = $this->newPage( "WikiPageTest_testDoRollback" );
848 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
849 "section one", EDIT_NEW, false, $admin );
851 $user1 = new User();
852 $user1->setName( "127.0.1.11" );
853 $text .= "\n\ntwo";
854 $page = new WikiPage( $page->getTitle() );
855 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
856 "adding section two", 0, false, $user1 );
858 $user2 = new User();
859 $user2->setName( "127.0.2.13" );
860 $text .= "\n\nthree";
861 $page = new WikiPage( $page->getTitle() );
862 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
863 "adding section three", 0, false, $user2 );
865 # we are having issues with doRollback spuriously failing. Apparently
866 # the last revision somehow goes missing or not committed under some
867 # circumstances. So, make sure the last revision has the right user name.
868 $dbr = wfGetDB( DB_SLAVE );
869 $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) );
871 $page = new WikiPage( $page->getTitle() );
872 $rev3 = $page->getRevision();
873 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
875 $rev2 = $rev3->getPrevious();
876 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
878 $rev1 = $rev2->getPrevious();
879 $this->assertEquals( 'Admin', $rev1->getUserText() );
881 # now, try the actual rollback
882 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
883 $token = $admin->getEditToken(
884 [ $page->getTitle()->getPrefixedText(), $user2->getName() ],
885 null
887 $errors = $page->doRollback(
888 $user2->getName(),
889 "testing revert",
890 $token,
891 false,
892 $details,
893 $admin
896 if ( $errors ) {
897 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
898 . ";\n" . print_r( $details, true ) );
901 $page = new WikiPage( $page->getTitle() );
902 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
903 "rollback did not revert to the correct revision" );
904 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
908 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
909 * @covers WikiPage::doRollback
911 public function testDoRollback() {
912 $admin = new User();
913 $admin->setName( "Admin" );
915 $text = "one";
916 $page = $this->newPage( "WikiPageTest_testDoRollback" );
917 $page->doEditContent(
918 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
919 "section one",
920 EDIT_NEW,
921 false,
922 $admin
924 $rev1 = $page->getRevision();
926 $user1 = new User();
927 $user1->setName( "127.0.1.11" );
928 $text .= "\n\ntwo";
929 $page = new WikiPage( $page->getTitle() );
930 $page->doEditContent(
931 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
932 "adding section two",
934 false,
935 $user1
938 # now, try the rollback
939 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
940 $token = $admin->getEditToken(
941 [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
942 null
944 $errors = $page->doRollback(
945 $user1->getName(),
946 "testing revert",
947 $token,
948 false,
949 $details,
950 $admin
953 if ( $errors ) {
954 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
955 . ";\n" . print_r( $details, true ) );
958 $page = new WikiPage( $page->getTitle() );
959 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
960 "rollback did not revert to the correct revision" );
961 $this->assertEquals( "one", $page->getContent()->getNativeData() );
965 * @covers WikiPage::doRollback
967 public function testDoRollbackFailureSameContent() {
968 $admin = new User();
969 $admin->setName( "Admin" );
970 $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
972 $text = "one";
973 $page = $this->newPage( "WikiPageTest_testDoRollback" );
974 $page->doEditContent(
975 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
976 "section one",
977 EDIT_NEW,
978 false,
979 $admin
981 $rev1 = $page->getRevision();
983 $user1 = new User();
984 $user1->setName( "127.0.1.11" );
985 $user1->addGroup( "sysop" ); # XXX: make the test user a sysop...
986 $text .= "\n\ntwo";
987 $page = new WikiPage( $page->getTitle() );
988 $page->doEditContent(
989 ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
990 "adding section two",
992 false,
993 $user1
996 # now, do a the rollback from the same user was doing the edit before
997 $resultDetails = [];
998 $token = $user1->getEditToken(
999 [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
1000 null
1002 $errors = $page->doRollback(
1003 $user1->getName(),
1004 "testing revert same user",
1005 $token,
1006 false,
1007 $resultDetails,
1008 $admin
1011 $this->assertEquals( [], $errors, "Rollback failed same user" );
1013 # now, try the rollback
1014 $resultDetails = [];
1015 $token = $admin->getEditToken(
1016 [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
1017 null
1019 $errors = $page->doRollback(
1020 $user1->getName(),
1021 "testing revert",
1022 $token,
1023 false,
1024 $resultDetails,
1025 $admin
1028 $this->assertEquals( [ [ 'alreadyrolled', 'WikiPageTest testDoRollback',
1029 '127.0.1.11', 'Admin' ] ], $errors, "Rollback not failed" );
1031 $page = new WikiPage( $page->getTitle() );
1032 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
1033 "rollback did not revert to the correct revision" );
1034 $this->assertEquals( "one", $page->getContent()->getNativeData() );
1037 public static function provideGetAutosummary() {
1038 return [
1040 'Hello there, world!',
1041 '#REDIRECT [[Foo]]',
1043 '/^Redirected page .*Foo/'
1047 null,
1048 'Hello world!',
1049 EDIT_NEW,
1050 '/^Created page .*Hello/'
1054 'Hello there, world!',
1057 '/^Blanked/'
1061 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
1062 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
1063 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
1064 clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
1065 'Hello world!',
1067 '/^Replaced .*Hello/'
1071 'foo',
1072 'bar',
1074 '/^$/'
1080 * @dataProvider provideGetAutoSummary
1081 * @covers WikiPage::getAutosummary
1083 public function testGetAutosummary( $old, $new, $flags, $expected ) {
1084 $this->hideDeprecated( "WikiPage::getAutosummary" );
1086 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
1088 $summary = $page->getAutosummary( $old, $new, $flags );
1090 $this->assertTrue( (bool)preg_match( $expected, $summary ),
1091 "Autosummary didn't match expected pattern $expected: $summary" );
1094 public static function provideGetAutoDeleteReason() {
1095 return [
1098 false,
1099 false
1104 [ "first edit", null ],
1106 "/first edit.*only contributor/",
1107 false
1112 [ "first edit", null ],
1113 [ "second edit", null ],
1115 "/second edit.*only contributor/",
1116 true
1121 [ "first edit", "127.0.2.22" ],
1122 [ "second edit", "127.0.3.33" ],
1124 "/second edit/",
1125 true
1131 "first edit: "
1132 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
1133 . " nonumy eirmod tempor invidunt ut labore et dolore magna "
1134 . "aliquyam erat, sed diam voluptua. At vero eos et accusam "
1135 . "et justo duo dolores et ea rebum. Stet clita kasd gubergren, "
1136 . "no sea takimata sanctus est Lorem ipsum dolor sit amet.'",
1137 null
1140 '/first edit:.*\.\.\."/',
1141 false
1146 [ "first edit", "127.0.2.22" ],
1147 [ "", "127.0.3.33" ],
1149 "/before blanking.*first edit/",
1150 true
1157 * @dataProvider provideGetAutoDeleteReason
1158 * @covers WikiPage::getAutoDeleteReason
1160 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
1161 global $wgUser;
1163 // NOTE: assume Help namespace to contain wikitext
1164 $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" );
1166 $c = 1;
1168 foreach ( $edits as $edit ) {
1169 $user = new User();
1171 if ( !empty( $edit[1] ) ) {
1172 $user->setName( $edit[1] );
1173 } else {
1174 $user = $wgUser;
1177 $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
1179 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user );
1181 $c += 1;
1184 $reason = $page->getAutoDeleteReason( $hasHistory );
1186 if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) {
1187 $this->assertEquals( $expectedResult, $reason );
1188 } else {
1189 $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
1190 "Autosummary didn't match expected pattern $expectedResult: $reason" );
1193 $this->assertEquals( $expectedHistory, $hasHistory,
1194 "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
1196 $page->doDeleteArticle( "done" );
1199 public static function providePreSaveTransform() {
1200 return [
1201 [ 'hello this is ~~~',
1202 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
1204 [ 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1205 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1211 * @covers WikiPage::factory
1213 public function testWikiPageFactory() {
1214 $title = Title::makeTitle( NS_FILE, 'Someimage.png' );
1215 $page = WikiPage::factory( $title );
1216 $this->assertEquals( 'WikiFilePage', get_class( $page ) );
1218 $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
1219 $page = WikiPage::factory( $title );
1220 $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
1222 $title = Title::makeTitle( NS_MAIN, 'SomePage' );
1223 $page = WikiPage::factory( $title );
1224 $this->assertEquals( 'WikiPage', get_class( $page ) );