MediaWiki
REL1_24
|
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 00066 protected function assertEditedTextEquals( $expected, $actual, $msg = '' ) { 00067 return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg ); 00068 } 00069 00095 protected function assertEdit( $title, $baseText, $user = null, array $edit, 00096 $expectedCode = null, $expectedText = null, $message = null 00097 ) { 00098 if ( is_string( $title ) ) { 00099 $ns = $this->getDefaultWikitextNS(); 00100 $title = Title::newFromText( $title, $ns ); 00101 } 00102 $this->assertNotNull( $title ); 00103 00104 if ( is_string( $user ) ) { 00105 $user = User::newFromName( $user ); 00106 00107 if ( $user->getId() === 0 ) { 00108 $user->addToDatabase(); 00109 } 00110 } 00111 00112 $page = WikiPage::factory( $title ); 00113 00114 if ( $baseText !== null ) { 00115 $content = ContentHandler::makeContent( $baseText, $title ); 00116 $page->doEditContent( $content, "base text for test" ); 00117 $this->forceRevisionDate( $page, '20120101000000' ); 00118 00119 //sanity check 00120 $page->clear(); 00121 $currentText = ContentHandler::getContentText( $page->getContent() ); 00122 00123 # EditPage rtrim() the user input, so we alter our expected text 00124 # to reflect that. 00125 $this->assertEditedTextEquals( $baseText, $currentText ); 00126 } 00127 00128 if ( $user == null ) { 00129 $user = $GLOBALS['wgUser']; 00130 } else { 00131 $this->setMwGlobals( 'wgUser', $user ); 00132 } 00133 00134 if ( !isset( $edit['wpEditToken'] ) ) { 00135 $edit['wpEditToken'] = $user->getEditToken(); 00136 } 00137 00138 if ( !isset( $edit['wpEdittime'] ) ) { 00139 $edit['wpEdittime'] = $page->exists() ? $page->getTimestamp() : ''; 00140 } 00141 00142 if ( !isset( $edit['wpStarttime'] ) ) { 00143 $edit['wpStarttime'] = wfTimestampNow(); 00144 } 00145 00146 $req = new FauxRequest( $edit, true ); // session ?? 00147 00148 $article = new Article( $title ); 00149 $article->getContext()->setTitle( $title ); 00150 $ep = new EditPage( $article ); 00151 $ep->setContextTitle( $title ); 00152 $ep->importFormData( $req ); 00153 00154 $bot = isset( $edit['bot'] ) ? (bool)$edit['bot'] : false; 00155 00156 // this is where the edit happens! 00157 // Note: don't want to use EditPage::AttemptSave, because it messes with $wgOut 00158 // and throws exceptions like PermissionsError 00159 $status = $ep->internalAttemptSave( $result, $bot ); 00160 00161 if ( $expectedCode !== null ) { 00162 // check edit code 00163 $this->assertEquals( $expectedCode, $status->value, 00164 "Expected result code mismatch. $message" ); 00165 } 00166 00167 $page = WikiPage::factory( $title ); 00168 00169 if ( $expectedText !== null ) { 00170 // check resulting page text 00171 $content = $page->getContent(); 00172 $text = ContentHandler::getContentText( $content ); 00173 00174 # EditPage rtrim() the user input, so we alter our expected text 00175 # to reflect that. 00176 $this->assertEditedTextEquals( $expectedText, $text, 00177 "Expected article text mismatch. $message" ); 00178 } 00179 00180 return $page; 00181 } 00182 00183 public static function provideCreatePages() { 00184 return array( 00185 array( 'expected article being created', 00186 'EditPageTest_testCreatePage', 00187 null, 00188 'Hello World!', 00189 EditPage::AS_SUCCESS_NEW_ARTICLE, 00190 'Hello World!' 00191 ), 00192 array( 'expected article not being created if empty', 00193 'EditPageTest_testCreatePage', 00194 null, 00195 '', 00196 EditPage::AS_BLANK_ARTICLE, 00197 null 00198 ), 00199 array( 'expected MediaWiki: page being created', 00200 'MediaWiki:January', 00201 'UTSysop', 00202 'Not January', 00203 EditPage::AS_SUCCESS_NEW_ARTICLE, 00204 'Not January' 00205 ), 00206 array( 'expected not-registered MediaWiki: page not being created if empty', 00207 'MediaWiki:EditPageTest_testCreatePage', 00208 'UTSysop', 00209 '', 00210 EditPage::AS_BLANK_ARTICLE, 00211 null 00212 ), 00213 array( 'expected registered MediaWiki: page being created even if empty', 00214 'MediaWiki:January', 00215 'UTSysop', 00216 '', 00217 EditPage::AS_SUCCESS_NEW_ARTICLE, 00218 '' 00219 ), 00220 array( 'expected registered MediaWiki: page whose default content is empty not being created if empty', 00221 'MediaWiki:Ipb-default-expiry', 00222 'UTSysop', 00223 '', 00224 EditPage::AS_BLANK_ARTICLE, 00225 '' 00226 ), 00227 array( 'expected MediaWiki: page not being created if text equals default message', 00228 'MediaWiki:January', 00229 'UTSysop', 00230 'January', 00231 EditPage::AS_BLANK_ARTICLE, 00232 null 00233 ), 00234 array( 'expected empty article being created', 00235 'EditPageTest_testCreatePage', 00236 null, 00237 '', 00238 EditPage::AS_SUCCESS_NEW_ARTICLE, 00239 '', 00240 true 00241 ), 00242 ); 00243 } 00244 00249 public function testCreatePage( $desc, $pageTitle, $user, $editText, $expectedCode, $expectedText, $ignoreBlank = false ) { 00250 $edit = array( 'wpTextbox1' => $editText ); 00251 if ( $ignoreBlank ) { 00252 $edit['wpIgnoreBlankArticle'] = 1; 00253 } 00254 00255 $page = $this->assertEdit( $pageTitle, null, $user, $edit, $expectedCode, $expectedText, $desc ); 00256 00257 if ( $expectedCode != EditPage::AS_BLANK_ARTICLE ) { 00258 $page->doDeleteArticleReal( $pageTitle ); 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 00343 public function testSectionEdit( $base, $section, $text, $summary, $expected ) { 00344 $edit = array( 00345 'wpTextbox1' => $text, 00346 'wpSummary' => $summary, 00347 'wpSection' => $section, 00348 ); 00349 00350 $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit, 00351 EditPage::AS_SUCCESS_UPDATE, $expected, 00352 "expected successfull update of section" ); 00353 } 00354 00355 public static function provideAutoMerge() { 00356 $tests = array(); 00357 00358 $tests[] = array( #0: plain conflict 00359 "Elmo", # base edit user 00360 "one\n\ntwo\n\nthree\n", 00361 array( #adam's edit 00362 'wpStarttime' => 1, 00363 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", 00364 ), 00365 array( #berta's edit 00366 'wpStarttime' => 2, 00367 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n", 00368 ), 00369 EditPage::AS_CONFLICT_DETECTED, # expected code 00370 "ONE\n\ntwo\n\nthree\n", # expected text 00371 'expected edit conflict', # message 00372 ); 00373 00374 $tests[] = array( #1: successful merge 00375 "Elmo", # base edit user 00376 "one\n\ntwo\n\nthree\n", 00377 array( #adam's edit 00378 'wpStarttime' => 1, 00379 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", 00380 ), 00381 array( #berta's edit 00382 'wpStarttime' => 2, 00383 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n", 00384 ), 00385 EditPage::AS_SUCCESS_UPDATE, # expected code 00386 "ONE\n\ntwo\n\nTHREE\n", # expected text 00387 'expected automatic merge', # message 00388 ); 00389 00390 $text = "Intro\n\n"; 00391 $text .= "== first section ==\n\n"; 00392 $text .= "one\n\ntwo\n\nthree\n\n"; 00393 $text .= "== second section ==\n\n"; 00394 $text .= "four\n\nfive\n\nsix\n\n"; 00395 00396 // extract the first section. 00397 $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text ); 00398 00399 // generate expected text after merge 00400 $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) ); 00401 00402 $tests[] = array( #2: merge in section 00403 "Elmo", # base edit user 00404 $text, 00405 array( #adam's edit 00406 'wpStarttime' => 1, 00407 'wpTextbox1' => str_replace( 'one', 'ONE', $section ), 00408 'wpSection' => '1' 00409 ), 00410 array( #berta's edit 00411 'wpStarttime' => 2, 00412 'wpTextbox1' => str_replace( 'three', 'THREE', $section ), 00413 'wpSection' => '1' 00414 ), 00415 EditPage::AS_SUCCESS_UPDATE, # expected code 00416 $expected, # expected text 00417 'expected automatic section merge', # message 00418 ); 00419 00420 // see whether it makes a difference who did the base edit 00421 $testsWithAdam = array_map( function ( $test ) { 00422 $test[0] = 'Adam'; // change base edit user 00423 return $test; 00424 }, $tests ); 00425 00426 $testsWithBerta = array_map( function ( $test ) { 00427 $test[0] = 'Berta'; // change base edit user 00428 return $test; 00429 }, $tests ); 00430 00431 return array_merge( $tests, $testsWithAdam, $testsWithBerta ); 00432 } 00433 00438 public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit, 00439 $expectedCode, $expectedText, $message = null 00440 ) { 00441 $this->checkHasDiff3(); 00442 00443 //create page 00444 $ns = $this->getDefaultWikitextNS(); 00445 $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns ); 00446 $page = WikiPage::factory( $title ); 00447 00448 if ( $page->exists() ) { 00449 $page->doDeleteArticle( "clean slate for testing" ); 00450 } 00451 00452 $baseEdit = array( 00453 'wpTextbox1' => $text, 00454 ); 00455 00456 $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null, 00457 $baseUser, $baseEdit, null, null, __METHOD__ ); 00458 00459 $this->forceRevisionDate( $page, '20120101000000' ); 00460 00461 $edittime = $page->getTimestamp(); 00462 00463 // start timestamps for conflict detection 00464 if ( !isset( $adamsEdit['wpStarttime'] ) ) { 00465 $adamsEdit['wpStarttime'] = 1; 00466 } 00467 00468 if ( !isset( $bertasEdit['wpStarttime'] ) ) { 00469 $bertasEdit['wpStarttime'] = 2; 00470 } 00471 00472 $starttime = wfTimestampNow(); 00473 $adamsTime = wfTimestamp( 00474 TS_MW, 00475 (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] 00476 ); 00477 $bertasTime = wfTimestamp( 00478 TS_MW, 00479 (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] 00480 ); 00481 00482 $adamsEdit['wpStarttime'] = $adamsTime; 00483 $bertasEdit['wpStarttime'] = $bertasTime; 00484 00485 $adamsEdit['wpSummary'] = 'Adam\'s edit'; 00486 $bertasEdit['wpSummary'] = 'Bertas\'s edit'; 00487 00488 $adamsEdit['wpEdittime'] = $edittime; 00489 $bertasEdit['wpEdittime'] = $edittime; 00490 00491 // first edit 00492 $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit, 00493 EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" ); 00494 00495 // second edit 00496 $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit, 00497 $expectedCode, $expectedText, $message ); 00498 } 00499 }