4 * Tests for MediaWiki api.php?action=edit.
6 * @author Daniel Kinzler
12 class ApiEditPageTest
extends ApiTestCase
{
14 public function setUp() {
15 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
19 $wgExtraNamespaces[12312] = 'Dummy';
20 $wgExtraNamespaces[12313] = 'Dummy_talk';
22 $wgNamespaceContentModels[12312] = "testing";
23 $wgContentHandlers["testing"] = 'DummyContentHandlerForTesting';
25 MWNamespace
::getCanonicalNamespaces( true ); # reset namespace cache
26 $wgContLang->resetNamespaces(); # reset namespace cache
31 public function tearDown() {
32 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
34 unset( $wgExtraNamespaces[12312] );
35 unset( $wgExtraNamespaces[12313] );
37 unset( $wgNamespaceContentModels[12312] );
38 unset( $wgContentHandlers["testing"] );
40 MWNamespace
::getCanonicalNamespaces( true ); # reset namespace cache
41 $wgContLang->resetNamespaces(); # reset namespace cache
47 $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext
49 // -- test new page --------------------------------------------
50 $apiResult = $this->doApiRequestWithToken( array(
53 'text' => 'some text',
55 $apiResult = $apiResult[0];
57 // Validate API result data
58 $this->assertArrayHasKey( 'edit', $apiResult );
59 $this->assertArrayHasKey( 'result', $apiResult['edit'] );
60 $this->assertEquals( 'Success', $apiResult['edit']['result'] );
62 $this->assertArrayHasKey( 'new', $apiResult['edit'] );
63 $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
65 $this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
67 // -- test existing page, no change ----------------------------
68 $data = $this->doApiRequestWithToken( array(
71 'text' => 'some text',
74 $this->assertEquals( 'Success', $data[0]['edit']['result'] );
76 $this->assertArrayNotHasKey( 'new', $data[0]['edit'] );
77 $this->assertArrayHasKey( 'nochange', $data[0]['edit'] );
79 // -- test existing page, with change --------------------------
80 $data = $this->doApiRequestWithToken( array(
83 'text' => 'different text'
86 $this->assertEquals( 'Success', $data[0]['edit']['result'] );
88 $this->assertArrayNotHasKey( 'new', $data[0]['edit'] );
89 $this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] );
91 $this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] );
92 $this->assertArrayHasKey( 'newrevid', $data[0]['edit'] );
93 $this->assertNotEquals(
94 $data[0]['edit']['newrevid'],
95 $data[0]['edit']['oldrevid'],
96 "revision id should change after edit"
100 function testNonTextEdit() {
101 $name = 'Dummy:ApiEditPageTest_testNonTextEdit';
102 $data = serialize( 'some bla bla text' );
104 // -- test new page --------------------------------------------
105 $apiResult = $this->doApiRequestWithToken( array(
108 'text' => $data, ) );
109 $apiResult = $apiResult[0];
111 // Validate API result data
112 $this->assertArrayHasKey( 'edit', $apiResult );
113 $this->assertArrayHasKey( 'result', $apiResult['edit'] );
114 $this->assertEquals( 'Success', $apiResult['edit']['result'] );
116 $this->assertArrayHasKey( 'new', $apiResult['edit'] );
117 $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
119 $this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
121 // validate resulting revision
122 $page = WikiPage
::factory( Title
::newFromText( $name ) );
123 $this->assertEquals( "testing", $page->getContentModel() );
124 $this->assertEquals( $data, $page->getContent()->serialize() );
127 public static function provideEditAppend() {
130 'foo', 'append', 'bar', "foobar"
133 'foo', 'prepend', 'bar', "barfoo"
135 array( #2: append to empty page
136 '', 'append', 'foo', "foo"
138 array( #3: prepend to empty page
139 '', 'prepend', 'foo', "foo"
141 array( #4: append to non-existing page
142 null, 'append', 'foo', "foo"
144 array( #5: prepend to non-existing page
145 null, 'prepend', 'foo', "foo"
151 * @dataProvider provideEditAppend
153 function testEditAppend( $text, $op, $append, $expected ) {
157 // assume NS_HELP defaults to wikitext
158 $name = "Help:ApiEditPageTest_testEditAppend_$count";
160 // -- create page (or not) -----------------------------------------
161 if ( $text !== null ) {
162 if ( $text === '' ) {
163 // can't create an empty page, so create it with some content
164 $this->doApiRequestWithToken( array(
167 'text' => '(dummy)', ) );
170 list( $re ) = $this->doApiRequestWithToken( array(
173 'text' => $text, ) );
175 $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity
178 // -- try append/prepend --------------------------------------------
179 list( $re ) = $this->doApiRequestWithToken( array(
182 $op . 'text' => $append, ) );
184 $this->assertEquals( 'Success', $re['edit']['result'] );
186 // -- validate -----------------------------------------------------
187 $page = new WikiPage( Title
::newFromText( $name ) );
188 $content = $page->getContent();
189 $this->assertNotNull( $content, 'Page should have been created' );
191 $text = $content->getNativeData();
193 $this->assertEquals( $expected, $text );
196 function testEditSection() {
197 $this->markTestIncomplete( "not yet implemented" );
201 * Test action=edit§ion=new
202 * Run it twice so we test adding a new section on a
203 * page that doesn't exist (bug 52830) and one that
206 function testEditNewSection() {
207 $name = 'Help:ApiEditPageTest_testEditNewSection';
209 // Test on a page that does not already exist
210 $this->assertFalse( Title
::newFromText( $name )->exists() );
211 list( $re ) = $this->doApiRequestWithToken( array(
216 'summary' => 'header',
219 $this->assertEquals( 'Success', $re['edit']['result'] );
220 // Check the page text is correct
221 $text = WikiPage
::factory( Title
::newFromText( $name ) )->getContent( Revision
::RAW
)->getNativeData();
222 $this->assertEquals( $text, "== header ==\n\ntest" );
224 // Now on one that does
225 $this->assertTrue( Title
::newFromText( $name )->exists() );
226 list( $re2 ) = $this->doApiRequestWithToken( array(
231 'summary' => 'header',
234 $this->assertEquals( 'Success', $re2['edit']['result'] );
235 $text = WikiPage
::factory( Title
::newFromText( $name ) )->getContent( Revision
::RAW
)->getNativeData();
236 $this->assertEquals( $text, "== header ==\n\ntest\n\n== header ==\n\ntest" );
239 function testUndo() {
240 $this->markTestIncomplete( "not yet implemented" );
243 function testEditConflict() {
247 // assume NS_HELP defaults to wikitext
248 $name = "Help:ApiEditPageTest_testEditConflict_$count";
249 $title = Title
::newFromText( $name );
251 $page = WikiPage
::factory( $title );
254 $page->doEditContent( new WikitextContent( "Foo" ),
255 "testing 1", EDIT_NEW
, false, self
::$users['sysop']->user
);
256 $this->forceRevisionDate( $page, '20120101000000' );
257 $baseTime = $page->getRevision()->getTimestamp();
260 $page->doEditContent( new WikitextContent( "Foo bar" ),
261 "testing 2", EDIT_UPDATE
, $page->getLatest(), self
::$users['uploader']->user
);
262 $this->forceRevisionDate( $page, '20120101020202' );
264 // try to save edit, expect conflict
266 $this->doApiRequestWithToken( array(
269 'text' => 'nix bar!',
270 'basetimestamp' => $baseTime,
271 ), null, self
::$users['sysop']->user
);
273 $this->fail( 'edit conflict expected' );
274 } catch ( UsageException
$ex ) {
275 $this->assertEquals( 'editconflict', $ex->getCodeString() );
279 function testEditConflict_redirect() {
283 // assume NS_HELP defaults to wikitext
284 $name = "Help:ApiEditPageTest_testEditConflict_redirect_$count";
285 $title = Title
::newFromText( $name );
286 $page = WikiPage
::factory( $title );
288 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_r$count";
289 $rtitle = Title
::newFromText( $rname );
290 $rpage = WikiPage
::factory( $rtitle );
292 // base edit for content
293 $page->doEditContent( new WikitextContent( "Foo" ),
294 "testing 1", EDIT_NEW
, false, self
::$users['sysop']->user
);
295 $this->forceRevisionDate( $page, '20120101000000' );
296 $baseTime = $page->getRevision()->getTimestamp();
298 // base edit for redirect
299 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
300 "testing 1", EDIT_NEW
, false, self
::$users['sysop']->user
);
301 $this->forceRevisionDate( $rpage, '20120101000000' );
303 // conflicting edit to redirect
304 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ),
305 "testing 2", EDIT_UPDATE
, $page->getLatest(), self
::$users['uploader']->user
);
306 $this->forceRevisionDate( $rpage, '20120101020202' );
308 // try to save edit; should work, because we follow the redirect
309 list( $re, , ) = $this->doApiRequestWithToken( array(
312 'text' => 'nix bar!',
313 'basetimestamp' => $baseTime,
315 ), null, self
::$users['sysop']->user
);
317 $this->assertEquals( 'Success', $re['edit']['result'],
318 "no edit conflict expected when following redirect" );
320 // try again, without following the redirect. Should fail.
322 $this->doApiRequestWithToken( array(
325 'text' => 'nix bar!',
326 'basetimestamp' => $baseTime,
327 ), null, self
::$users['sysop']->user
);
329 $this->fail( 'edit conflict expected' );
330 } catch ( UsageException
$ex ) {
331 $this->assertEquals( 'editconflict', $ex->getCodeString() );
335 function testEditConflict_bug41990() {
340 * bug 41990: if the target page has a newer revision than the redirect, then editing the
341 * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erronously
342 * caused an edit conflict to be detected.
345 // assume NS_HELP defaults to wikitext
346 $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count";
347 $title = Title
::newFromText( $name );
348 $page = WikiPage
::factory( $title );
350 $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count";
351 $rtitle = Title
::newFromText( $rname );
352 $rpage = WikiPage
::factory( $rtitle );
354 // base edit for content
355 $page->doEditContent( new WikitextContent( "Foo" ),
356 "testing 1", EDIT_NEW
, false, self
::$users['sysop']->user
);
357 $this->forceRevisionDate( $page, '20120101000000' );
359 // base edit for redirect
360 $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
361 "testing 1", EDIT_NEW
, false, self
::$users['sysop']->user
);
362 $this->forceRevisionDate( $rpage, '20120101000000' );
363 $baseTime = $rpage->getRevision()->getTimestamp();
365 // new edit to content
366 $page->doEditContent( new WikitextContent( "Foo bar" ),
367 "testing 2", EDIT_UPDATE
, $page->getLatest(), self
::$users['uploader']->user
);
368 $this->forceRevisionDate( $rpage, '20120101020202' );
370 // try to save edit; should work, following the redirect.
371 list( $re, , ) = $this->doApiRequestWithToken( array(
374 'text' => 'nix bar!',
376 ), null, self
::$users['sysop']->user
);
378 $this->assertEquals( 'Success', $re['edit']['result'],
379 "no edit conflict expected here" );
382 protected function forceRevisionDate( WikiPage
$page, $timestamp ) {
383 $dbw = wfGetDB( DB_MASTER
);
385 $dbw->update( 'revision',
386 array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ),
387 array( 'rev_id' => $page->getLatest() ) );