2012-06-25 14:09:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
2012-08-29 08:07:10 +00:00
|
|
|
* Tests for MediaWiki api.php?action=edit.
|
|
|
|
|
*
|
|
|
|
|
* @author Daniel Kinzler
|
|
|
|
|
*
|
2012-06-25 14:09:08 +00:00
|
|
|
* @group API
|
|
|
|
|
* @group Database
|
2012-11-26 13:49:52 +00:00
|
|
|
* @group medium
|
2013-10-23 16:01:33 +00:00
|
|
|
*
|
|
|
|
|
* @covers ApiEditPage
|
2012-06-25 14:09:08 +00:00
|
|
|
*/
|
|
|
|
|
class ApiEditPageTest extends ApiTestCase {
|
|
|
|
|
|
2013-11-24 00:46:49 +00:00
|
|
|
protected function setUp() {
|
2012-09-12 11:43:52 +00:00
|
|
|
global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
|
|
|
|
|
|
2013-03-22 16:44:34 +00:00
|
|
|
parent::setUp();
|
2012-09-12 11:43:52 +00:00
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->setMwGlobals( [
|
2014-03-05 13:21:35 +00:00
|
|
|
'wgExtraNamespaces' => $wgExtraNamespaces,
|
|
|
|
|
'wgNamespaceContentModels' => $wgNamespaceContentModels,
|
|
|
|
|
'wgContentHandlers' => $wgContentHandlers,
|
|
|
|
|
'wgContLang' => $wgContLang,
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2014-03-05 13:21:35 +00:00
|
|
|
|
2012-10-08 15:26:11 +00:00
|
|
|
$wgExtraNamespaces[12312] = 'Dummy';
|
|
|
|
|
$wgExtraNamespaces[12313] = 'Dummy_talk';
|
2015-04-15 08:26:22 +00:00
|
|
|
$wgExtraNamespaces[12314] = 'DummyNonText';
|
|
|
|
|
$wgExtraNamespaces[12315] = 'DummyNonText_talk';
|
2012-09-12 11:43:52 +00:00
|
|
|
|
2012-10-08 15:26:11 +00:00
|
|
|
$wgNamespaceContentModels[12312] = "testing";
|
2015-04-15 08:26:22 +00:00
|
|
|
$wgNamespaceContentModels[12314] = "testing-nontext";
|
|
|
|
|
|
2012-10-08 15:26:11 +00:00
|
|
|
$wgContentHandlers["testing"] = 'DummyContentHandlerForTesting';
|
2015-04-15 08:26:22 +00:00
|
|
|
$wgContentHandlers["testing-nontext"] = 'DummyNonTextContentHandler';
|
2012-09-12 11:43:52 +00:00
|
|
|
|
|
|
|
|
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
|
|
|
|
|
$wgContLang->resetNamespaces(); # reset namespace cache
|
|
|
|
|
|
2012-06-25 14:09:08 +00:00
|
|
|
$this->doLogin();
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-24 00:46:49 +00:00
|
|
|
protected function tearDown() {
|
2012-09-12 11:43:52 +00:00
|
|
|
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
|
2013-03-22 16:44:34 +00:00
|
|
|
parent::tearDown();
|
2012-09-12 11:43:52 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEdit() {
|
2012-09-19 18:07:56 +00:00
|
|
|
$name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext
|
2012-06-25 14:09:08 +00:00
|
|
|
|
2012-08-29 08:07:10 +00:00
|
|
|
// -- test new page --------------------------------------------
|
2016-02-17 09:09:32 +00:00
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
2013-02-14 11:56:23 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'some text',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2012-08-29 08:07:10 +00:00
|
|
|
$apiResult = $apiResult[0];
|
2012-08-29 08:07:10 +00:00
|
|
|
|
2012-09-12 11:43:52 +00:00
|
|
|
// Validate API result data
|
2012-08-29 08:07:10 +00:00
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'Success', $apiResult['edit']['result'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'new', $apiResult['edit'] );
|
|
|
|
|
$this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
2012-08-29 08:07:10 +00:00
|
|
|
$this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
2012-08-29 08:07:10 +00:00
|
|
|
// -- test existing page, no change ----------------------------
|
2016-02-17 09:09:32 +00:00
|
|
|
$data = $this->doApiRequestWithToken( [
|
2013-02-14 11:56:23 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'some text',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $data[0]['edit']['result'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayNotHasKey( 'new', $data[0]['edit'] );
|
|
|
|
|
$this->assertArrayHasKey( 'nochange', $data[0]['edit'] );
|
|
|
|
|
|
2012-08-29 08:07:10 +00:00
|
|
|
// -- test existing page, with change --------------------------
|
2016-02-17 09:09:32 +00:00
|
|
|
$data = $this->doApiRequestWithToken( [
|
2013-02-14 11:56:23 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'different text'
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $data[0]['edit']['result'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayNotHasKey( 'new', $data[0]['edit'] );
|
|
|
|
|
$this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] );
|
|
|
|
|
$this->assertArrayHasKey( 'newrevid', $data[0]['edit'] );
|
2012-08-29 08:07:10 +00:00
|
|
|
$this->assertNotEquals(
|
|
|
|
|
$data[0]['edit']['newrevid'],
|
|
|
|
|
$data[0]['edit']['oldrevid'],
|
|
|
|
|
"revision id should change after edit"
|
|
|
|
|
);
|
2012-06-25 14:09:08 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-15 14:32:12 +00:00
|
|
|
/**
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2013-03-22 02:12:37 +00:00
|
|
|
public static function provideEditAppend() {
|
2016-02-17 09:09:32 +00:00
|
|
|
return [
|
|
|
|
|
[ # 0: append
|
2012-10-10 19:30:40 +00:00
|
|
|
'foo', 'append', 'bar', "foobar"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
[ # 1: prepend
|
2012-10-10 19:30:40 +00:00
|
|
|
'foo', 'prepend', 'bar', "barfoo"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
[ # 2: append to empty page
|
2012-10-10 19:30:40 +00:00
|
|
|
'', 'append', 'foo', "foo"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
[ # 3: prepend to empty page
|
2012-10-10 19:30:40 +00:00
|
|
|
'', 'prepend', 'foo', "foo"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
[ # 4: append to non-existing page
|
2012-10-10 19:30:40 +00:00
|
|
|
null, 'append', 'foo', "foo"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
[ # 5: prepend to non-existing page
|
2012-10-10 19:30:40 +00:00
|
|
|
null, 'prepend', 'foo', "foo"
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
];
|
2012-06-25 14:09:08 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 19:30:40 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideEditAppend
|
|
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditAppend( $text, $op, $append, $expected ) {
|
2012-10-10 19:30:40 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
|
|
|
|
$name = "Help:ApiEditPageTest_testEditAppend_$count";
|
|
|
|
|
|
|
|
|
|
// -- create page (or not) -----------------------------------------
|
|
|
|
|
if ( $text !== null ) {
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re ) = $this->doApiRequestWithToken( [
|
2012-10-10 19:30:40 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
2016-02-17 09:09:32 +00:00
|
|
|
'text' => $text, ] );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'] ); // sanity
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -- try append/prepend --------------------------------------------
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re ) = $this->doApiRequestWithToken( [
|
2012-10-10 19:30:40 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
2016-02-17 09:09:32 +00:00
|
|
|
$op . 'text' => $append, ] );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
|
|
|
|
$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 );
|
2012-06-25 14:09:08 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-07 05:56:37 +00:00
|
|
|
/**
|
|
|
|
|
* Test editing of sections
|
|
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditSection() {
|
2013-09-07 05:56:37 +00:00
|
|
|
$name = 'Help:ApiEditPageTest_testEditSection';
|
|
|
|
|
$page = WikiPage::factory( Title::newFromText( $name ) );
|
|
|
|
|
$text = "==section 1==\ncontent 1\n==section 2==\ncontent2";
|
|
|
|
|
// Preload the page with some text
|
|
|
|
|
$page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), 'summary' );
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re ) = $this->doApiRequestWithToken( [
|
2013-09-07 05:56:37 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'section' => '1',
|
|
|
|
|
'text' => "==section 1==\nnew content 1",
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-09-07 05:56:37 +00:00
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'] );
|
2014-03-05 13:21:35 +00:00
|
|
|
$newtext = WikiPage::factory( Title::newFromText( $name ) )
|
|
|
|
|
->getContent( Revision::RAW )
|
|
|
|
|
->getNativeData();
|
2014-04-01 11:59:46 +00:00
|
|
|
$this->assertEquals( "==section 1==\nnew content 1\n\n==section 2==\ncontent2", $newtext );
|
2013-09-07 05:56:37 +00:00
|
|
|
|
|
|
|
|
// Test that we raise a 'nosuchsection' error
|
|
|
|
|
try {
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->doApiRequestWithToken( [
|
2013-09-07 05:56:37 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'section' => '9999',
|
|
|
|
|
'text' => 'text',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-09-07 05:56:37 +00:00
|
|
|
$this->fail( "Should have raised a UsageException" );
|
|
|
|
|
} catch ( UsageException $e ) {
|
2014-04-01 11:59:46 +00:00
|
|
|
$this->assertEquals( 'nosuchsection', $e->getCodeString() );
|
2013-09-07 05:56:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-16 05:48:05 +00:00
|
|
|
/**
|
|
|
|
|
* Test action=edit§ion=new
|
|
|
|
|
* Run it twice so we test adding a new section on a
|
|
|
|
|
* page that doesn't exist (bug 52830) and one that
|
|
|
|
|
* does exist
|
|
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditNewSection() {
|
2013-08-16 05:48:05 +00:00
|
|
|
$name = 'Help:ApiEditPageTest_testEditNewSection';
|
|
|
|
|
|
|
|
|
|
// Test on a page that does not already exist
|
|
|
|
|
$this->assertFalse( Title::newFromText( $name )->exists() );
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re ) = $this->doApiRequestWithToken( [
|
2013-08-16 05:48:05 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'test',
|
|
|
|
|
'summary' => 'header',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'] );
|
|
|
|
|
// Check the page text is correct
|
2014-03-05 13:21:35 +00:00
|
|
|
$text = WikiPage::factory( Title::newFromText( $name ) )
|
|
|
|
|
->getContent( Revision::RAW )
|
|
|
|
|
->getNativeData();
|
2014-04-01 11:59:46 +00:00
|
|
|
$this->assertEquals( "== header ==\n\ntest", $text );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
|
|
|
|
// Now on one that does
|
|
|
|
|
$this->assertTrue( Title::newFromText( $name )->exists() );
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re2 ) = $this->doApiRequestWithToken( [
|
2013-08-16 05:48:05 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'test',
|
|
|
|
|
'summary' => 'header',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re2['edit']['result'] );
|
2014-03-05 13:21:35 +00:00
|
|
|
$text = WikiPage::factory( Title::newFromText( $name ) )
|
|
|
|
|
->getContent( Revision::RAW )
|
|
|
|
|
->getNativeData();
|
2014-04-01 11:59:46 +00:00
|
|
|
$this->assertEquals( "== header ==\n\ntest\n\n== header ==\n\ntest", $text );
|
2013-08-16 05:48:05 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
/**
|
|
|
|
|
* Ensure we can edit through a redirect, if adding a section
|
|
|
|
|
*/
|
|
|
|
|
public function testEdit_redirect() {
|
|
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
|
|
|
|
$name = "Help:ApiEditPageTest_testEdit_redirect_$count";
|
|
|
|
|
$title = Title::newFromText( $name );
|
|
|
|
|
$page = WikiPage::factory( $title );
|
|
|
|
|
|
|
|
|
|
$rname = "Help:ApiEditPageTest_testEdit_redirect_r$count";
|
|
|
|
|
$rtitle = Title::newFromText( $rname );
|
|
|
|
|
$rpage = WikiPage::factory( $rtitle );
|
|
|
|
|
|
|
|
|
|
// base edit for content
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseTime = $page->getRevision()->getTimestamp();
|
|
|
|
|
|
|
|
|
|
// base edit for redirect
|
|
|
|
|
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// conflicting edit to redirect
|
|
|
|
|
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit, following the redirect
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re, , ) = $this->doApiRequestWithToken( [
|
2014-05-18 07:04:36 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $rname,
|
|
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'redirect' => true,
|
2016-02-17 09:09:32 +00:00
|
|
|
], null, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'],
|
|
|
|
|
"no problems expected when following redirect" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Ensure we cannot edit through a redirect, if attempting to overwrite content
|
|
|
|
|
*/
|
|
|
|
|
public function testEdit_redirectText() {
|
|
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
|
|
|
|
$name = "Help:ApiEditPageTest_testEdit_redirectText_$count";
|
|
|
|
|
$title = Title::newFromText( $name );
|
|
|
|
|
$page = WikiPage::factory( $title );
|
|
|
|
|
|
|
|
|
|
$rname = "Help:ApiEditPageTest_testEdit_redirectText_r$count";
|
|
|
|
|
$rtitle = Title::newFromText( $rname );
|
|
|
|
|
$rpage = WikiPage::factory( $rtitle );
|
|
|
|
|
|
|
|
|
|
// base edit for content
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseTime = $page->getRevision()->getTimestamp();
|
|
|
|
|
|
|
|
|
|
// base edit for redirect
|
|
|
|
|
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// conflicting edit to redirect
|
|
|
|
|
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit, following the redirect but without creating a section
|
|
|
|
|
try {
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->doApiRequestWithToken( [
|
2014-05-18 07:04:36 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $rname,
|
|
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
|
|
|
|
'redirect' => true,
|
2016-02-17 09:09:32 +00:00
|
|
|
], null, self::$users['sysop']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
|
|
|
|
$this->fail( 'redirect-appendonly error expected' );
|
|
|
|
|
} catch ( UsageException $ex ) {
|
|
|
|
|
$this->assertEquals( 'redirect-appendonly', $ex->getCodeString() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditConflict() {
|
2012-11-12 15:39:29 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
|
|
|
|
$name = "Help:ApiEditPageTest_testEditConflict_$count";
|
|
|
|
|
$title = Title::newFromText( $name );
|
|
|
|
|
|
|
|
|
|
$page = WikiPage::factory( $title );
|
|
|
|
|
|
|
|
|
|
// base edit
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseTime = $page->getRevision()->getTimestamp();
|
|
|
|
|
|
|
|
|
|
// conflicting edit
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo bar" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit, expect conflict
|
|
|
|
|
try {
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->doApiRequestWithToken( [
|
2012-11-12 15:39:29 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
2016-02-17 09:09:32 +00:00
|
|
|
], null, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$this->fail( 'edit conflict expected' );
|
|
|
|
|
} catch ( UsageException $ex ) {
|
|
|
|
|
$this->assertEquals( 'editconflict', $ex->getCodeString() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
/**
|
|
|
|
|
* Ensure that editing using section=new will prevent simple conflicts
|
|
|
|
|
*/
|
|
|
|
|
public function testEditConflict_newSection() {
|
2012-11-12 15:39:29 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
2014-05-18 07:04:36 +00:00
|
|
|
$name = "Help:ApiEditPageTest_testEditConflict_newSection_$count";
|
2012-11-12 15:39:29 +00:00
|
|
|
$title = Title::newFromText( $name );
|
|
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
$page = WikiPage::factory( $title );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
// base edit
|
2012-11-12 15:39:29 +00:00
|
|
|
$page->doEditContent( new WikitextContent( "Foo" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseTime = $page->getRevision()->getTimestamp();
|
|
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
// conflicting edit
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo bar" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101020202' );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
// try to save edit, expect no conflict
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re, , ) = $this->doApiRequestWithToken( [
|
2012-11-12 15:39:29 +00:00
|
|
|
'action' => 'edit',
|
2014-05-18 07:04:36 +00:00
|
|
|
'title' => $name,
|
2012-11-12 15:39:29 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
2014-05-18 07:04:36 +00:00
|
|
|
'section' => 'new',
|
2016-02-17 09:09:32 +00:00
|
|
|
], null, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'],
|
2014-05-18 07:04:36 +00:00
|
|
|
"no edit conflict expected here" );
|
2012-11-12 15:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditConflict_bug41990() {
|
2012-11-12 15:39:29 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* bug 41990: if the target page has a newer revision than the redirect, then editing the
|
2013-10-21 17:29:16 +00:00
|
|
|
* redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously
|
2012-11-12 15:39:29 +00:00
|
|
|
* caused an edit conflict to be detected.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
|
|
|
|
$name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count";
|
|
|
|
|
$title = Title::newFromText( $name );
|
|
|
|
|
$page = WikiPage::factory( $title );
|
|
|
|
|
|
|
|
|
|
$rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count";
|
|
|
|
|
$rtitle = Title::newFromText( $rname );
|
|
|
|
|
$rpage = WikiPage::factory( $rtitle );
|
|
|
|
|
|
|
|
|
|
// base edit for content
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// base edit for redirect
|
|
|
|
|
$rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 1", EDIT_NEW, false, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// new edit to content
|
|
|
|
|
$page->doEditContent( new WikitextContent( "Foo bar" ),
|
2015-08-07 16:10:26 +00:00
|
|
|
"testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit; should work, following the redirect.
|
2016-02-17 09:09:32 +00:00
|
|
|
list( $re, , ) = $this->doApiRequestWithToken( [
|
2012-11-12 15:39:29 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $rname,
|
|
|
|
|
'text' => 'nix bar!',
|
2014-05-18 07:04:36 +00:00
|
|
|
'section' => 'new',
|
2012-11-12 15:39:29 +00:00
|
|
|
'redirect' => true,
|
2016-02-17 09:09:32 +00:00
|
|
|
], null, self::$users['sysop']->getUser() );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$this->assertEquals( 'Success', $re['edit']['result'],
|
|
|
|
|
"no edit conflict expected here" );
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-15 14:32:12 +00:00
|
|
|
/**
|
|
|
|
|
* @param WikiPage $page
|
|
|
|
|
* @param string|int $timestamp
|
|
|
|
|
*/
|
2012-11-12 15:39:29 +00:00
|
|
|
protected function forceRevisionDate( WikiPage $page, $timestamp ) {
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
|
|
|
|
|
$dbw->update( 'revision',
|
2016-02-17 09:09:32 +00:00
|
|
|
[ 'rev_timestamp' => $dbw->timestamp( $timestamp ) ],
|
|
|
|
|
[ 'rev_id' => $page->getLatest() ] );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$page->clear();
|
|
|
|
|
}
|
2015-04-15 08:26:22 +00:00
|
|
|
|
|
|
|
|
public function testCheckDirectApiEditingDisallowed_forNonTextContent() {
|
|
|
|
|
$this->setExpectedException(
|
|
|
|
|
'UsageException',
|
2015-10-03 13:44:13 +00:00
|
|
|
'Direct editing via API is not supported for content model ' .
|
|
|
|
|
'testing used by Dummy:ApiEditPageTest_nonTextPageEdit'
|
2015-04-15 08:26:22 +00:00
|
|
|
);
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->doApiRequestWithToken( [
|
2015-04-15 08:26:22 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => 'Dummy:ApiEditPageTest_nonTextPageEdit',
|
|
|
|
|
'text' => '{"animals":["kittens!"]}'
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2015-04-15 08:26:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSupportsDirectApiEditing_withContentHandlerOverride() {
|
|
|
|
|
$name = 'DummyNonText:ApiEditPageTest_testNonTextEdit';
|
|
|
|
|
$data = serialize( 'some bla bla text' );
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$result = $this->doApiRequestWithToken( [
|
2015-04-15 08:26:22 +00:00
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => $data,
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2015-04-15 08:26:22 +00:00
|
|
|
|
|
|
|
|
$apiResult = $result[0];
|
|
|
|
|
|
|
|
|
|
// Validate API result data
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'Success', $apiResult['edit']['result'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'new', $apiResult['edit'] );
|
|
|
|
|
$this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
|
|
|
|
|
|
|
|
|
|
// validate resulting revision
|
|
|
|
|
$page = WikiPage::factory( Title::newFromText( $name ) );
|
|
|
|
|
$this->assertEquals( "testing-nontext", $page->getContentModel() );
|
|
|
|
|
$this->assertEquals( $data, $page->getContent()->serialize() );
|
|
|
|
|
}
|
2016-09-08 23:43:36 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This test verifies that after changing the content model
|
|
|
|
|
* of a page, undoing that edit via the API will also
|
|
|
|
|
* undo the content model change.
|
|
|
|
|
*/
|
|
|
|
|
public function testUndoAfterContentModelChange() {
|
|
|
|
|
$name = 'Help:' . __FUNCTION__;
|
|
|
|
|
$uploader = self::$users['uploader']->getUser();
|
|
|
|
|
$sysop = self::$users['sysop']->getUser();
|
|
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'some text',
|
|
|
|
|
], null, $sysop )[0];
|
|
|
|
|
|
|
|
|
|
// Check success
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'Success', $apiResult['edit']['result'] );
|
|
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
|
|
|
|
// Content model is wikitext
|
|
|
|
|
$this->assertEquals( 'wikitext', $apiResult['edit']['contentmodel'] );
|
|
|
|
|
|
|
|
|
|
// Convert the page to JSON
|
|
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => '{}',
|
|
|
|
|
'contentmodel' => 'json',
|
|
|
|
|
], null, $uploader )[0];
|
|
|
|
|
|
|
|
|
|
// Check success
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'Success', $apiResult['edit']['result'] );
|
|
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'json', $apiResult['edit']['contentmodel'] );
|
|
|
|
|
|
|
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'undo' => $apiResult['edit']['newrevid']
|
|
|
|
|
], null, $sysop )[0];
|
|
|
|
|
|
|
|
|
|
// Check success
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
|
|
|
|
$this->assertEquals( 'Success', $apiResult['edit']['result'] );
|
|
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
|
|
|
|
// Check that the contentmodel is back to wikitext now.
|
|
|
|
|
$this->assertEquals( 'wikitext', $apiResult['edit']['contentmodel'] );
|
|
|
|
|
}
|
2012-06-25 14:09:08 +00:00
|
|
|
}
|