MediaWiki  REL1_22
EditPageTest.php
Go to the documentation of this file.
00001 <?php
00002 
00012 class EditPageTest extends MediaWikiLangTestCase {
00013 
00017     public function testExtractSectionTitle( $section, $title ) {
00018         $extracted = EditPage::extractSectionTitle( $section );
00019         $this->assertEquals( $title, $extracted );
00020     }
00021 
00022     public static function provideExtractSectionTitle() {
00023         return array(
00024             array(
00025                 "== Test ==\n\nJust a test section.",
00026                 "Test"
00027             ),
00028             array(
00029                 "An initial section, no header.",
00030                 false
00031             ),
00032             array(
00033                 "An initial section with a fake heder (bug 32617)\n\n== Test == ??\nwtf",
00034                 false
00035             ),
00036             array(
00037                 "== Section ==\nfollowed by a fake == Non-section == ??\nnoooo",
00038                 "Section"
00039             ),
00040             array(
00041                 "== Section== \t\r\n followed by whitespace (bug 35051)",
00042                 'Section',
00043             ),
00044         );
00045     }
00046 
00047     protected function forceRevisionDate( WikiPage $page, $timestamp ) {
00048         $dbw = wfGetDB( DB_MASTER );
00049 
00050         $dbw->update( 'revision',
00051             array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ),
00052             array( 'rev_id' => $page->getLatest() ) );
00053 
00054         $page->clear();
00055     }
00056 
00062     function assertEditedTextEquals( $expected, $actual, $msg = '' ) {
00063         return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg );
00064     }
00065 
00090     protected function assertEdit( $title, $baseText, $user = null, array $edit,
00091         $expectedCode = EditPage::AS_OK, $expectedText = null, $message = null
00092     ) {
00093         if ( is_string( $title ) ) {
00094             $ns = $this->getDefaultWikitextNS();
00095             $title = Title::newFromText( $title, $ns );
00096         }
00097 
00098         if ( is_string( $user ) ) {
00099             $user = User::newFromName( $user );
00100 
00101             if ( $user->getId() === 0 ) {
00102                 $user->addToDatabase();
00103             }
00104         }
00105 
00106         $page = WikiPage::factory( $title );
00107 
00108         if ( $baseText !== null ) {
00109             $content = ContentHandler::makeContent( $baseText, $title );
00110             $page->doEditContent( $content, "base text for test" );
00111             $this->forceRevisionDate( $page, '20120101000000' );
00112 
00113             //sanity check
00114             $page->clear();
00115             $currentText = ContentHandler::getContentText( $page->getContent() );
00116 
00117             # EditPage rtrim() the user input, so we alter our expected text
00118             # to reflect that.
00119             $this->assertEditedTextEquals( $baseText, $currentText );
00120         }
00121 
00122         if ( $user == null ) {
00123             $user = $GLOBALS['wgUser'];
00124         } else {
00125             $this->setMwGlobals( 'wgUser', $user );
00126         }
00127 
00128         if ( !isset( $edit['wpEditToken'] ) ) {
00129             $edit['wpEditToken'] = $user->getEditToken();
00130         }
00131 
00132         if ( !isset( $edit['wpEdittime'] ) ) {
00133             $edit['wpEdittime'] = $page->exists() ? $page->getTimestamp() : '';
00134         }
00135 
00136         if ( !isset( $edit['wpStarttime'] ) ) {
00137             $edit['wpStarttime'] = wfTimestampNow();
00138         }
00139 
00140         $req = new FauxRequest( $edit, true ); // session ??
00141 
00142         $ep = new EditPage( new Article( $title ) );
00143         $ep->setContextTitle( $title );
00144         $ep->importFormData( $req );
00145 
00146         $bot = isset( $edit['bot'] ) ? (bool)$edit['bot'] : false;
00147 
00148         // this is where the edit happens!
00149         // Note: don't want to use EditPage::AttemptSave, because it messes with $wgOut
00150         // and throws exceptions like PermissionsError
00151         $status = $ep->internalAttemptSave( $result, $bot );
00152 
00153         if ( $expectedCode !== null ) {
00154             // check edit code
00155             $this->assertEquals( $expectedCode, $status->value,
00156                 "Expected result code mismatch. $message" );
00157         }
00158 
00159         $page = WikiPage::factory( $title );
00160 
00161         if ( $expectedText !== null ) {
00162             // check resulting page text
00163             $content = $page->getContent();
00164             $text = ContentHandler::getContentText( $content );
00165 
00166             # EditPage rtrim() the user input, so we alter our expected text
00167             # to reflect that.
00168             $this->assertEditedTextEquals( $expectedText, $text,
00169                 "Expected article text mismatch. $message" );
00170         }
00171 
00172         return $page;
00173     }
00174 
00175     public function testCreatePage() {
00176         $this->assertEdit(
00177             'EditPageTest_testCreatePage',
00178             null,
00179             null,
00180             array(
00181                 'wpTextbox1' => "Hello World!",
00182             ),
00183             EditPage::AS_SUCCESS_NEW_ARTICLE,
00184             "Hello World!",
00185             "expected article being created"
00186         )->doDeleteArticleReal( 'EditPageTest_testCreatePage' );
00187 
00188         $this->assertEdit(
00189             'EditPageTest_testCreatePage',
00190             null,
00191             null,
00192             array(
00193                 'wpTextbox1' => "",
00194             ),
00195             EditPage::AS_BLANK_ARTICLE,
00196             null,
00197             "expected article not being created if empty"
00198         );
00199 
00200 
00201         $this->assertEdit(
00202             'MediaWiki:January',
00203             null,
00204             'UTSysop',
00205             array(
00206                 'wpTextbox1' => "Not January",
00207             ),
00208             EditPage::AS_SUCCESS_NEW_ARTICLE,
00209             "Not January",
00210             "expected MediaWiki: page being created"
00211         )->doDeleteArticleReal( 'EditPageTest_testCreatePage' );
00212 
00213         $this->assertEdit(
00214             'MediaWiki:EditPageTest_testCreatePage',
00215             null,
00216             'UTSysop',
00217             array(
00218                 'wpTextbox1' => "",
00219             ),
00220             EditPage::AS_BLANK_ARTICLE,
00221             null,
00222             "expected not-registered MediaWiki: page not being created if empty"
00223         );
00224 
00225         $this->assertEdit(
00226             'MediaWiki:January',
00227             null,
00228             'UTSysop',
00229             array(
00230                 'wpTextbox1' => "",
00231             ),
00232             EditPage::AS_SUCCESS_NEW_ARTICLE,
00233             "",
00234             "expected registered MediaWiki: page being created even if empty"
00235         )->doDeleteArticleReal( 'EditPageTest_testCreatePage' );
00236 
00237         $this->assertEdit(
00238             'MediaWiki:Ipb-default-expiry',
00239             null,
00240             'UTSysop',
00241             array(
00242                 'wpTextbox1' => "",
00243             ),
00244             EditPage::AS_BLANK_ARTICLE,
00245             "",
00246             "expected registered MediaWiki: page whose default content is empty not being created if empty"
00247         );
00248 
00249         $this->assertEdit(
00250             'MediaWiki:January',
00251             null,
00252             'UTSysop',
00253             array(
00254                 'wpTextbox1' => "January",
00255             ),
00256             EditPage::AS_BLANK_ARTICLE,
00257             null,
00258             "expected MediaWiki: page not being created if text equals default message"
00259         );
00260     }
00261 
00262     public function testUpdatePage() {
00263         $text = "one";
00264         $edit = array(
00265             'wpTextbox1' => $text,
00266             'wpSummary' => 'first update',
00267         );
00268 
00269         $page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit,
00270             EditPage::AS_SUCCESS_UPDATE, $text,
00271             "expected successfull update with given text" );
00272 
00273         $this->forceRevisionDate( $page, '20120101000000' );
00274 
00275         $text = "two";
00276         $edit = array(
00277             'wpTextbox1' => $text,
00278             'wpSummary' => 'second update',
00279         );
00280 
00281         $this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit,
00282             EditPage::AS_SUCCESS_UPDATE, $text,
00283             "expected successfull update with given text" );
00284     }
00285 
00286     public static function provideSectionEdit() {
00287         $text = 'Intro
00288 
00289 == one ==
00290 first section.
00291 
00292 == two ==
00293 second section.
00294 ';
00295 
00296         $sectionOne = '== one ==
00297 hello
00298 ';
00299 
00300         $newSection = '== new section ==
00301 
00302 hello
00303 ';
00304 
00305         $textWithNewSectionOne = preg_replace(
00306             '/== one ==.*== two ==/ms',
00307             "$sectionOne\n== two ==", $text
00308         );
00309 
00310         $textWithNewSectionAdded = "$text\n$newSection";
00311 
00312         return array(
00313             array( #0
00314                 $text,
00315                 '',
00316                 'hello',
00317                 'replace all',
00318                 'hello'
00319             ),
00320 
00321             array( #1
00322                 $text,
00323                 '1',
00324                 $sectionOne,
00325                 'replace first section',
00326                 $textWithNewSectionOne,
00327             ),
00328 
00329             array( #2
00330                 $text,
00331                 'new',
00332                 'hello',
00333                 'new section',
00334                 $textWithNewSectionAdded,
00335             ),
00336         );
00337     }
00338 
00342     public function testSectionEdit( $base, $section, $text, $summary, $expected ) {
00343         $edit = array(
00344             'wpTextbox1' => $text,
00345             'wpSummary' => $summary,
00346             'wpSection' => $section,
00347         );
00348 
00349         $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit,
00350             EditPage::AS_SUCCESS_UPDATE, $expected,
00351             "expected successfull update of section" );
00352     }
00353 
00354     public static function provideAutoMerge() {
00355         $tests = array();
00356 
00357         $tests[] = array( #0: plain conflict
00358             "Elmo", # base edit user
00359             "one\n\ntwo\n\nthree\n",
00360             array( #adam's edit
00361                 'wpStarttime' => 1,
00362                 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
00363             ),
00364             array( #berta's edit
00365                 'wpStarttime' => 2,
00366                 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n",
00367             ),
00368             EditPage::AS_CONFLICT_DETECTED, # expected code
00369             "ONE\n\ntwo\n\nthree\n", # expected text
00370             'expected edit conflict', # message
00371         );
00372 
00373         $tests[] = array( #1: successful merge
00374             "Elmo", # base edit user
00375             "one\n\ntwo\n\nthree\n",
00376             array( #adam's edit
00377                 'wpStarttime' => 1,
00378                 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
00379             ),
00380             array( #berta's edit
00381                 'wpStarttime' => 2,
00382                 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n",
00383             ),
00384             EditPage::AS_SUCCESS_UPDATE, # expected code
00385             "ONE\n\ntwo\n\nTHREE\n", # expected text
00386             'expected automatic merge', # message
00387         );
00388 
00389         $text = "Intro\n\n";
00390         $text .= "== first section ==\n\n";
00391         $text .= "one\n\ntwo\n\nthree\n\n";
00392         $text .= "== second section ==\n\n";
00393         $text .= "four\n\nfive\n\nsix\n\n";
00394 
00395         // extract the first section.
00396         $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text );
00397 
00398         // generate expected text after merge
00399         $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) );
00400 
00401         $tests[] = array( #2: merge in section
00402             "Elmo", # base edit user
00403             $text,
00404             array( #adam's edit
00405                 'wpStarttime' => 1,
00406                 'wpTextbox1' => str_replace( 'one', 'ONE', $section ),
00407                 'wpSection' => '1'
00408             ),
00409             array( #berta's edit
00410                 'wpStarttime' => 2,
00411                 'wpTextbox1' => str_replace( 'three', 'THREE', $section ),
00412                 'wpSection' => '1'
00413             ),
00414             EditPage::AS_SUCCESS_UPDATE, # expected code
00415             $expected, # expected text
00416             'expected automatic section merge', # message
00417         );
00418 
00419         // see whether it makes a difference who did the base edit
00420         $testsWithAdam = array_map( function ( $test ) {
00421             $test[0] = 'Adam'; // change base edit user
00422             return $test;
00423         }, $tests );
00424 
00425         $testsWithBerta = array_map( function ( $test ) {
00426             $test[0] = 'Berta'; // change base edit user
00427             return $test;
00428         }, $tests );
00429 
00430         return array_merge( $tests, $testsWithAdam, $testsWithBerta );
00431     }
00432 
00436     public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
00437         $expectedCode, $expectedText, $message = null
00438     ) {
00439         $this->checkHasDiff3();
00440 
00441         //create page
00442         $ns = $this->getDefaultWikitextNS();
00443         $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns );
00444         $page = WikiPage::factory( $title );
00445 
00446         if ( $page->exists() ) {
00447             $page->doDeleteArticle( "clean slate for testing" );
00448         }
00449 
00450         $baseEdit = array(
00451             'wpTextbox1' => $text,
00452         );
00453 
00454         $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null,
00455             $baseUser, $baseEdit, null, null, __METHOD__ );
00456 
00457         $this->forceRevisionDate( $page, '20120101000000' );
00458 
00459         $edittime = $page->getTimestamp();
00460 
00461         // start timestamps for conflict detection
00462         if ( !isset( $adamsEdit['wpStarttime'] ) ) {
00463             $adamsEdit['wpStarttime'] = 1;
00464         }
00465 
00466         if ( !isset( $bertasEdit['wpStarttime'] ) ) {
00467             $bertasEdit['wpStarttime'] = 2;
00468         }
00469 
00470         $starttime = wfTimestampNow();
00471         $adamsTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] );
00472         $bertasTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] );
00473 
00474         $adamsEdit['wpStarttime'] = $adamsTime;
00475         $bertasEdit['wpStarttime'] = $bertasTime;
00476 
00477         $adamsEdit['wpSummary'] = 'Adam\'s edit';
00478         $bertasEdit['wpSummary'] = 'Bertas\'s edit';
00479 
00480         $adamsEdit['wpEdittime'] = $edittime;
00481         $bertasEdit['wpEdittime'] = $edittime;
00482 
00483         // first edit
00484         $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit,
00485             EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" );
00486 
00487         // second edit
00488         $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit,
00489             $expectedCode, $expectedText, $message );
00490     }
00491 }