MediaWiki
REL1_24
|
00001 <?php 00002 00014 class ApiEditPageTest extends ApiTestCase { 00015 00016 protected function setUp() { 00017 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; 00018 00019 parent::setUp(); 00020 00021 $this->setMwGlobals( array( 00022 'wgExtraNamespaces' => $wgExtraNamespaces, 00023 'wgNamespaceContentModels' => $wgNamespaceContentModels, 00024 'wgContentHandlers' => $wgContentHandlers, 00025 'wgContLang' => $wgContLang, 00026 ) ); 00027 00028 $wgExtraNamespaces[12312] = 'Dummy'; 00029 $wgExtraNamespaces[12313] = 'Dummy_talk'; 00030 00031 $wgNamespaceContentModels[12312] = "testing"; 00032 $wgContentHandlers["testing"] = 'DummyContentHandlerForTesting'; 00033 00034 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache 00035 $wgContLang->resetNamespaces(); # reset namespace cache 00036 00037 $this->doLogin(); 00038 } 00039 00040 protected function tearDown() { 00041 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache 00042 parent::tearDown(); 00043 } 00044 00045 public function testEdit() { 00046 $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext 00047 00048 // -- test new page -------------------------------------------- 00049 $apiResult = $this->doApiRequestWithToken( array( 00050 'action' => 'edit', 00051 'title' => $name, 00052 'text' => 'some text', 00053 ) ); 00054 $apiResult = $apiResult[0]; 00055 00056 // Validate API result data 00057 $this->assertArrayHasKey( 'edit', $apiResult ); 00058 $this->assertArrayHasKey( 'result', $apiResult['edit'] ); 00059 $this->assertEquals( 'Success', $apiResult['edit']['result'] ); 00060 00061 $this->assertArrayHasKey( 'new', $apiResult['edit'] ); 00062 $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); 00063 00064 $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); 00065 00066 // -- test existing page, no change ---------------------------- 00067 $data = $this->doApiRequestWithToken( array( 00068 'action' => 'edit', 00069 'title' => $name, 00070 'text' => 'some text', 00071 ) ); 00072 00073 $this->assertEquals( 'Success', $data[0]['edit']['result'] ); 00074 00075 $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); 00076 $this->assertArrayHasKey( 'nochange', $data[0]['edit'] ); 00077 00078 // -- test existing page, with change -------------------------- 00079 $data = $this->doApiRequestWithToken( array( 00080 'action' => 'edit', 00081 'title' => $name, 00082 'text' => 'different text' 00083 ) ); 00084 00085 $this->assertEquals( 'Success', $data[0]['edit']['result'] ); 00086 00087 $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); 00088 $this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] ); 00089 00090 $this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] ); 00091 $this->assertArrayHasKey( 'newrevid', $data[0]['edit'] ); 00092 $this->assertNotEquals( 00093 $data[0]['edit']['newrevid'], 00094 $data[0]['edit']['oldrevid'], 00095 "revision id should change after edit" 00096 ); 00097 } 00098 00099 public function testNonTextEdit() { 00100 $name = 'Dummy:ApiEditPageTest_testNonTextEdit'; 00101 $data = serialize( 'some bla bla text' ); 00102 00103 // -- test new page -------------------------------------------- 00104 $apiResult = $this->doApiRequestWithToken( array( 00105 'action' => 'edit', 00106 'title' => $name, 00107 'text' => $data, ) ); 00108 $apiResult = $apiResult[0]; 00109 00110 // Validate API result data 00111 $this->assertArrayHasKey( 'edit', $apiResult ); 00112 $this->assertArrayHasKey( 'result', $apiResult['edit'] ); 00113 $this->assertEquals( 'Success', $apiResult['edit']['result'] ); 00114 00115 $this->assertArrayHasKey( 'new', $apiResult['edit'] ); 00116 $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); 00117 00118 $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); 00119 00120 // validate resulting revision 00121 $page = WikiPage::factory( Title::newFromText( $name ) ); 00122 $this->assertEquals( "testing", $page->getContentModel() ); 00123 $this->assertEquals( $data, $page->getContent()->serialize() ); 00124 } 00125 00129 public static function provideEditAppend() { 00130 return array( 00131 array( #0: append 00132 'foo', 'append', 'bar', "foobar" 00133 ), 00134 array( #1: prepend 00135 'foo', 'prepend', 'bar', "barfoo" 00136 ), 00137 array( #2: append to empty page 00138 '', 'append', 'foo', "foo" 00139 ), 00140 array( #3: prepend to empty page 00141 '', 'prepend', 'foo', "foo" 00142 ), 00143 array( #4: append to non-existing page 00144 null, 'append', 'foo', "foo" 00145 ), 00146 array( #5: prepend to non-existing page 00147 null, 'prepend', 'foo', "foo" 00148 ), 00149 ); 00150 } 00151 00155 public function testEditAppend( $text, $op, $append, $expected ) { 00156 static $count = 0; 00157 $count++; 00158 00159 // assume NS_HELP defaults to wikitext 00160 $name = "Help:ApiEditPageTest_testEditAppend_$count"; 00161 00162 // -- create page (or not) ----------------------------------------- 00163 if ( $text !== null ) { 00164 list( $re ) = $this->doApiRequestWithToken( array( 00165 'action' => 'edit', 00166 'title' => $name, 00167 'text' => $text, ) ); 00168 00169 $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity 00170 } 00171 00172 // -- try append/prepend -------------------------------------------- 00173 list( $re ) = $this->doApiRequestWithToken( array( 00174 'action' => 'edit', 00175 'title' => $name, 00176 $op . 'text' => $append, ) ); 00177 00178 $this->assertEquals( 'Success', $re['edit']['result'] ); 00179 00180 // -- validate ----------------------------------------------------- 00181 $page = new WikiPage( Title::newFromText( $name ) ); 00182 $content = $page->getContent(); 00183 $this->assertNotNull( $content, 'Page should have been created' ); 00184 00185 $text = $content->getNativeData(); 00186 00187 $this->assertEquals( $expected, $text ); 00188 } 00189 00193 public function testEditSection() { 00194 $name = 'Help:ApiEditPageTest_testEditSection'; 00195 $page = WikiPage::factory( Title::newFromText( $name ) ); 00196 $text = "==section 1==\ncontent 1\n==section 2==\ncontent2"; 00197 // Preload the page with some text 00198 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), 'summary' ); 00199 00200 list( $re ) = $this->doApiRequestWithToken( array( 00201 'action' => 'edit', 00202 'title' => $name, 00203 'section' => '1', 00204 'text' => "==section 1==\nnew content 1", 00205 ) ); 00206 $this->assertEquals( 'Success', $re['edit']['result'] ); 00207 $newtext = WikiPage::factory( Title::newFromText( $name ) ) 00208 ->getContent( Revision::RAW ) 00209 ->getNativeData(); 00210 $this->assertEquals( "==section 1==\nnew content 1\n\n==section 2==\ncontent2", $newtext ); 00211 00212 // Test that we raise a 'nosuchsection' error 00213 try { 00214 $this->doApiRequestWithToken( array( 00215 'action' => 'edit', 00216 'title' => $name, 00217 'section' => '9999', 00218 'text' => 'text', 00219 ) ); 00220 $this->fail( "Should have raised a UsageException" ); 00221 } catch ( UsageException $e ) { 00222 $this->assertEquals( 'nosuchsection', $e->getCodeString() ); 00223 } 00224 } 00225 00232 public function testEditNewSection() { 00233 $name = 'Help:ApiEditPageTest_testEditNewSection'; 00234 00235 // Test on a page that does not already exist 00236 $this->assertFalse( Title::newFromText( $name )->exists() ); 00237 list( $re ) = $this->doApiRequestWithToken( array( 00238 'action' => 'edit', 00239 'title' => $name, 00240 'section' => 'new', 00241 'text' => 'test', 00242 'summary' => 'header', 00243 )); 00244 00245 $this->assertEquals( 'Success', $re['edit']['result'] ); 00246 // Check the page text is correct 00247 $text = WikiPage::factory( Title::newFromText( $name ) ) 00248 ->getContent( Revision::RAW ) 00249 ->getNativeData(); 00250 $this->assertEquals( "== header ==\n\ntest", $text ); 00251 00252 // Now on one that does 00253 $this->assertTrue( Title::newFromText( $name )->exists() ); 00254 list( $re2 ) = $this->doApiRequestWithToken( array( 00255 'action' => 'edit', 00256 'title' => $name, 00257 'section' => 'new', 00258 'text' => 'test', 00259 'summary' => 'header', 00260 )); 00261 00262 $this->assertEquals( 'Success', $re2['edit']['result'] ); 00263 $text = WikiPage::factory( Title::newFromText( $name ) ) 00264 ->getContent( Revision::RAW ) 00265 ->getNativeData(); 00266 $this->assertEquals( "== header ==\n\ntest\n\n== header ==\n\ntest", $text ); 00267 } 00268 00272 public function testEdit_redirect() { 00273 static $count = 0; 00274 $count++; 00275 00276 // assume NS_HELP defaults to wikitext 00277 $name = "Help:ApiEditPageTest_testEdit_redirect_$count"; 00278 $title = Title::newFromText( $name ); 00279 $page = WikiPage::factory( $title ); 00280 00281 $rname = "Help:ApiEditPageTest_testEdit_redirect_r$count"; 00282 $rtitle = Title::newFromText( $rname ); 00283 $rpage = WikiPage::factory( $rtitle ); 00284 00285 // base edit for content 00286 $page->doEditContent( new WikitextContent( "Foo" ), 00287 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00288 $this->forceRevisionDate( $page, '20120101000000' ); 00289 $baseTime = $page->getRevision()->getTimestamp(); 00290 00291 // base edit for redirect 00292 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00293 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00294 $this->forceRevisionDate( $rpage, '20120101000000' ); 00295 00296 // conflicting edit to redirect 00297 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), 00298 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00299 $this->forceRevisionDate( $rpage, '20120101020202' ); 00300 00301 // try to save edit, following the redirect 00302 list( $re, , ) = $this->doApiRequestWithToken( array( 00303 'action' => 'edit', 00304 'title' => $rname, 00305 'text' => 'nix bar!', 00306 'basetimestamp' => $baseTime, 00307 'section' => 'new', 00308 'redirect' => true, 00309 ), null, self::$users['sysop']->user ); 00310 00311 $this->assertEquals( 'Success', $re['edit']['result'], 00312 "no problems expected when following redirect" ); 00313 } 00314 00318 public function testEdit_redirectText() { 00319 static $count = 0; 00320 $count++; 00321 00322 // assume NS_HELP defaults to wikitext 00323 $name = "Help:ApiEditPageTest_testEdit_redirectText_$count"; 00324 $title = Title::newFromText( $name ); 00325 $page = WikiPage::factory( $title ); 00326 00327 $rname = "Help:ApiEditPageTest_testEdit_redirectText_r$count"; 00328 $rtitle = Title::newFromText( $rname ); 00329 $rpage = WikiPage::factory( $rtitle ); 00330 00331 // base edit for content 00332 $page->doEditContent( new WikitextContent( "Foo" ), 00333 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00334 $this->forceRevisionDate( $page, '20120101000000' ); 00335 $baseTime = $page->getRevision()->getTimestamp(); 00336 00337 // base edit for redirect 00338 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00339 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00340 $this->forceRevisionDate( $rpage, '20120101000000' ); 00341 00342 // conflicting edit to redirect 00343 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), 00344 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00345 $this->forceRevisionDate( $rpage, '20120101020202' ); 00346 00347 // try to save edit, following the redirect but without creating a section 00348 try { 00349 $this->doApiRequestWithToken( array( 00350 'action' => 'edit', 00351 'title' => $rname, 00352 'text' => 'nix bar!', 00353 'basetimestamp' => $baseTime, 00354 'redirect' => true, 00355 ), null, self::$users['sysop']->user ); 00356 00357 $this->fail( 'redirect-appendonly error expected' ); 00358 } catch ( UsageException $ex ) { 00359 $this->assertEquals( 'redirect-appendonly', $ex->getCodeString() ); 00360 } 00361 } 00362 00363 public function testEditConflict() { 00364 static $count = 0; 00365 $count++; 00366 00367 // assume NS_HELP defaults to wikitext 00368 $name = "Help:ApiEditPageTest_testEditConflict_$count"; 00369 $title = Title::newFromText( $name ); 00370 00371 $page = WikiPage::factory( $title ); 00372 00373 // base edit 00374 $page->doEditContent( new WikitextContent( "Foo" ), 00375 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00376 $this->forceRevisionDate( $page, '20120101000000' ); 00377 $baseTime = $page->getRevision()->getTimestamp(); 00378 00379 // conflicting edit 00380 $page->doEditContent( new WikitextContent( "Foo bar" ), 00381 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00382 $this->forceRevisionDate( $page, '20120101020202' ); 00383 00384 // try to save edit, expect conflict 00385 try { 00386 $this->doApiRequestWithToken( array( 00387 'action' => 'edit', 00388 'title' => $name, 00389 'text' => 'nix bar!', 00390 'basetimestamp' => $baseTime, 00391 ), null, self::$users['sysop']->user ); 00392 00393 $this->fail( 'edit conflict expected' ); 00394 } catch ( UsageException $ex ) { 00395 $this->assertEquals( 'editconflict', $ex->getCodeString() ); 00396 } 00397 } 00398 00402 public function testEditConflict_newSection() { 00403 static $count = 0; 00404 $count++; 00405 00406 // assume NS_HELP defaults to wikitext 00407 $name = "Help:ApiEditPageTest_testEditConflict_newSection_$count"; 00408 $title = Title::newFromText( $name ); 00409 00410 $page = WikiPage::factory( $title ); 00411 00412 // base edit 00413 $page->doEditContent( new WikitextContent( "Foo" ), 00414 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00415 $this->forceRevisionDate( $page, '20120101000000' ); 00416 $baseTime = $page->getRevision()->getTimestamp(); 00417 00418 // conflicting edit 00419 $page->doEditContent( new WikitextContent( "Foo bar" ), 00420 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00421 $this->forceRevisionDate( $page, '20120101020202' ); 00422 00423 // try to save edit, expect no conflict 00424 list( $re, , ) = $this->doApiRequestWithToken( array( 00425 'action' => 'edit', 00426 'title' => $name, 00427 'text' => 'nix bar!', 00428 'basetimestamp' => $baseTime, 00429 'section' => 'new', 00430 ), null, self::$users['sysop']->user ); 00431 00432 $this->assertEquals( 'Success', $re['edit']['result'], 00433 "no edit conflict expected here" ); 00434 } 00435 00436 public function testEditConflict_bug41990() { 00437 static $count = 0; 00438 $count++; 00439 00440 /* 00441 * bug 41990: if the target page has a newer revision than the redirect, then editing the 00442 * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously 00443 * caused an edit conflict to be detected. 00444 */ 00445 00446 // assume NS_HELP defaults to wikitext 00447 $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count"; 00448 $title = Title::newFromText( $name ); 00449 $page = WikiPage::factory( $title ); 00450 00451 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count"; 00452 $rtitle = Title::newFromText( $rname ); 00453 $rpage = WikiPage::factory( $rtitle ); 00454 00455 // base edit for content 00456 $page->doEditContent( new WikitextContent( "Foo" ), 00457 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00458 $this->forceRevisionDate( $page, '20120101000000' ); 00459 00460 // base edit for redirect 00461 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00462 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00463 $this->forceRevisionDate( $rpage, '20120101000000' ); 00464 00465 // new edit to content 00466 $page->doEditContent( new WikitextContent( "Foo bar" ), 00467 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00468 $this->forceRevisionDate( $rpage, '20120101020202' ); 00469 00470 // try to save edit; should work, following the redirect. 00471 list( $re, , ) = $this->doApiRequestWithToken( array( 00472 'action' => 'edit', 00473 'title' => $rname, 00474 'text' => 'nix bar!', 00475 'section' => 'new', 00476 'redirect' => true, 00477 ), null, self::$users['sysop']->user ); 00478 00479 $this->assertEquals( 'Success', $re['edit']['result'], 00480 "no edit conflict expected here" ); 00481 } 00482 00487 protected function forceRevisionDate( WikiPage $page, $timestamp ) { 00488 $dbw = wfGetDB( DB_MASTER ); 00489 00490 $dbw->update( 'revision', 00491 array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), 00492 array( 'rev_id' => $page->getLatest() ) ); 00493 00494 $page->clear(); 00495 } 00496 }