4 * @group ContentHandler
8 class WikiPageTest
extends MediaWikiLangTestCase
{
10 private $pagesToDelete;
12 public function __construct( $name = null, array $data = [], $dataName = '' ) {
13 parent
::__construct( $name, $data, $dataName );
15 $this->tablesUsed
= array_merge(
36 protected function setUp() {
38 $this->pagesToDelete
= [];
41 protected function tearDown() {
42 foreach ( $this->pagesToDelete
as $p ) {
43 /* @var $p WikiPage */
47 $p->doDeleteArticle( "testing done." );
49 } catch ( MWException
$ex ) {
57 * @param Title|string $title
58 * @param string|null $model
61 private function newPage( $title, $model = null ) {
62 if ( is_string( $title ) ) {
63 $ns = $this->getDefaultWikitextNS();
64 $title = Title
::newFromText( $title, $ns );
67 $p = new WikiPage( $title );
69 $this->pagesToDelete
[] = $p;
75 * @param string|Title|WikiPage $page
81 private function createPage( $page, $text, $model = null ) {
82 if ( is_string( $page ) ||
$page instanceof Title
) {
83 $page = $this->newPage( $page, $model );
86 $content = ContentHandler
::makeContent( $text, $page->getTitle(), $model );
87 $page->doEditContent( $content, "testing", EDIT_NEW
);
93 * @covers WikiPage::doEditContent
94 * @covers WikiPage::doModify
95 * @covers WikiPage::doCreate
96 * @covers WikiPage::doEditUpdates
98 public function testDoEditContent() {
99 $page = $this->newPage( __METHOD__
);
100 $title = $page->getTitle();
102 $content = ContentHandler
::makeContent(
103 "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
104 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
106 CONTENT_MODEL_WIKITEXT
109 $page->doEditContent( $content, "[[testing]] 1" );
111 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
112 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
113 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
114 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
116 $id = $page->getId();
118 # ------------------------
119 $dbr = wfGetDB( DB_REPLICA
);
120 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
121 $n = $res->numRows();
124 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
126 # ------------------------
127 $page = new WikiPage( $title );
129 $retrieved = $page->getContent();
130 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
132 # ------------------------
133 $content = ContentHandler
::makeContent(
134 "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
135 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
137 CONTENT_MODEL_WIKITEXT
140 $page->doEditContent( $content, "testing 2" );
142 # ------------------------
143 $page = new WikiPage( $title );
145 $retrieved = $page->getContent();
146 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
148 # ------------------------
149 $dbr = wfGetDB( DB_REPLICA
);
150 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
151 $n = $res->numRows();
154 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
158 * @covers WikiPage::doDeleteArticle
160 public function testDoDeleteArticle() {
161 $page = $this->createPage(
163 "[[original text]] foo",
164 CONTENT_MODEL_WIKITEXT
166 $id = $page->getId();
168 $page->doDeleteArticle( "testing deletion" );
171 $page->getTitle()->getArticleID() > 0,
172 "Title object should now have page id 0"
174 $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" );
177 "WikiPage::exists should return false after page was deleted"
181 "WikiPage::getContent should return null after page was deleted"
184 $t = Title
::newFromText( $page->getTitle()->getPrefixedText() );
187 "Title::exists should return false after page was deleted"
191 JobQueueGroup
::destroySingletons();
193 $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
196 # ------------------------
197 $dbr = wfGetDB( DB_REPLICA
);
198 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
199 $n = $res->numRows();
202 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
206 * @covers WikiPage::doDeleteUpdates
208 public function testDoDeleteUpdates() {
209 $page = $this->createPage(
211 "[[original text]] foo",
212 CONTENT_MODEL_WIKITEXT
214 $id = $page->getId();
216 // Similar to MovePage logic
217 wfGetDB( DB_MASTER
)->delete( 'page', [ 'page_id' => $id ], __METHOD__
);
218 $page->doDeleteUpdates( $id );
221 JobQueueGroup
::destroySingletons();
223 $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
226 # ------------------------
227 $dbr = wfGetDB( DB_REPLICA
);
228 $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
229 $n = $res->numRows();
232 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
236 * @covers WikiPage::getRevision
238 public function testGetRevision() {
239 $page = $this->newPage( __METHOD__
);
241 $rev = $page->getRevision();
242 $this->assertNull( $rev );
245 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT
);
247 $rev = $page->getRevision();
249 $this->assertEquals( $page->getLatest(), $rev->getId() );
250 $this->assertEquals( "some text", $rev->getContent()->getNativeData() );
254 * @covers WikiPage::getContent
256 public function testGetContent() {
257 $page = $this->newPage( __METHOD__
);
259 $content = $page->getContent();
260 $this->assertNull( $content );
263 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT
);
265 $content = $page->getContent();
266 $this->assertEquals( "some text", $content->getNativeData() );
270 * @covers WikiPage::getContentModel
272 public function testGetContentModel() {
273 global $wgContentHandlerUseDB;
275 if ( !$wgContentHandlerUseDB ) {
276 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
279 $page = $this->createPage(
282 CONTENT_MODEL_JAVASCRIPT
285 $page = new WikiPage( $page->getTitle() );
286 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $page->getContentModel() );
290 * @covers WikiPage::getContentHandler
292 public function testGetContentHandler() {
293 global $wgContentHandlerUseDB;
295 if ( !$wgContentHandlerUseDB ) {
296 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
299 $page = $this->createPage(
302 CONTENT_MODEL_JAVASCRIPT
305 $page = new WikiPage( $page->getTitle() );
306 $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) );
310 * @covers WikiPage::exists
312 public function testExists() {
313 $page = $this->newPage( __METHOD__
);
314 $this->assertFalse( $page->exists() );
317 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT
);
318 $this->assertTrue( $page->exists() );
320 $page = new WikiPage( $page->getTitle() );
321 $this->assertTrue( $page->exists() );
324 $page->doDeleteArticle( "done testing" );
325 $this->assertFalse( $page->exists() );
327 $page = new WikiPage( $page->getTitle() );
328 $this->assertFalse( $page->exists() );
331 public function provideHasViewableContent() {
333 [ 'WikiPageTest_testHasViewableContent', false, true ],
334 [ 'Special:WikiPageTest_testHasViewableContent', false ],
335 [ 'MediaWiki:WikiPageTest_testHasViewableContent', false ],
336 [ 'Special:Userlogin', true ],
337 [ 'MediaWiki:help', true ],
342 * @dataProvider provideHasViewableContent
343 * @covers WikiPage::hasViewableContent
345 public function testHasViewableContent( $title, $viewable, $create = false ) {
346 $page = $this->newPage( $title );
347 $this->assertEquals( $viewable, $page->hasViewableContent() );
350 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT
);
351 $this->assertTrue( $page->hasViewableContent() );
353 $page = new WikiPage( $page->getTitle() );
354 $this->assertTrue( $page->hasViewableContent() );
358 public function provideGetRedirectTarget() {
360 [ 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT
, "hello world", null ],
362 'WikiPageTest_testGetRedirectTarget_2',
363 CONTENT_MODEL_WIKITEXT
,
364 "#REDIRECT [[hello world]]",
371 * @dataProvider provideGetRedirectTarget
372 * @covers WikiPage::getRedirectTarget
374 public function testGetRedirectTarget( $title, $model, $text, $target ) {
375 $this->setMwGlobals( [
376 'wgCapitalLinks' => true,
379 $page = $this->createPage( $title, $text, $model );
381 # sanity check, because this test seems to fail for no reason for some people.
382 $c = $page->getContent();
383 $this->assertEquals( 'WikitextContent', get_class( $c ) );
385 # now, test the actual redirect
386 $t = $page->getRedirectTarget();
387 $this->assertEquals( $target, is_null( $t ) ?
null : $t->getPrefixedText() );
391 * @dataProvider provideGetRedirectTarget
392 * @covers WikiPage::isRedirect
394 public function testIsRedirect( $title, $model, $text, $target ) {
395 $page = $this->createPage( $title, $text, $model );
396 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
399 public function provideIsCountable() {
403 [ 'WikiPageTest_testIsCountable',
404 CONTENT_MODEL_WIKITEXT
,
409 [ 'WikiPageTest_testIsCountable',
410 CONTENT_MODEL_WIKITEXT
,
417 [ 'WikiPageTest_testIsCountable',
418 CONTENT_MODEL_WIKITEXT
,
423 [ 'WikiPageTest_testIsCountable',
424 CONTENT_MODEL_WIKITEXT
,
431 [ 'WikiPageTest_testIsCountable',
432 CONTENT_MODEL_WIKITEXT
,
437 [ 'WikiPageTest_testIsCountable',
438 CONTENT_MODEL_WIKITEXT
,
445 [ 'WikiPageTest_testIsCountable',
446 CONTENT_MODEL_WIKITEXT
,
451 [ 'WikiPageTest_testIsCountable',
452 CONTENT_MODEL_WIKITEXT
,
457 [ 'WikiPageTest_testIsCountable',
458 CONTENT_MODEL_WIKITEXT
,
464 // not a content namespace
465 [ 'Talk:WikiPageTest_testIsCountable',
466 CONTENT_MODEL_WIKITEXT
,
471 [ 'Talk:WikiPageTest_testIsCountable',
472 CONTENT_MODEL_WIKITEXT
,
477 [ 'Talk:WikiPageTest_testIsCountable',
478 CONTENT_MODEL_WIKITEXT
,
484 // not a content namespace, different model
485 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
491 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
497 [ 'MediaWiki:WikiPageTest_testIsCountable.js',
507 * @dataProvider provideIsCountable
508 * @covers WikiPage::isCountable
510 public function testIsCountable( $title, $model, $text, $mode, $expected ) {
511 global $wgContentHandlerUseDB;
513 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
515 $title = Title
::newFromText( $title );
517 if ( !$wgContentHandlerUseDB
519 && ContentHandler
::getDefaultModelFor( $title ) != $model
521 $this->markTestSkipped( "Can not use non-default content model $model for "
522 . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled." );
525 $page = $this->createPage( $title, $text, $model );
527 $editInfo = $page->prepareContentForEdit( $page->getContent() );
529 $v = $page->isCountable();
530 $w = $page->isCountable( $editInfo );
535 "isCountable( null ) returned unexpected value " . var_export( $v, true )
536 . " instead of " . var_export( $expected, true )
537 . " in mode `$mode` for text \"$text\""
543 "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
544 . " instead of " . var_export( $expected, true )
545 . " in mode `$mode` for text \"$text\""
549 public function provideGetParserOutput() {
552 CONTENT_MODEL_WIKITEXT
,
554 "<div class=\"mw-parser-output\"><p>hello <i>world</i></p></div>"
561 * @dataProvider provideGetParserOutput
562 * @covers WikiPage::getParserOutput
564 public function testGetParserOutput( $model, $text, $expectedHtml ) {
565 $page = $this->createPage( __METHOD__
, $text, $model );
567 $opt = $page->makeParserOptions( 'canonical' );
568 $po = $page->getParserOutput( $opt );
569 $text = $po->getText();
571 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
572 $text = preg_replace( '!\s*(</p>|</div>)!sm', '\1', $text ); # don't let tidy confuse us
574 $this->assertEquals( $expectedHtml, $text );
580 * @covers WikiPage::getParserOutput
582 public function testGetParserOutput_nonexisting() {
583 $page = new WikiPage( Title
::newFromText( __METHOD__
) );
585 $opt = new ParserOptions();
586 $po = $page->getParserOutput( $opt );
588 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
592 * @covers WikiPage::getParserOutput
594 public function testGetParserOutput_badrev() {
595 $page = $this->createPage( __METHOD__
, 'dummy', CONTENT_MODEL_WIKITEXT
);
597 $opt = new ParserOptions();
598 $po = $page->getParserOutput( $opt, $page->getLatest() +
1234 );
600 // @todo would be neat to also test deleted revision
602 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." );
605 public static $sections =
619 public function dataReplaceSection() {
620 // NOTE: assume the Help namespace to contain wikitext
622 [ 'Help:WikiPageTest_testReplaceSection',
623 CONTENT_MODEL_WIKITEXT
,
628 trim( preg_replace( '/^Intro/sm', 'No more', self
::$sections ) )
630 [ 'Help:WikiPageTest_testReplaceSection',
631 CONTENT_MODEL_WIKITEXT
,
638 [ 'Help:WikiPageTest_testReplaceSection',
639 CONTENT_MODEL_WIKITEXT
,
642 "== TEST ==\nmore fun",
644 trim( preg_replace( '/^== test ==.*== foo ==/sm',
645 "== TEST ==\nmore fun\n\n== foo ==",
648 [ 'Help:WikiPageTest_testReplaceSection',
649 CONTENT_MODEL_WIKITEXT
,
654 trim( self
::$sections )
656 [ 'Help:WikiPageTest_testReplaceSection',
657 CONTENT_MODEL_WIKITEXT
,
662 trim( self
::$sections ) . "\n\n== New ==\n\nNo more"
668 * @dataProvider dataReplaceSection
669 * @covers WikiPage::replaceSectionContent
671 public function testReplaceSectionContent( $title, $model, $text, $section,
672 $with, $sectionTitle, $expected
674 $page = $this->createPage( $title, $text, $model );
676 $content = ContentHandler
::makeContent( $with, $page->getTitle(), $page->getContentModel() );
677 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
679 $this->assertEquals( $expected, is_null( $c ) ?
null : trim( $c->getNativeData() ) );
683 * @dataProvider dataReplaceSection
684 * @covers WikiPage::replaceSectionAtRev
686 public function testReplaceSectionAtRev( $title, $model, $text, $section,
687 $with, $sectionTitle, $expected
689 $page = $this->createPage( $title, $text, $model );
690 $baseRevId = $page->getLatest();
692 $content = ContentHandler
::makeContent( $with, $page->getTitle(), $page->getContentModel() );
693 $c = $page->replaceSectionAtRev( $section, $content, $sectionTitle, $baseRevId );
695 $this->assertEquals( $expected, is_null( $c ) ?
null : trim( $c->getNativeData() ) );
699 * @covers WikiPage::getOldestRevision
701 public function testGetOldestRevision() {
702 $page = $this->newPage( __METHOD__
);
703 $page->doEditContent(
704 new WikitextContent( 'one' ),
708 $rev1 = $page->getRevision();
710 $page = new WikiPage( $page->getTitle() );
711 $page->doEditContent(
712 new WikitextContent( 'two' ),
717 $page = new WikiPage( $page->getTitle() );
718 $page->doEditContent(
719 new WikitextContent( 'three' ),
725 $this->assertNotEquals(
727 $page->getRevision()->getId(),
728 '$page->getRevision()->getId()'
734 $page->getOldestRevision()->getId(),
735 '$page->getOldestRevision()->getId()'
740 * @todo FIXME: this is a better rollback test than the one below, but it
741 * keeps failing in jenkins for some reason.
743 public function broken_testDoRollback() {
744 $admin = $this->getTestSysop()->getUser();
747 $page = $this->newPage( __METHOD__
);
748 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ),
749 "section one", EDIT_NEW
, false, $admin );
751 $user1 = $this->getTestUser()->getUser();
753 $page = new WikiPage( $page->getTitle() );
754 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ),
755 "adding section two", 0, false, $user1 );
757 $user2 = $this->getTestUser()->getUser();
758 $text .= "\n\nthree";
759 $page = new WikiPage( $page->getTitle() );
760 $page->doEditContent( ContentHandler
::makeContent( $text, $page->getTitle() ),
761 "adding section three", 0, false, $user2 );
763 # we are having issues with doRollback spuriously failing. Apparently
764 # the last revision somehow goes missing or not committed under some
765 # circumstances. So, make sure the last revision has the right user name.
766 $dbr = wfGetDB( DB_REPLICA
);
767 $this->assertEquals( 3, Revision
::countByPageId( $dbr, $page->getId() ) );
769 $page = new WikiPage( $page->getTitle() );
770 $rev3 = $page->getRevision();
771 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
773 $rev2 = $rev3->getPrevious();
774 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
776 $rev1 = $rev2->getPrevious();
777 $this->assertEquals( 'Admin', $rev1->getUserText() );
779 # now, try the actual rollback
780 $token = $admin->getEditToken(
781 [ $page->getTitle()->getPrefixedText(), $user2->getName() ],
784 $errors = $page->doRollback(
794 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
795 . ";\n" . print_r( $details, true ) );
798 $page = new WikiPage( $page->getTitle() );
799 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
800 "rollback did not revert to the correct revision" );
801 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
805 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
806 * @covers WikiPage::doRollback
808 public function testDoRollback() {
809 $admin = $this->getTestSysop()->getUser();
812 $page = $this->newPage( __METHOD__
);
813 $page->doEditContent(
814 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
820 $rev1 = $page->getRevision();
822 $user1 = $this->getTestUser()->getUser();
824 $page = new WikiPage( $page->getTitle() );
825 $page->doEditContent(
826 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
827 "adding section two",
833 # now, try the rollback
834 $token = $admin->getEditToken( 'rollback' );
835 $errors = $page->doRollback(
845 $this->fail( "Rollback failed:\n" . print_r( $errors, true )
846 . ";\n" . print_r( $details, true ) );
849 $page = new WikiPage( $page->getTitle() );
850 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
851 "rollback did not revert to the correct revision" );
852 $this->assertEquals( "one", $page->getContent()->getNativeData() );
856 * @covers WikiPage::doRollback
858 public function testDoRollbackFailureSameContent() {
859 $admin = $this->getTestSysop()->getUser();
862 $page = $this->newPage( __METHOD__
);
863 $page->doEditContent(
864 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
870 $rev1 = $page->getRevision();
872 $user1 = $this->getTestUser( [ 'sysop' ] )->getUser();
874 $page = new WikiPage( $page->getTitle() );
875 $page->doEditContent(
876 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
877 "adding section two",
883 # now, do a the rollback from the same user was doing the edit before
885 $token = $user1->getEditToken( 'rollback' );
886 $errors = $page->doRollback(
888 "testing revert same user",
895 $this->assertEquals( [], $errors, "Rollback failed same user" );
897 # now, try the rollback
899 $token = $admin->getEditToken( 'rollback' );
900 $errors = $page->doRollback(
919 "Rollback not failed"
922 $page = new WikiPage( $page->getTitle() );
923 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
924 "rollback did not revert to the correct revision" );
925 $this->assertEquals( "one", $page->getContent()->getNativeData() );
929 * Tests tagging for edits that do rollback action
930 * @covers WikiPage::doRollback
932 public function testDoRollbackTagging() {
933 if ( !in_array( 'mw-rollback', ChangeTags
::getSoftwareTags() ) ) {
934 $this->markTestSkipped( 'Rollback tag deactivated, skipped the test.' );
938 $admin->setName( 'Administrator' );
939 $admin->addToDatabase();
941 $text = 'First line';
942 $page = $this->newPage( 'WikiPageTest_testDoRollbackTagging' );
943 $page->doEditContent(
944 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
951 $secondUser = new User();
952 $secondUser->setName( '92.65.217.32' );
953 $text .= '\n\nSecond line';
954 $page = new WikiPage( $page->getTitle() );
955 $page->doEditContent(
956 ContentHandler
::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT
),
957 'Adding second line',
963 // Now, try the rollback
964 $admin->addGroup( 'sysop' ); // Make the test user a sysop
965 $token = $admin->getEditToken( 'rollback' );
966 $errors = $page->doRollback(
967 $secondUser->getName(),
975 // If doRollback completed without errors
976 if ( $errors === [] ) {
977 $tags = $resultDetails[ 'tags' ];
978 $this->assertContains( 'mw-rollback', $tags );
982 public function provideGetAutoDeleteReason() {
992 [ "first edit", null ],
994 "/first edit.*only contributor/",
1000 [ "first edit", null ],
1001 [ "second edit", null ],
1003 "/second edit.*only contributor/",
1009 [ "first edit", "127.0.2.22" ],
1010 [ "second edit", "127.0.3.33" ],
1020 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
1021 . " nonumy eirmod tempor invidunt ut labore et dolore magna "
1022 . "aliquyam erat, sed diam voluptua. At vero eos et accusam "
1023 . "et justo duo dolores et ea rebum. Stet clita kasd gubergren, "
1024 . "no sea takimata sanctus est Lorem ipsum dolor sit amet.'",
1028 '/first edit:.*\.\.\."/',
1034 [ "first edit", "127.0.2.22" ],
1035 [ "", "127.0.3.33" ],
1037 "/before blanking.*first edit/",
1045 * @dataProvider provideGetAutoDeleteReason
1046 * @covers WikiPage::getAutoDeleteReason
1048 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
1051 // NOTE: assume Help namespace to contain wikitext
1052 $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" );
1056 foreach ( $edits as $edit ) {
1059 if ( !empty( $edit[1] ) ) {
1060 $user->setName( $edit[1] );
1065 $content = ContentHandler
::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
1067 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW
: 0, false, $user );
1072 $reason = $page->getAutoDeleteReason( $hasHistory );
1074 if ( is_bool( $expectedResult ) ||
is_null( $expectedResult ) ) {
1075 $this->assertEquals( $expectedResult, $reason );
1077 $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
1078 "Autosummary didn't match expected pattern $expectedResult: $reason" );
1081 $this->assertEquals( $expectedHistory, $hasHistory,
1082 "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
1084 $page->doDeleteArticle( "done" );
1087 public function providePreSaveTransform() {
1089 [ 'hello this is ~~~',
1090 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
1092 [ 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1093 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1099 * @covers WikiPage::factory
1101 public function testWikiPageFactory() {
1102 $title = Title
::makeTitle( NS_FILE
, 'Someimage.png' );
1103 $page = WikiPage
::factory( $title );
1104 $this->assertEquals( 'WikiFilePage', get_class( $page ) );
1106 $title = Title
::makeTitle( NS_CATEGORY
, 'SomeCategory' );
1107 $page = WikiPage
::factory( $title );
1108 $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
1110 $title = Title
::makeTitle( NS_MAIN
, 'SomePage' );
1111 $page = WikiPage
::factory( $title );
1112 $this->assertEquals( 'WikiPage', get_class( $page ) );
1116 * @dataProvider provideCommentMigrationOnDeletion
1118 * @param int $writeStage
1119 * @param int $readStage
1121 public function testCommentMigrationOnDeletion( $writeStage, $readStage ) {
1122 $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $writeStage );
1123 $dbr = wfGetDB( DB_REPLICA
);
1125 $page = $this->createPage(
1128 CONTENT_MODEL_WIKITEXT
1130 $revid = $page->getLatest();
1131 if ( $writeStage > MIGRATION_OLD
) {
1132 $comment_id = $dbr->selectField(
1133 'revision_comment_temp',
1134 'revcomment_comment_id',
1135 [ 'revcomment_rev' => $revid ],
1140 $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $readStage );
1142 $page->doDeleteArticle( "testing deletion" );
1144 if ( $readStage > MIGRATION_OLD
) {
1145 // Didn't leave behind any 'revision_comment_temp' rows
1146 $n = $dbr->selectField(
1147 'revision_comment_temp', 'COUNT(*)', [ 'revcomment_rev' => $revid ], __METHOD__
1149 $this->assertEquals( 0, $n, 'no entry in revision_comment_temp after deletion' );
1151 // Copied or upgraded the comment_id, as applicable
1152 $ar_comment_id = $dbr->selectField(
1155 [ 'ar_rev_id' => $revid ],
1158 if ( $writeStage > MIGRATION_OLD
) {
1159 $this->assertSame( $comment_id, $ar_comment_id );
1161 $this->assertNotEquals( 0, $ar_comment_id );
1165 // Copied rev_comment, if applicable
1166 if ( $readStage <= MIGRATION_WRITE_BOTH
&& $writeStage <= MIGRATION_WRITE_BOTH
) {
1167 $ar_comment = $dbr->selectField(
1170 [ 'ar_rev_id' => $revid ],
1173 $this->assertSame( 'testing', $ar_comment );
1177 public function provideCommentMigrationOnDeletion() {
1179 [ MIGRATION_OLD
, MIGRATION_OLD
],
1180 [ MIGRATION_OLD
, MIGRATION_WRITE_BOTH
],
1181 [ MIGRATION_OLD
, MIGRATION_WRITE_NEW
],
1182 [ MIGRATION_WRITE_BOTH
, MIGRATION_OLD
],
1183 [ MIGRATION_WRITE_BOTH
, MIGRATION_WRITE_BOTH
],
1184 [ MIGRATION_WRITE_BOTH
, MIGRATION_WRITE_NEW
],
1185 [ MIGRATION_WRITE_BOTH
, MIGRATION_NEW
],
1186 [ MIGRATION_WRITE_NEW
, MIGRATION_WRITE_BOTH
],
1187 [ MIGRATION_WRITE_NEW
, MIGRATION_WRITE_NEW
],
1188 [ MIGRATION_WRITE_NEW
, MIGRATION_NEW
],
1189 [ MIGRATION_NEW
, MIGRATION_WRITE_BOTH
],
1190 [ MIGRATION_NEW
, MIGRATION_WRITE_NEW
],
1191 [ MIGRATION_NEW
, MIGRATION_NEW
],