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