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