MediaWiki
REL1_23
|
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 if ( $text === '' ) { 00165 // can't create an empty page, so create it with some content 00166 $this->doApiRequestWithToken( array( 00167 'action' => 'edit', 00168 'title' => $name, 00169 'text' => '(dummy)', ) ); 00170 } 00171 00172 list( $re ) = $this->doApiRequestWithToken( array( 00173 'action' => 'edit', 00174 'title' => $name, 00175 'text' => $text, ) ); 00176 00177 $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity 00178 } 00179 00180 // -- try append/prepend -------------------------------------------- 00181 list( $re ) = $this->doApiRequestWithToken( array( 00182 'action' => 'edit', 00183 'title' => $name, 00184 $op . 'text' => $append, ) ); 00185 00186 $this->assertEquals( 'Success', $re['edit']['result'] ); 00187 00188 // -- validate ----------------------------------------------------- 00189 $page = new WikiPage( Title::newFromText( $name ) ); 00190 $content = $page->getContent(); 00191 $this->assertNotNull( $content, 'Page should have been created' ); 00192 00193 $text = $content->getNativeData(); 00194 00195 $this->assertEquals( $expected, $text ); 00196 } 00197 00201 public function testEditSection() { 00202 $name = 'Help:ApiEditPageTest_testEditSection'; 00203 $page = WikiPage::factory( Title::newFromText( $name ) ); 00204 $text = "==section 1==\ncontent 1\n==section 2==\ncontent2"; 00205 // Preload the page with some text 00206 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), 'summary' ); 00207 00208 list( $re ) = $this->doApiRequestWithToken( array( 00209 'action' => 'edit', 00210 'title' => $name, 00211 'section' => '1', 00212 'text' => "==section 1==\nnew content 1", 00213 ) ); 00214 $this->assertEquals( 'Success', $re['edit']['result'] ); 00215 $newtext = WikiPage::factory( Title::newFromText( $name ) ) 00216 ->getContent( Revision::RAW ) 00217 ->getNativeData(); 00218 $this->assertEquals( "==section 1==\nnew content 1\n\n==section 2==\ncontent2", $newtext ); 00219 00220 // Test that we raise a 'nosuchsection' error 00221 try { 00222 $this->doApiRequestWithToken( array( 00223 'action' => 'edit', 00224 'title' => $name, 00225 'section' => '9999', 00226 'text' => 'text', 00227 ) ); 00228 $this->fail( "Should have raised a UsageException" ); 00229 } catch ( UsageException $e ) { 00230 $this->assertEquals( 'nosuchsection', $e->getCodeString() ); 00231 } 00232 } 00233 00240 public function testEditNewSection() { 00241 $name = 'Help:ApiEditPageTest_testEditNewSection'; 00242 00243 // Test on a page that does not already exist 00244 $this->assertFalse( Title::newFromText( $name )->exists() ); 00245 list( $re ) = $this->doApiRequestWithToken( array( 00246 'action' => 'edit', 00247 'title' => $name, 00248 'section' => 'new', 00249 'text' => 'test', 00250 'summary' => 'header', 00251 )); 00252 00253 $this->assertEquals( 'Success', $re['edit']['result'] ); 00254 // Check the page text is correct 00255 $text = WikiPage::factory( Title::newFromText( $name ) ) 00256 ->getContent( Revision::RAW ) 00257 ->getNativeData(); 00258 $this->assertEquals( "== header ==\n\ntest", $text ); 00259 00260 // Now on one that does 00261 $this->assertTrue( Title::newFromText( $name )->exists() ); 00262 list( $re2 ) = $this->doApiRequestWithToken( array( 00263 'action' => 'edit', 00264 'title' => $name, 00265 'section' => 'new', 00266 'text' => 'test', 00267 'summary' => 'header', 00268 )); 00269 00270 $this->assertEquals( 'Success', $re2['edit']['result'] ); 00271 $text = WikiPage::factory( Title::newFromText( $name ) ) 00272 ->getContent( Revision::RAW ) 00273 ->getNativeData(); 00274 $this->assertEquals( "== header ==\n\ntest\n\n== header ==\n\ntest", $text ); 00275 } 00276 00277 public function testEditConflict() { 00278 static $count = 0; 00279 $count++; 00280 00281 // assume NS_HELP defaults to wikitext 00282 $name = "Help:ApiEditPageTest_testEditConflict_$count"; 00283 $title = Title::newFromText( $name ); 00284 00285 $page = WikiPage::factory( $title ); 00286 00287 // base edit 00288 $page->doEditContent( new WikitextContent( "Foo" ), 00289 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00290 $this->forceRevisionDate( $page, '20120101000000' ); 00291 $baseTime = $page->getRevision()->getTimestamp(); 00292 00293 // conflicting edit 00294 $page->doEditContent( new WikitextContent( "Foo bar" ), 00295 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00296 $this->forceRevisionDate( $page, '20120101020202' ); 00297 00298 // try to save edit, expect conflict 00299 try { 00300 $this->doApiRequestWithToken( array( 00301 'action' => 'edit', 00302 'title' => $name, 00303 'text' => 'nix bar!', 00304 'basetimestamp' => $baseTime, 00305 ), null, self::$users['sysop']->user ); 00306 00307 $this->fail( 'edit conflict expected' ); 00308 } catch ( UsageException $ex ) { 00309 $this->assertEquals( 'editconflict', $ex->getCodeString() ); 00310 } 00311 } 00312 00313 public function testEditConflict_redirect() { 00314 static $count = 0; 00315 $count++; 00316 00317 // assume NS_HELP defaults to wikitext 00318 $name = "Help:ApiEditPageTest_testEditConflict_redirect_$count"; 00319 $title = Title::newFromText( $name ); 00320 $page = WikiPage::factory( $title ); 00321 00322 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_r$count"; 00323 $rtitle = Title::newFromText( $rname ); 00324 $rpage = WikiPage::factory( $rtitle ); 00325 00326 // base edit for content 00327 $page->doEditContent( new WikitextContent( "Foo" ), 00328 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00329 $this->forceRevisionDate( $page, '20120101000000' ); 00330 $baseTime = $page->getRevision()->getTimestamp(); 00331 00332 // base edit for redirect 00333 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00334 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00335 $this->forceRevisionDate( $rpage, '20120101000000' ); 00336 00337 // conflicting edit to redirect 00338 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), 00339 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00340 $this->forceRevisionDate( $rpage, '20120101020202' ); 00341 00342 // try to save edit; should work, because we follow the redirect 00343 list( $re, , ) = $this->doApiRequestWithToken( array( 00344 'action' => 'edit', 00345 'title' => $rname, 00346 'text' => 'nix bar!', 00347 'basetimestamp' => $baseTime, 00348 'redirect' => true, 00349 ), null, self::$users['sysop']->user ); 00350 00351 $this->assertEquals( 'Success', $re['edit']['result'], 00352 "no edit conflict expected when following redirect" ); 00353 00354 // try again, without following the redirect. Should fail. 00355 try { 00356 $this->doApiRequestWithToken( array( 00357 'action' => 'edit', 00358 'title' => $rname, 00359 'text' => 'nix bar!', 00360 'basetimestamp' => $baseTime, 00361 ), null, self::$users['sysop']->user ); 00362 00363 $this->fail( 'edit conflict expected' ); 00364 } catch ( UsageException $ex ) { 00365 $this->assertEquals( 'editconflict', $ex->getCodeString() ); 00366 } 00367 } 00368 00369 public function testEditConflict_bug41990() { 00370 static $count = 0; 00371 $count++; 00372 00373 /* 00374 * bug 41990: if the target page has a newer revision than the redirect, then editing the 00375 * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously 00376 * caused an edit conflict to be detected. 00377 */ 00378 00379 // assume NS_HELP defaults to wikitext 00380 $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count"; 00381 $title = Title::newFromText( $name ); 00382 $page = WikiPage::factory( $title ); 00383 00384 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count"; 00385 $rtitle = Title::newFromText( $rname ); 00386 $rpage = WikiPage::factory( $rtitle ); 00387 00388 // base edit for content 00389 $page->doEditContent( new WikitextContent( "Foo" ), 00390 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00391 $this->forceRevisionDate( $page, '20120101000000' ); 00392 00393 // base edit for redirect 00394 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00395 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00396 $this->forceRevisionDate( $rpage, '20120101000000' ); 00397 00398 // new edit to content 00399 $page->doEditContent( new WikitextContent( "Foo bar" ), 00400 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00401 $this->forceRevisionDate( $rpage, '20120101020202' ); 00402 00403 // try to save edit; should work, following the redirect. 00404 list( $re, , ) = $this->doApiRequestWithToken( array( 00405 'action' => 'edit', 00406 'title' => $rname, 00407 'text' => 'nix bar!', 00408 'redirect' => true, 00409 ), null, self::$users['sysop']->user ); 00410 00411 $this->assertEquals( 'Success', $re['edit']['result'], 00412 "no edit conflict expected here" ); 00413 } 00414 00419 protected function forceRevisionDate( WikiPage $page, $timestamp ) { 00420 $dbw = wfGetDB( DB_MASTER ); 00421 00422 $dbw->update( 'revision', 00423 array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), 00424 array( 'rev_id' => $page->getLatest() ) ); 00425 00426 $page->clear(); 00427 } 00428 }