(bug 40930) Fix regression: ContentHandler prevents action=edit append to blank page
authorBrad Jorsch <anomie.wikipedia@gmail.com>
Wed, 10 Oct 2012 19:30:40 +0000 (15:30 -0400)
committerdaniel <daniel.kinzler@wikimedia.de>
Mon, 15 Oct 2012 13:45:39 +0000 (15:45 +0200)
Before the ContentHandler merge, using action=edit&appendtext=... on a
non-existent page would treat the page as if it existed but had no
content. After the merge, it throws an error incorrectly claiming that
appending is not supported for wikitext.

The fix is to create a new, empty content object when appending and
there is no existing content.

Change-Id: I61f2cf3911a7d9d8553fc3f745e545cb1bcfd270

includes/api/ApiEditPage.php
tests/phpunit/includes/api/ApiEditPageTest.php

index 87302e6..ca62bc6 100644 (file)
@@ -128,17 +128,10 @@ class ApiEditPage extends ApiBase {
                {
                        $content = $pageObj->getContent();
 
-                       // @todo: Add support for appending/prepending to the Content interface
-
-                       if ( !( $content instanceof TextContent ) ) {
-                               $mode = $contentHandler->getModelID();
-                               $this->dieUsage( "Can't append to pages using content model $mode", 'appendnotsupported' );
-                       }
-
                        if ( !$content ) {
-                               # If this is a MediaWiki:x message, then load the messages
-                               # and return the message value for x.
                                if ( $titleObj->getNamespace() == NS_MEDIAWIKI ) {
+                                       # If this is a MediaWiki:x message, then load the messages
+                                       # and return the message value for x.
                                        $text = $titleObj->getDefaultMessageText();
                                        if ( $text === false ) {
                                                $text = '';
@@ -150,9 +143,19 @@ class ApiEditPage extends ApiBase {
                                                $this->dieUsage( $ex->getMessage(), 'parseerror' );
                                                return;
                                        }
+                               } else {
+                                       # Otherwise, make a new empty content.
+                                       $content = $contentHandler->makeEmptyContent();
                                }
                        }
 
+                       // @todo: Add support for appending/prepending to the Content interface
+
+                       if ( !( $content instanceof TextContent ) ) {
+                               $mode = $contentHandler->getModelID();
+                               $this->dieUsage( "Can't append to pages using content model $mode", 'appendnotsupported' );
+                       }
+
                        if ( !is_null( $params['section'] ) ) {
                                if ( !$contentHandler->supportsSections() ) {
                                        $modelName = $contentHandler->getModelID();
index 8eca9a3..624cf49 100644 (file)
@@ -120,19 +120,80 @@ class ApiEditPageTest extends ApiTestCase {
                $this->assertEquals( $data, $page->getContent()->serialize() );
        }
 
-       function testEditAppend() {
-               $this->markTestIncomplete( "not yet implemented" );
+       static function provideEditAppend() {
+               return array(
+                       array( #0: append
+                               'foo', 'append', 'bar', "foobar"
+                       ),
+                       array( #1: prepend
+                               'foo', 'prepend', 'bar', "barfoo"
+                       ),
+                       array( #2: append to empty page
+                               '', 'append', 'foo', "foo"
+                       ),
+                       array( #3: prepend to empty page
+                               '', 'prepend', 'foo', "foo"
+                       ),
+                       array( #4: append to non-existing page
+                               null, 'append', 'foo', "foo"
+                       ),
+                       array( #5: prepend to non-existing page
+                               null, 'prepend', 'foo', "foo"
+                       ),
+               );
        }
 
-       function testEditSection() {
-               $this->markTestIncomplete( "not yet implemented" );
+       /**
+        * @dataProvider provideEditAppend
+        */
+       function testEditAppend( $text, $op, $append, $expected ) {
+               static $count = 0;
+               $count++;
+
+               // assume NS_HELP defaults to wikitext
+               $name = "Help:ApiEditPageTest_testEditAppend_$count";
+
+               // -- create page (or not) -----------------------------------------
+               if ( $text !== null ) {
+                       if ( $text === '' ) {
+                               // can't create an empty page, so create it with some content
+                               list( $re,, ) = $this->doApiRequestWithToken( array(
+                                       'action' => 'edit',
+                                       'title' => $name,
+                                       'text' => '(dummy)', ) );
+                       }
+
+                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                               'action' => 'edit',
+                               'title' => $name,
+                               'text' => $text, ) );
+
+                       $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity
+               }
+
+               // -- try append/prepend --------------------------------------------
+               list( $re,, ) = $this->doApiRequestWithToken( array(
+                       'action' => 'edit',
+                       'title' => $name,
+                       $op . 'text' => $append, ) );
+
+               $this->assertEquals( 'Success', $re['edit']['result'] );
+
+               // -- validate -----------------------------------------------------
+               $page = new WikiPage( Title::newFromText( $name ) );
+               $content = $page->getContent();
+               $this->assertNotNull( $content, 'Page should have been created' );
+
+               $text = $content->getNativeData();
+
+               $this->assertEquals( $expected, $text );
        }
 
-       function testUndo() {
+       function testEditSection() {
                $this->markTestIncomplete( "not yet implemented" );
        }
 
-       function testEditNonText() {
+       function testUndo() {
                $this->markTestIncomplete( "not yet implemented" );
        }
 }