4 * ^--- important, causes temporary tables to be used instead of the real database
7 class WikiPageTest
extends MediaWikiTestCase
{
11 function __construct( $name = null, array $data = array(), $dataName = '' ) {
12 parent
::__construct( $name, $data, $dataName );
14 $this->tablesUsed
= array_merge ( $this->tablesUsed
,
32 public function setUp() {
33 $this->pages_to_delete
= array();
36 public function tearDown() {
37 foreach ( $this->pages_to_delete
as $p ) {
38 /* @var $p WikiPage */
42 $p->doDeleteArticle( "testing done." );
44 } catch ( MWException
$ex ) {
50 protected function newPage( $title ) {
51 if ( is_string( $title ) ) $title = Title
::newFromText( $title );
53 $p = new WikiPage( $title );
55 $this->pages_to_delete
[] = $p;
60 protected function createPage( $page, $text, $model = null ) {
61 if ( is_string( $page ) ) $page = Title
::newFromText( $page );
62 if ( $page instanceof Title
) $page = $this->newPage( $page );
64 $page->doEdit( $text, "testing", EDIT_NEW
);
69 public function testDoEdit() {
70 $title = Title
::newFromText( "WikiPageTest_testDoEdit" );
72 $page = $this->newPage( $title );
74 $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
75 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
77 $page->doEdit( $text, "testing 1" );
79 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
80 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
84 # ------------------------
85 $page = new WikiPage( $title );
87 $retrieved = $page->getText();
88 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
90 # ------------------------
91 $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
92 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
94 $page->doEdit( $text, "testing 2" );
96 # ------------------------
97 $page = new WikiPage( $title );
99 $retrieved = $page->getText();
100 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
102 # ------------------------
103 $dbr = wfGetDB( DB_SLAVE
);
104 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
105 $n = $res->numRows();
108 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
111 public function testDoQuickEdit() {
114 $page = $this->createPage( "WikiPageTest_testDoQuickEdit", "original text" );
116 $text = "quick text";
117 $page->doQuickEdit( $text, $wgUser, "testing q" );
119 # ---------------------
120 $page = new WikiPage( $page->getTitle() );
121 $this->assertEquals( $text, $page->getText() );
124 public function testDoDeleteArticle() {
125 $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo" );
126 $id = $page->getId();
128 $page->doDeleteArticle( "testing deletion" );
130 $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" );
131 $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" );
133 $t = Title
::newFromText( $page->getTitle()->getPrefixedText() );
134 $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" );
136 # ------------------------
137 $dbr = wfGetDB( DB_SLAVE
);
138 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
139 $n = $res->numRows();
142 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
145 public function testDoDeleteUpdates() {
146 $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo" );
147 $id = $page->getId();
149 $page->doDeleteUpdates( $id );
151 # ------------------------
152 $dbr = wfGetDB( DB_SLAVE
);
153 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
154 $n = $res->numRows();
157 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
160 public function testGetRevision() {
161 $page = $this->newPage( "WikiPageTest_testGetRevision" );
163 $rev = $page->getRevision();
164 $this->assertNull( $rev );
167 $this->createPage( $page, "some text" );
169 $rev = $page->getRevision();
171 $this->assertEquals( $page->getLatest(), $rev->getId() );
172 $this->assertEquals( "some text", $rev->getText() );
175 public function testGetText() {
176 $page = $this->newPage( "WikiPageTest_testGetText" );
178 $text = $page->getText();
179 $this->assertFalse( $text );
182 $this->createPage( $page, "some text" );
184 $text = $page->getText();
185 $this->assertEquals( "some text", $text );
188 public function testGetRawText() {
189 $page = $this->newPage( "WikiPageTest_testGetRawText" );
191 $text = $page->getRawText();
192 $this->assertFalse( $text );
195 $this->createPage( $page, "some text" );
197 $text = $page->getRawText();
198 $this->assertEquals( "some text", $text );
202 public function testExists() {
203 $page = $this->newPage( "WikiPageTest_testExists" );
204 $this->assertFalse( $page->exists() );
207 $this->createPage( $page, "some text" );
208 $this->assertTrue( $page->exists() );
210 $page = new WikiPage( $page->getTitle() );
211 $this->assertTrue( $page->exists() );
214 $page->doDeleteArticle( "done testing" );
215 $this->assertFalse( $page->exists() );
217 $page = new WikiPage( $page->getTitle() );
218 $this->assertFalse( $page->exists() );
221 public function dataHasViewableContent() {
223 array( 'WikiPageTest_testHasViewableContent', false, true ),
224 array( 'Special:WikiPageTest_testHasViewableContent', false ),
225 array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ),
226 array( 'Special:Userlogin', true ),
227 array( 'MediaWiki:help', true ),
232 * @dataProvider dataHasViewableContent
234 public function testHasViewableContent( $title, $viewable, $create = false ) {
235 $page = $this->newPage( $title );
236 $this->assertEquals( $viewable, $page->hasViewableContent() );
239 $this->createPage( $page, "some text" );
240 $this->assertTrue( $page->hasViewableContent() );
242 $page = new WikiPage( $page->getTitle() );
243 $this->assertTrue( $page->hasViewableContent() );
247 public function dataGetRedirectTarget() {
249 array( 'WikiPageTest_testGetRedirectTarget_1', "hello world", null ),
250 array( 'WikiPageTest_testGetRedirectTarget_2', "#REDIRECT [[hello world]]", "Hello world" ),
255 * @dataProvider dataGetRedirectTarget
257 public function testGetRedirectTarget( $title, $text, $target ) {
258 $page = $this->createPage( $title, $text );
260 # now, test the actual redirect
261 $t = $page->getRedirectTarget();
262 $this->assertEquals( $target, is_null( $t ) ?
null : $t->getPrefixedText() );
266 * @dataProvider dataGetRedirectTarget
268 public function testIsRedirect( $title, $text, $target ) {
269 $page = $this->createPage( $title, $text );
270 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
273 public function dataIsCountable() {
277 array( 'WikiPageTest_testIsCountable',
282 array( 'WikiPageTest_testIsCountable',
289 array( 'WikiPageTest_testIsCountable',
294 array( 'WikiPageTest_testIsCountable',
301 array( 'WikiPageTest_testIsCountable',
306 array( 'WikiPageTest_testIsCountable',
313 array( 'WikiPageTest_testIsCountable',
318 array( 'WikiPageTest_testIsCountable',
323 array( 'WikiPageTest_testIsCountable',
329 // not a content namespace
330 array( 'Talk:WikiPageTest_testIsCountable',
335 array( 'Talk:WikiPageTest_testIsCountable',
340 array( 'Talk:WikiPageTest_testIsCountable',
346 // not a content namespace, different model
347 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
352 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
357 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
367 * @dataProvider dataIsCountable
369 public function testIsCountable( $title, $text, $mode, $expected ) {
370 global $wgArticleCountMethod;
372 $old = $wgArticleCountMethod;
373 $wgArticleCountMethod = $mode;
375 $page = $this->createPage( $title, $text );
376 $editInfo = $page->prepareTextForEdit( $page->getText() );
378 $v = $page->isCountable();
379 $w = $page->isCountable( $editInfo );
380 $wgArticleCountMethod = $old;
382 $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
383 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
385 $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
386 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
389 public function dataGetParserOutput() {
391 array("hello ''world''\n", "<p>hello <i>world</i></p>"),
397 * @dataProvider dataGetParserOutput
399 public function testGetParserOutput( $text, $expectedHtml ) {
400 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text );
402 $opt = new ParserOptions();
403 $po = $page->getParserOutput( $opt );
404 $text = $po->getText();
406 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
407 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
409 $this->assertEquals( $expectedHtml, $text );
428 public function dataReplaceSection() {
430 array( 'WikiPageTest_testReplaceSection',
431 WikiPageTest
::$sections,
435 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest
::$sections ) )
437 array( 'WikiPageTest_testReplaceSection',
438 WikiPageTest
::$sections,
444 array( 'WikiPageTest_testReplaceSection',
445 WikiPageTest
::$sections,
447 "== TEST ==\nmore fun",
449 trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikiPageTest
::$sections ) )
451 array( 'WikiPageTest_testReplaceSection',
452 WikiPageTest
::$sections,
456 trim( WikiPageTest
::$sections )
458 array( 'WikiPageTest_testReplaceSection',
459 WikiPageTest
::$sections,
463 trim( WikiPageTest
::$sections ) . "\n\n== New ==\n\nNo more"
469 * @dataProvider dataReplaceSection
471 public function testReplaceSection( $title, $text, $section, $with, $sectionTitle, $expected ) {
472 $page = $this->createPage( $title, $text );
473 $text = $page->replaceSection( $section, $with, $sectionTitle );
474 $text = trim( $text );
476 $this->assertEquals( $expected, $text );
480 public function testGetUndoText() {
483 wfSuppressWarnings();
484 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
488 $this->markTestSkipped( "diff3 not installed or not found" );
493 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
494 $rev1 = $page->getRevision();
497 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
498 $rev2 = $page->getRevision();
500 $text .= "\n\nthree";
501 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
502 $rev3 = $page->getRevision();
505 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
506 $rev4 = $page->getRevision();
509 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
510 $rev5 = $page->getRevision();
513 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
514 $rev6 = $page->getRevision();
516 $undo6 = $page->getUndoText( $rev6 );
517 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
518 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
520 $undo3 = $page->getUndoText( $rev4, $rev2 );
521 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
522 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
524 $undo2 = $page->getUndoText( $rev2 );
525 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
526 $this->assertEquals( "one\n\nfive", $undo2 );
531 * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason.
533 public function broken_testDoRollback() {
535 $admin->setName("Admin");
538 $page = $this->newPage( "WikiPageTest_testDoRollback" );
539 $page->doEdit( $text, "section one", EDIT_NEW
, false, $admin );
542 $user1->setName( "127.0.1.11" );
544 $page = new WikiPage( $page->getTitle() );
545 $page->doEdit( $text, "adding section two", 0, false, $user1 );
548 $user2->setName( "127.0.2.13" );
549 $text .= "\n\nthree";
550 $page = new WikiPage( $page->getTitle() );
551 $page->doEdit( $text, "adding section three", 0, false, $user2 );
553 # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
554 # or not committed under some circumstances. so, make sure the last revision has the right user name.
555 $dbr = wfGetDB( DB_SLAVE
);
556 $this->assertEquals( 3, Revision
::countByPageId( $dbr, $page->getId() ) );
558 $page = new WikiPage( $page->getTitle() );
559 $rev3 = $page->getRevision();
560 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
562 $rev2 = $rev3->getPrevious();
563 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
565 $rev1 = $rev2->getPrevious();
566 $this->assertEquals( 'Admin', $rev1->getUserText() );
568 # now, try the actual rollback
569 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
570 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null );
571 $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin );
574 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
577 $page = new WikiPage( $page->getTitle() );
578 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision" );
579 $this->assertEquals( "one\n\ntwo", $page->getText() );
583 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
585 public function testDoRollback() {
587 $admin->setName("Admin");
590 $page = $this->newPage( "WikiPageTest_testDoRollback" );
591 $page->doEdit( $text, "section one", EDIT_NEW
, false, $admin );
592 $rev1 = $page->getRevision();
595 $user1->setName( "127.0.1.11" );
597 $page = new WikiPage( $page->getTitle() );
598 $page->doEdit( $text, "adding section two", 0, false, $user1 );
600 # now, try the rollback
601 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
602 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
603 $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin );
606 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
609 $page = new WikiPage( $page->getTitle() );
610 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision" );
611 $this->assertEquals( "one", $page->getText() );
614 public function dataGetAutosummary( ) {
617 'Hello there, world!',
620 '/^Redirected page .*Foo/'
627 '/^Created page .*Hello/'
631 'Hello there, world!',
638 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
639 labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et
640 ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
643 '/^Replaced .*Hello/'
656 * @dataProvider dataGetAutoSummary
658 public function testGetAutosummary( $old, $new, $flags, $expected ) {
659 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
661 $summary = $page->getAutosummary( $old, $new, $flags );
663 $this->assertTrue( (bool)preg_match( $expected, $summary ), "Autosummary didn't match expected pattern $expected: $summary" );
666 public function dataGetAutoDeleteReason( ) {
676 array( "first edit", null ),
678 "/first edit.*only contributor/",
684 array( "first edit", null ),
685 array( "second edit", null ),
687 "/second edit.*only contributor/",
693 array( "first edit", "127.0.2.22" ),
694 array( "second edit", "127.0.3.33" ),
702 array( "first edit: "
703 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
704 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
705 . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
706 . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
708 '/first edit:.*\.\.\."/',
714 array( "first edit", "127.0.2.22" ),
715 array( "", "127.0.3.33" ),
717 "/before blanking.*first edit/",
725 * @dataProvider dataGetAutoDeleteReason
727 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
730 $page = $this->newPage( "WikiPageTest_testGetAutoDeleteReason" );
734 foreach ( $edits as $edit ) {
737 if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
738 else $user = $wgUser;
740 $page->doEdit( $edit[0], "test edit $c", $c < 2 ? EDIT_NEW
: 0, false, $user );
745 $reason = $page->getAutoDeleteReason( $hasHistory );
747 if ( is_bool( $expectedResult ) ||
is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason );
748 else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ), "Autosummary didn't match expected pattern $expectedResult: $reason" );
750 $this->assertEquals( $expectedHistory, $hasHistory, "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
752 $page->doDeleteArticle( "done" );
755 public function dataPreSaveTransform() {
757 array( 'hello this is ~~~',
758 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
760 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
761 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
767 * @dataProvider dataPreSaveTransform
769 public function testPreSaveTransform( $text, $expected ) {
771 $user->setName("127.0.0.1");
773 $page = $this->newPage( "WikiPageTest_testPreloadTransform" );
774 $text = $page->preSaveTransform( $text, $user );
776 $this->assertEquals( $expected, $text );