4 * ^--- important, causes temporary tables to be used instead of the real database
7 class WikiPageTest
extends MediaWikiTestCase
{
11 public function setUp() {
12 $this->pages_to_delete
= array();
15 public function tearDown() {
16 foreach ( $this->pages_to_delete
as $p ) {
17 /* @var $p WikiPage */
21 $p->doDeleteArticle( "testing done." );
23 } catch ( MWException
$ex ) {
29 protected function newPage( $title ) {
30 if ( is_string( $title ) ) $title = Title
::newFromText( $title );
32 $p = new WikiPage( $title );
34 $this->pages_to_delete
[] = $p;
39 protected function createPage( $page, $text, $model = null ) {
40 if ( is_string( $page ) ) $page = Title
::newFromText( $page );
41 if ( $page instanceof Title
) $page = $this->newPage( $page );
43 $content = ContentHandler
::makeContent( $text, $page->getTitle(), $model );
44 $page->doEditContent( $content, "testing", EDIT_NEW
);
49 public function testDoEditContent() {
50 $title = Title
::newFromText( "WikiPageTest_testDoEditContent" );
52 $page = $this->newPage( $title );
54 $content = ContentHandler
::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
55 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
58 $page->doEditContent( $content, "testing 1" );
60 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
61 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
65 # ------------------------
66 $page = new WikiPage( $title );
68 $retrieved = $page->getContent();
69 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
71 # ------------------------
72 $content = ContentHandler
::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
73 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
76 $page->doEditContent( $content, "testing 2" );
78 # ------------------------
79 $page = new WikiPage( $title );
81 $retrieved = $page->getContent();
82 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
84 # ------------------------
85 $dbr = wfGetDB( DB_SLAVE
);
86 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
90 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
93 public function testDoEdit() {
94 $title = Title
::newFromText( "WikiPageTest_testDoEdit" );
96 $page = $this->newPage( $title );
98 $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
99 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
101 $page->doEdit( $text, "testing 1" );
103 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
104 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
106 $id = $page->getId();
108 # ------------------------
109 $page = new WikiPage( $title );
111 $retrieved = $page->getText();
112 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
114 # ------------------------
115 $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
116 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
118 $page->doEdit( $text, "testing 2" );
120 # ------------------------
121 $page = new WikiPage( $title );
123 $retrieved = $page->getText();
124 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
126 # ------------------------
127 $dbr = wfGetDB( DB_SLAVE
);
128 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
129 $n = $res->numRows();
132 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
135 public function testDoQuickEdit() {
138 $page = $this->createPage( "WikiPageTest_testDoQuickEdit", "original text" );
140 $text = "quick text";
141 $page->doQuickEdit( $text, $wgUser, "testing q" );
143 # ---------------------
144 $page = new WikiPage( $page->getTitle() );
145 $this->assertEquals( $text, $page->getText() );
148 public function testDoQuickEditContent() {
151 $page = $this->createPage( "WikiPageTest_testDoQuickEditContent", "original text" );
153 $content = ContentHandler
::makeContent( "quick text", $page->getTitle() );
154 $page->doQuickEditContent( $content, $wgUser, "testing q" );
156 # ---------------------
157 $page = new WikiPage( $page->getTitle() );
158 $this->assertTrue( $content->equals( $page->getContent() ) );
161 public function testDoDeleteArticle() {
162 $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo" );
163 $id = $page->getId();
165 $page->doDeleteArticle( "testing deletion" );
167 $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" );
169 $this->assertNull( $page->getContent(), "WikiPage::getContent should return null after page was deleted" );
170 $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" );
172 $t = Title
::newFromText( $page->getTitle()->getPrefixedText() );
173 $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" );
175 # ------------------------
176 $dbr = wfGetDB( DB_SLAVE
);
177 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
178 $n = $res->numRows();
181 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
184 public function testGetRevision() {
185 $page = $this->newPage( "WikiPageTest_testGetRevision" );
187 $rev = $page->getRevision();
188 $this->assertNull( $rev );
191 $this->createPage( $page, "some text" );
193 $rev = $page->getRevision();
195 $this->assertEquals( $page->getLatest(), $rev->getId() );
196 $this->assertEquals( "some text", $rev->getContent()->getNativeData() );
199 public function testGetContent() {
200 $page = $this->newPage( "WikiPageTest_testGetContent" );
202 $content = $page->getContent();
203 $this->assertNull( $content );
206 $this->createPage( $page, "some text" );
208 $content = $page->getContent();
209 $this->assertEquals( "some text", $content->getNativeData() );
212 public function testGetText() {
213 $page = $this->newPage( "WikiPageTest_testGetText" );
215 $text = $page->getText();
216 $this->assertFalse( $text );
219 $this->createPage( $page, "some text" );
221 $text = $page->getText();
222 $this->assertEquals( "some text", $text );
225 public function testGetRawText() {
226 $page = $this->newPage( "WikiPageTest_testGetRawText" );
228 $text = $page->getRawText();
229 $this->assertFalse( $text );
232 $this->createPage( $page, "some text" );
234 $text = $page->getRawText();
235 $this->assertEquals( "some text", $text );
238 public function testGetContentModelName() {
239 $page = $this->createPage( "WikiPageTest_testGetContentModelName", "some text", CONTENT_MODEL_JAVASCRIPT
);
241 $page = new WikiPage( $page->getTitle() );
242 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $page->getContentModelName() );
245 public function testGetContentHandler() {
246 $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT
);
248 $page = new WikiPage( $page->getTitle() );
249 $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) );
252 public function testExists() {
253 $page = $this->newPage( "WikiPageTest_testExists" );
254 $this->assertFalse( $page->exists() );
257 $this->createPage( $page, "some text" );
258 $this->assertTrue( $page->exists() );
260 $page = new WikiPage( $page->getTitle() );
261 $this->assertTrue( $page->exists() );
264 $page->doDeleteArticle( "done testing" );
265 $this->assertFalse( $page->exists() );
267 $page = new WikiPage( $page->getTitle() );
268 $this->assertFalse( $page->exists() );
271 public function dataHasViewableContent() {
273 array( 'WikiPageTest_testHasViewableContent', false, true ),
274 array( 'Special:WikiPageTest_testHasViewableContent', false ),
275 array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ),
276 array( 'Special:Userlogin', true ),
277 array( 'MediaWiki:help', true ),
282 * @dataProvider dataHasViewableContent
284 public function testHasViewableContent( $title, $viewable, $create = false ) {
285 $page = $this->newPage( $title );
286 $this->assertEquals( $viewable, $page->hasViewableContent() );
289 $this->createPage( $page, "some text" );
290 $this->assertTrue( $page->hasViewableContent() );
292 $page = new WikiPage( $page->getTitle() );
293 $this->assertTrue( $page->hasViewableContent() );
297 public function dataGetRedirectTarget() {
299 array( 'WikiPageTest_testGetRedirectTarget_1', "hello world", null ),
300 array( 'WikiPageTest_testGetRedirectTarget_2', "#REDIRECT [[hello world]]", "Hello world" ),
305 * @dataProvider dataGetRedirectTarget
307 public function testGetRedirectTarget( $title, $text, $target ) {
308 $page = $this->createPage( $title, $text );
310 # sanity check, because this test seems to fail for no reason for some people.
311 $c = $page->getContent();
312 $this->assertEquals( 'WikitextContent', get_class( $c ) );
314 # now, test the actual redirect
315 $t = $page->getRedirectTarget();
316 $this->assertEquals( $target, is_null( $t ) ?
null : $t->getPrefixedText() );
320 * @dataProvider dataGetRedirectTarget
322 public function testIsRedirect( $title, $text, $target ) {
323 $page = $this->createPage( $title, $text );
324 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
327 public function dataIsCountable() {
331 array( 'WikiPageTest_testIsCountable',
336 array( 'WikiPageTest_testIsCountable',
343 array( 'WikiPageTest_testIsCountable',
348 array( 'WikiPageTest_testIsCountable',
355 array( 'WikiPageTest_testIsCountable',
360 array( 'WikiPageTest_testIsCountable',
367 array( 'WikiPageTest_testIsCountable',
372 array( 'WikiPageTest_testIsCountable',
377 array( 'WikiPageTest_testIsCountable',
383 // not a content namespace
384 array( 'Talk:WikiPageTest_testIsCountable',
389 array( 'Talk:WikiPageTest_testIsCountable',
394 array( 'Talk:WikiPageTest_testIsCountable',
400 // not a content namespace, different model
401 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
406 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
411 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
421 * @dataProvider dataIsCountable
423 public function testIsCountable( $title, $text, $mode, $expected ) {
424 global $wgArticleCountMethod;
426 $old = $wgArticleCountMethod;
427 $wgArticleCountMethod = $mode;
429 $page = $this->createPage( $title, $text );
430 $editInfo = $page->prepareContentForEdit( $page->getContent() );
432 $v = $page->isCountable();
433 $w = $page->isCountable( $editInfo );
434 $wgArticleCountMethod = $old;
436 $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
437 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
439 $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
440 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
443 public function dataGetParserOutput() {
445 array("hello ''world''\n", "<p>hello <i>world</i></p>"),
451 * @dataProvider dataGetParserOutput
453 public function testGetParserOutput( $text, $expectedHtml ) {
454 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text );
456 $opt = new ParserOptions();
457 $po = $page->getParserOutput( $opt );
458 $text = $po->getText();
460 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
461 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
463 $this->assertEquals( $expectedHtml, $text );
482 public function dataReplaceSection() {
484 array( 'WikiPageTest_testReplaceSection',
485 WikiPageTest
::$sections,
489 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest
::$sections ) )
491 array( 'WikiPageTest_testReplaceSection',
492 WikiPageTest
::$sections,
498 array( 'WikiPageTest_testReplaceSection',
499 WikiPageTest
::$sections,
501 "== TEST ==\nmore fun",
503 trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikiPageTest
::$sections ) )
505 array( 'WikiPageTest_testReplaceSection',
506 WikiPageTest
::$sections,
510 trim( WikiPageTest
::$sections )
512 array( 'WikiPageTest_testReplaceSection',
513 WikiPageTest
::$sections,
517 trim( WikiPageTest
::$sections ) . "\n\n== New ==\n\nNo more"
523 * @dataProvider dataReplaceSection
525 public function testReplaceSection( $title, $text, $section, $with, $sectionTitle, $expected ) {
526 $page = $this->createPage( $title, $text );
527 $text = $page->replaceSection( $section, $with, $sectionTitle );
528 $text = trim( $text );
530 $this->assertEquals( $expected, $text );
534 * @dataProvider dataReplaceSection
536 public function testReplaceSectionContent( $title, $text, $section, $with, $sectionTitle, $expected ) {
537 $page = $this->createPage( $title, $text );
539 $content = ContentHandler
::makeContent( $with, $page->getTitle(), $page->getContentModelName() );
540 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
542 $this->assertEquals( $expected, is_null( $c ) ?
null : trim( $c->getNativeData() ) );
546 public function testGetUndoText() {
549 wfSuppressWarnings();
550 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
554 $this->markTestSkipped( "diff3 not installed or not found" );
559 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
560 $rev1 = $page->getRevision();
563 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
564 $rev2 = $page->getRevision();
566 $text .= "\n\nthree";
567 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
568 $rev3 = $page->getRevision();
571 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
572 $rev4 = $page->getRevision();
575 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
576 $rev5 = $page->getRevision();
579 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
580 $rev6 = $page->getRevision();
582 $undo6 = $page->getUndoText( $rev6 );
583 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
584 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
586 $undo3 = $page->getUndoText( $rev4, $rev2 );
587 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
588 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
590 $undo2 = $page->getUndoText( $rev2 );
591 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
592 $this->assertEquals( "one\n\nfive", $undo2 );
599 * ^--- marked as broken, because it fails in jenkins, though it passes locally for everyone. or so it seems.
601 public function testDoRollback() {
603 $admin->setName("Admin");
606 $page = $this->newPage( "WikiPageTest_testDoRollback" );
607 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ), "section one", EDIT_NEW
, false, $admin );
610 $user1->setName( "127.0.1.11" );
612 $page = new WikiPage( $page->getTitle() );
613 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ), "adding section two", 0, false, $user1 );
616 $user2->setName( "127.0.2.13" );
617 $text .= "\n\nthree";
618 $page = new WikiPage( $page->getTitle() );
619 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ), "adding section three", 0, false, $user2 );
621 # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
622 # or not committed under some circumstances. so, make sure the last revision has the right user name.
623 $dbr = wfGetDB( DB_SLAVE
);
624 $this->assertEquals( 3, Revision
::countByPageId( $dbr, $page->getId() ) );
626 $page = new WikiPage( $page->getTitle() );
627 $rev3 = $page->getRevision();
628 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
630 $rev2 = $rev3->getPrevious();
631 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
633 $rev1 = $rev2->getPrevious();
634 $this->assertEquals( 'Admin', $rev1->getUserText() );
636 # now, try the actual rollback
637 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
638 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null );
639 $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin );
642 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
645 $page = new WikiPage( $page->getTitle() );
646 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision" );
647 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
650 public function dataGetAutosummary( ) {
653 'Hello there, world!',
656 '/^Redirected page .*Foo/'
663 '/^Created page .*Hello/'
667 'Hello there, world!',
674 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
675 labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et
676 ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
679 '/^Replaced .*Hello/'
692 * @dataProvider dataGetAutoSummary
694 public function testGetAutosummary( $old, $new, $flags, $expected ) {
695 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
697 $summary = $page->getAutosummary( $old, $new, $flags );
699 $this->assertTrue( (bool)preg_match( $expected, $summary ), "Autosummary didn't match expected pattern $expected: $summary" );
702 public function dataGetAutoDeleteReason( ) {
712 array( "first edit", null ),
714 "/first edit.*only contributor/",
720 array( "first edit", null ),
721 array( "second edit", null ),
723 "/second edit.*only contributor/",
729 array( "first edit", "127.0.2.22" ),
730 array( "second edit", "127.0.3.33" ),
738 array( "first edit: "
739 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
740 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
741 . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
742 . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
744 '/first edit:.*\.\.\."/',
750 array( "first edit", "127.0.2.22" ),
751 array( "", "127.0.3.33" ),
753 "/before blanking.*first edit/",
761 * @dataProvider dataGetAutoDeleteReason
763 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
766 $page = $this->newPage( "WikiPageTest_testGetAutoDeleteReason" );
770 foreach ( $edits as $edit ) {
773 if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
774 else $user = $wgUser;
776 $content = ContentHandler
::makeContent( $edit[0], $page->getTitle(), $page->getContentModelName() );
778 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW
: 0, false, $user );
783 $reason = $page->getAutoDeleteReason( $hasHistory );
785 if ( is_bool( $expectedResult ) ||
is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason );
786 else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ), "Autosummary didn't match expected pattern $expectedResult: $reason" );
788 $this->assertEquals( $expectedHistory, $hasHistory, "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
790 $page->doDeleteArticle( "done" );
793 public function dataPreSaveTransform() {
795 array( 'hello this is ~~~',
796 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
798 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
799 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
805 * @dataProvider dataPreSaveTransform
807 public function testPreSaveTransform( $text, $expected ) {
809 $user->setName("127.0.0.1");
811 $page = $this->newPage( "WikiPageTest_testPreloadTransform" );
812 $text = $page->preSaveTransform( $text, $user );
814 $this->assertEquals( $expected, $text );