MediaWiki
REL1_21
|
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 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 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 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 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 list( $re, , ) = $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 00196 function testEditSection() { 00197 $this->markTestIncomplete( "not yet implemented" ); 00198 } 00199 00200 function testUndo() { 00201 $this->markTestIncomplete( "not yet implemented" ); 00202 } 00203 00204 function testEditConflict() { 00205 static $count = 0; 00206 $count++; 00207 00208 // assume NS_HELP defaults to wikitext 00209 $name = "Help:ApiEditPageTest_testEditConflict_$count"; 00210 $title = Title::newFromText( $name ); 00211 00212 $page = WikiPage::factory( $title ); 00213 00214 // base edit 00215 $page->doEditContent( new WikitextContent( "Foo" ), 00216 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00217 $this->forceRevisionDate( $page, '20120101000000' ); 00218 $baseTime = $page->getRevision()->getTimestamp(); 00219 00220 // conflicting edit 00221 $page->doEditContent( new WikitextContent( "Foo bar" ), 00222 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00223 $this->forceRevisionDate( $page, '20120101020202' ); 00224 00225 // try to save edit, expect conflict 00226 try { 00227 list( $re, , ) = $this->doApiRequestWithToken( array( 00228 'action' => 'edit', 00229 'title' => $name, 00230 'text' => 'nix bar!', 00231 'basetimestamp' => $baseTime, 00232 ), null, self::$users['sysop']->user ); 00233 00234 $this->fail( 'edit conflict expected' ); 00235 } catch ( UsageException $ex ) { 00236 $this->assertEquals( 'editconflict', $ex->getCodeString() ); 00237 } 00238 } 00239 00240 function testEditConflict_redirect() { 00241 static $count = 0; 00242 $count++; 00243 00244 // assume NS_HELP defaults to wikitext 00245 $name = "Help:ApiEditPageTest_testEditConflict_redirect_$count"; 00246 $title = Title::newFromText( $name ); 00247 $page = WikiPage::factory( $title ); 00248 00249 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_r$count"; 00250 $rtitle = Title::newFromText( $rname ); 00251 $rpage = WikiPage::factory( $rtitle ); 00252 00253 // base edit for content 00254 $page->doEditContent( new WikitextContent( "Foo" ), 00255 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00256 $this->forceRevisionDate( $page, '20120101000000' ); 00257 $baseTime = $page->getRevision()->getTimestamp(); 00258 00259 // base edit for redirect 00260 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00261 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00262 $this->forceRevisionDate( $rpage, '20120101000000' ); 00263 00264 // conflicting edit to redirect 00265 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), 00266 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00267 $this->forceRevisionDate( $rpage, '20120101020202' ); 00268 00269 // try to save edit; should work, because we follow the redirect 00270 list( $re, , ) = $this->doApiRequestWithToken( array( 00271 'action' => 'edit', 00272 'title' => $rname, 00273 'text' => 'nix bar!', 00274 'basetimestamp' => $baseTime, 00275 'redirect' => true, 00276 ), null, self::$users['sysop']->user ); 00277 00278 $this->assertEquals( 'Success', $re['edit']['result'], 00279 "no edit conflict expected when following redirect" ); 00280 00281 // try again, without following the redirect. Should fail. 00282 try { 00283 list( $re, , ) = $this->doApiRequestWithToken( array( 00284 'action' => 'edit', 00285 'title' => $rname, 00286 'text' => 'nix bar!', 00287 'basetimestamp' => $baseTime, 00288 ), null, self::$users['sysop']->user ); 00289 00290 $this->fail( 'edit conflict expected' ); 00291 } catch ( UsageException $ex ) { 00292 $this->assertEquals( 'editconflict', $ex->getCodeString() ); 00293 } 00294 } 00295 00296 function testEditConflict_bug41990() { 00297 static $count = 0; 00298 $count++; 00299 00300 /* 00301 * bug 41990: if the target page has a newer revision than the redirect, then editing the 00302 * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erronously 00303 * caused an edit conflict to be detected. 00304 */ 00305 00306 // assume NS_HELP defaults to wikitext 00307 $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count"; 00308 $title = Title::newFromText( $name ); 00309 $page = WikiPage::factory( $title ); 00310 00311 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count"; 00312 $rtitle = Title::newFromText( $rname ); 00313 $rpage = WikiPage::factory( $rtitle ); 00314 00315 // base edit for content 00316 $page->doEditContent( new WikitextContent( "Foo" ), 00317 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00318 $this->forceRevisionDate( $page, '20120101000000' ); 00319 00320 // base edit for redirect 00321 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), 00322 "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); 00323 $this->forceRevisionDate( $rpage, '20120101000000' ); 00324 $baseTime = $rpage->getRevision()->getTimestamp(); 00325 00326 // new edit to content 00327 $page->doEditContent( new WikitextContent( "Foo bar" ), 00328 "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); 00329 $this->forceRevisionDate( $rpage, '20120101020202' ); 00330 00331 // try to save edit; should work, following the redirect. 00332 list( $re, , ) = $this->doApiRequestWithToken( array( 00333 'action' => 'edit', 00334 'title' => $rname, 00335 'text' => 'nix bar!', 00336 'redirect' => true, 00337 ), null, self::$users['sysop']->user ); 00338 00339 $this->assertEquals( 'Success', $re['edit']['result'], 00340 "no edit conflict expected here" ); 00341 } 00342 00343 protected function forceRevisionDate( WikiPage $page, $timestamp ) { 00344 $dbw = wfGetDB( DB_MASTER ); 00345 00346 $dbw->update( 'revision', 00347 array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), 00348 array( 'rev_id' => $page->getLatest() ) ); 00349 00350 $page->clear(); 00351 } 00352 }