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