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