MediaWiki  master
EditPageTest.php
Go to the documentation of this file.
00001 <?php
00002 
00012 class EditPageTest extends MediaWikiTestCase {
00013 
00017         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' => $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                 $text = "Hello World!";
00177                 $edit = array(
00178                         'wpTextbox1' => $text,
00179                         'wpSummary' => 'just testing',
00180                 );
00181 
00182                 $this->assertEdit( 'EditPageTest_testCreatePafe', null, null, $edit,
00183                         EditPage::AS_SUCCESS_NEW_ARTICLE, $text,
00184                         "expected successfull creation with given text" );
00185         }
00186 
00187         public function testUpdatePage() {
00188                 $text = "one";
00189                 $edit = array(
00190                         'wpTextbox1' => $text,
00191                         'wpSummary' => 'first update',
00192                 );
00193 
00194                 $page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit,
00195                         EditPage::AS_SUCCESS_UPDATE, $text,
00196                         "expected successfull update with given text" );
00197 
00198                 $this->forceRevisionDate( $page, '20120101000000' );
00199 
00200                 $text = "two";
00201                 $edit = array(
00202                         'wpTextbox1' => $text,
00203                         'wpSummary' => 'second update',
00204                 );
00205 
00206                 $this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit,
00207                         EditPage::AS_SUCCESS_UPDATE, $text,
00208                         "expected successfull update with given text" );
00209         }
00210 
00211         public static function provideSectionEdit() {
00212                 $text =
00213 'Intro
00214 
00215 == one ==
00216 first section.
00217 
00218 == two ==
00219 second section.
00220 ';
00221 
00222                 $sectionOne =
00223 '== one ==
00224 hello
00225 ';
00226 
00227                 $newSection =
00228 '== new section ==
00229 
00230 hello
00231 ';
00232 
00233                 $textWithNewSectionOne = preg_replace( '/== one ==.*== two ==/ms',
00234                                                                                 "$sectionOne\n== two ==", $text );
00235 
00236                 $textWithNewSectionAdded = "$text\n$newSection";
00237 
00238                 return array(
00239                         array( #0
00240                                 $text,
00241                                 '',
00242                                 'hello',
00243                                 'replace all',
00244                                 'hello'
00245                         ),
00246 
00247                         array( #1
00248                                 $text,
00249                                 '1',
00250                                 $sectionOne,
00251                                 'replace first section',
00252                                 $textWithNewSectionOne,
00253                         ),
00254 
00255                         array( #2
00256                                 $text,
00257                                 'new',
00258                                 'hello',
00259                                 'new section',
00260                                 $textWithNewSectionAdded,
00261                         ),
00262                 );
00263         }
00264 
00268         public function testSectionEdit( $base, $section, $text, $summary, $expected ) {
00269                 $edit = array(
00270                         'wpTextbox1' => $text,
00271                         'wpSummary' => $summary,
00272                         'wpSection' => $section,
00273                 );
00274 
00275                 $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit,
00276                         EditPage::AS_SUCCESS_UPDATE, $expected,
00277                         "expected successfull update of section" );
00278         }
00279 
00280         public static function provideAutoMerge() {
00281                 $tests = array();
00282 
00283                 $tests[] = array( #0: plain conflict
00284                         "Elmo", # base edit user
00285                         "one\n\ntwo\n\nthree\n",
00286                         array( #adam's edit
00287                                 'wpStarttime' => 1,
00288                                 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
00289                         ),
00290                         array( #berta's edit
00291                                 'wpStarttime' => 2,
00292                                 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n",
00293                         ),
00294                         EditPage::AS_CONFLICT_DETECTED, # expected code
00295                         "ONE\n\ntwo\n\nthree\n", # expected text
00296                         'expected edit conflict', # message
00297                 );
00298 
00299                 $tests[] = array( #1: successful merge
00300                         "Elmo", # base edit user
00301                         "one\n\ntwo\n\nthree\n",
00302                         array( #adam's edit
00303                                 'wpStarttime' => 1,
00304                                 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n",
00305                         ),
00306                         array( #berta's edit
00307                                 'wpStarttime' => 2,
00308                                 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n",
00309                         ),
00310                         EditPage::AS_SUCCESS_UPDATE, # expected code
00311                         "ONE\n\ntwo\n\nTHREE\n", # expected text
00312                         'expected automatic merge', # message
00313                 );
00314 
00315                 $text = "Intro\n\n";
00316                 $text .= "== first section ==\n\n";
00317                 $text .= "one\n\ntwo\n\nthree\n\n";
00318                 $text .= "== second section ==\n\n";
00319                 $text .= "four\n\nfive\n\nsix\n\n";
00320 
00321                 // extract the first section.
00322                 $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text );
00323 
00324                 // generate expected text after merge
00325                 $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) );
00326 
00327                 $tests[] = array( #2: merge in section
00328                         "Elmo", # base edit user
00329                         $text,
00330                         array( #adam's edit
00331                                 'wpStarttime' => 1,
00332                                 'wpTextbox1' => str_replace( 'one', 'ONE', $section ),
00333                                 'wpSection' => '1'
00334                         ),
00335                         array( #berta's edit
00336                                 'wpStarttime' => 2,
00337                                 'wpTextbox1' => str_replace( 'three', 'THREE', $section ),
00338                                 'wpSection' => '1'
00339                         ),
00340                         EditPage::AS_SUCCESS_UPDATE, # expected code
00341                         $expected, # expected text
00342                         'expected automatic section merge', # message
00343                 );
00344 
00345                 // see whether it makes a difference who did the base edit
00346                 $testsWithAdam = array_map( function( $test ) {
00347                         $test[0] = 'Adam'; // change base edit user
00348                         return $test;
00349                 }, $tests );
00350 
00351                 $testsWithBerta = array_map( function( $test ) {
00352                         $test[0] = 'Berta'; // change base edit user
00353                         return $test;
00354                 }, $tests );
00355 
00356                 return array_merge( $tests, $testsWithAdam, $testsWithBerta );
00357         }
00358 
00359         function testHasValidDiff3() {
00360                 global $wgDiff3;
00361 
00362                 if ( !$wgDiff3 ) {
00363                         $this->markTestSkipped( "Can't test conflict resolution because \$wgDiff3 is not configured" );
00364                 } elseif ( !file_exists( $wgDiff3 ) ) {
00365                         #XXX: this sucks, since it uses arcane internal knowledge about TextContentHandler::merge3 and wfMerge.
00366                         $this->markTestSkipped( "Can't test conflict resolution because \$wgDiff3 is misconfigured: can't find $wgDiff3" );
00367                 }
00368                 $this->assertTrue( true );
00369         }
00370 
00375         public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
00376                                 $expectedCode, $expectedText, $message = null
00377         ) {
00378 
00379                 //create page
00380                 $ns = $this->getDefaultWikitextNS();
00381                 $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns );
00382                 $page = WikiPage::factory( $title );
00383 
00384                 if ( $page->exists() ) {
00385                         $page->doDeleteArticle( "clean slate for testing" );
00386                 }
00387 
00388                 $baseEdit = array(
00389                         'wpTextbox1' => $text,
00390                 );
00391 
00392                 $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null,
00393                                         $baseUser, $baseEdit, null, null, __METHOD__ );
00394 
00395                 $this->forceRevisionDate( $page, '20120101000000' );
00396 
00397                 $edittime = $page->getTimestamp();
00398 
00399                 // start timestamps for conflict detection
00400                 if ( !isset( $adamsEdit['wpStarttime'] ) ) {
00401                         $adamsEdit['wpStarttime'] = 1;
00402                 }
00403 
00404                 if ( !isset( $bertasEdit['wpStarttime'] ) ) {
00405                         $bertasEdit['wpStarttime'] = 2;
00406                 }
00407 
00408                 $starttime = wfTimestampNow();
00409                 $adamsTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] );
00410                 $bertasTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] );
00411 
00412                 $adamsEdit['wpStarttime'] = $adamsTime;
00413                 $bertasEdit['wpStarttime'] = $bertasTime;
00414 
00415                 $adamsEdit['wpSummary'] = 'Adam\'s edit';
00416                 $bertasEdit['wpSummary'] = 'Bertas\'s edit';
00417 
00418                 $adamsEdit['wpEdittime'] = $edittime;
00419                 $bertasEdit['wpEdittime'] = $edittime;
00420 
00421                 // first edit
00422                 $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit,
00423                         EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" );
00424 
00425                 // second edit
00426                 $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit,
00427                         $expectedCode, $expectedText, $message );
00428         }
00429 }