MediaWiki
REL1_22
|
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 }