2012-06-25 14:09:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlock;
|
2022-07-06 15:05:30 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2020-07-03 00:20:38 +00:00
|
|
|
use MediaWiki\Revision\RevisionRecord;
|
2023-08-25 12:29:41 +00:00
|
|
|
use MediaWiki\Status\Status;
|
2023-03-01 20:33:26 +00:00
|
|
|
use MediaWiki\Title\Title;
|
2023-09-18 13:56:39 +00:00
|
|
|
use MediaWiki\Title\TitleValue;
|
2023-09-19 12:13:45 +00:00
|
|
|
use MediaWiki\User\User;
|
2023-08-19 03:35:06 +00:00
|
|
|
use MediaWiki\Utils\MWTimestamp;
|
2019-05-13 14:18:07 +00:00
|
|
|
|
2012-06-25 14:09:08 +00:00
|
|
|
/**
|
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 {
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
protected function setUp(): void {
|
2013-03-22 16:44:34 +00:00
|
|
|
parent::setUp();
|
2012-09-12 11:43:52 +00:00
|
|
|
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValues( [
|
|
|
|
|
MainConfigNames::ExtraNamespaces => [
|
2018-08-01 12:40:47 +00:00
|
|
|
12312 => 'Dummy',
|
|
|
|
|
12313 => 'Dummy_talk',
|
|
|
|
|
12314 => 'DummyNonText',
|
|
|
|
|
12315 => 'DummyNonText_talk',
|
|
|
|
|
],
|
2022-07-06 15:05:30 +00:00
|
|
|
MainConfigNames::NamespaceContentModels => [
|
2018-08-01 12:40:47 +00:00
|
|
|
12312 => 'testing',
|
|
|
|
|
12314 => 'testing-nontext',
|
|
|
|
|
],
|
2022-07-06 15:05:30 +00:00
|
|
|
MainConfigNames::WatchlistExpiry => true,
|
|
|
|
|
MainConfigNames::WatchlistExpiryMaxDuration => '6 months',
|
2018-08-01 12:40:47 +00:00
|
|
|
] );
|
|
|
|
|
$this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
|
|
|
|
|
'testing' => 'DummyContentHandlerForTesting',
|
|
|
|
|
'testing-nontext' => 'DummyNonTextContentHandler',
|
|
|
|
|
'testing-serialize-error' => 'DummySerializeErrorContentHandler',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2018-09-04 19:50:46 +00:00
|
|
|
$this->tablesUsed = array_merge(
|
|
|
|
|
$this->tablesUsed,
|
2020-06-04 20:16:23 +00:00
|
|
|
[ 'change_tag', 'change_tag_def', 'logging', 'watchlist', 'watchlist_expiry' ]
|
2018-09-04 19:50:46 +00:00
|
|
|
);
|
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'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $apiResult['edit']['result'] );
|
2012-08-29 08:07:10 +00:00
|
|
|
|
|
|
|
|
$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
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $data[0]['edit']['result'] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
|
|
|
|
$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
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $data[0]['edit']['result'] );
|
2012-06-25 14:09:08 +00:00
|
|
|
|
|
|
|
|
$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
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditAppend_$count" );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
|
|
|
|
// -- create page (or not) -----------------------------------------
|
|
|
|
|
if ( $text !== null ) {
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re ] = $this->doApiRequestWithToken( [
|
2012-10-10 19:30:40 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2016-02-17 09:09:32 +00:00
|
|
|
'text' => $text, ] );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
2021-11-21 16:23:11 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'] );
|
2012-10-10 19:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -- try append/prepend --------------------------------------------
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re ] = $this->doApiRequestWithToken( [
|
2012-10-10 19:30:40 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2016-02-17 09:09:32 +00:00
|
|
|
$op . 'text' => $append, ] );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'] );
|
2012-10-10 19:30:40 +00:00
|
|
|
|
|
|
|
|
// -- validate -----------------------------------------------------
|
2023-07-28 21:47:54 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2012-10-10 19:30:40 +00:00
|
|
|
$content = $page->getContent();
|
|
|
|
|
$this->assertNotNull( $content, 'Page should have been created' );
|
|
|
|
|
|
2019-02-07 00:14:23 +00:00
|
|
|
$text = $content->getText();
|
2012-10-10 19:30:40 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( $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() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'ApiEditPageTest_testEditSection' );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2023-07-28 21:47:54 +00:00
|
|
|
$page = $wikiPageFactory->newFromTitle( $title );
|
2013-09-07 05:56:37 +00:00
|
|
|
$text = "==section 1==\ncontent 1\n==section 2==\ncontent2";
|
|
|
|
|
// Preload the page with some text
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
2023-07-29 09:44:29 +00:00
|
|
|
$page->getContentHandler()->unserializeContent( $text ),
|
2022-08-05 19:39:42 +00:00
|
|
|
$this->getTestSysop()->getAuthority(),
|
2021-06-24 08:42:19 +00:00
|
|
|
'summary'
|
|
|
|
|
);
|
2013-09-07 05:56:37 +00:00
|
|
|
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re ] = $this->doApiRequestWithToken( [
|
2013-09-07 05:56:37 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2013-09-07 05:56:37 +00:00
|
|
|
'section' => '1',
|
|
|
|
|
'text' => "==section 1==\nnew content 1",
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'] );
|
2023-07-28 21:47:54 +00:00
|
|
|
$newtext = $wikiPageFactory->newFromTitle( $title )
|
2020-07-03 00:20:38 +00:00
|
|
|
->getContent( RevisionRecord::RAW )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( "==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',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2013-09-07 05:56:37 +00:00
|
|
|
'section' => '9999',
|
|
|
|
|
'text' => 'text',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2016-10-19 16:54:25 +00:00
|
|
|
$this->fail( "Should have raised an ApiUsageException" );
|
|
|
|
|
} catch ( ApiUsageException $e ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'nosuchsection', $e );
|
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
|
2017-02-20 23:45:58 +00:00
|
|
|
* page that doesn't exist (T54830) and one that
|
2013-08-16 05:48:05 +00:00
|
|
|
* does exist
|
|
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testEditNewSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'ApiEditPageTest_testEditNewSection' );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2013-08-16 05:48:05 +00:00
|
|
|
|
|
|
|
|
// Test on a page that does not already exist
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists() );
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re ] = $this->doApiRequestWithToken( [
|
2013-08-16 05:48:05 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2013-08-16 05:48:05 +00:00
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'test',
|
|
|
|
|
'summary' => 'header',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'] );
|
2013-08-16 05:48:05 +00:00
|
|
|
// Check the page text is correct
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $wikiPageFactory->newFromTitle( $title )
|
2020-07-03 00:20:38 +00:00
|
|
|
->getContent( RevisionRecord::RAW )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( "== header ==\n\ntest", $text );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
|
|
|
|
// Now on one that does
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re2 ] = $this->doApiRequestWithToken( [
|
2013-08-16 05:48:05 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2013-08-16 05:48:05 +00:00
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'test',
|
|
|
|
|
'summary' => 'header',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2013-08-16 05:48:05 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re2['edit']['result'] );
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $wikiPageFactory->newFromTitle( $title )
|
2020-07-03 00:20:38 +00:00
|
|
|
->getContent( RevisionRecord::RAW )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( "== header ==\n\ntest\n\n== header ==\n\ntest", $text );
|
2013-08-16 05:48:05 +00:00
|
|
|
}
|
|
|
|
|
|
2022-06-13 20:53:45 +00:00
|
|
|
/**
|
|
|
|
|
* Test action=edit§ion=new with different combinations of summary and sectiontitle.
|
|
|
|
|
*
|
|
|
|
|
* @dataProvider provideEditNewSectionSummarySectiontitle
|
|
|
|
|
*/
|
|
|
|
|
public function testEditNewSectionSummarySectiontitle(
|
|
|
|
|
$sectiontitle,
|
|
|
|
|
$summary,
|
|
|
|
|
$expectedText,
|
|
|
|
|
$expectedSummary
|
|
|
|
|
) {
|
|
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'ApiEditPageTest_testEditNewSectionSummarySectiontitle' . $count );
|
2022-06-13 20:53:45 +00:00
|
|
|
|
2022-06-28 20:24:09 +00:00
|
|
|
// Test edit 1 (new page)
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2022-06-28 20:24:09 +00:00
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'text',
|
|
|
|
|
'sectiontitle' => $sectiontitle,
|
|
|
|
|
'summary' => $summary,
|
|
|
|
|
] );
|
|
|
|
|
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2023-07-28 21:47:54 +00:00
|
|
|
$wikiPage = $wikiPageFactory->newFromTitle( $title );
|
2022-06-28 20:24:09 +00:00
|
|
|
|
|
|
|
|
// Check the page text is correct
|
|
|
|
|
$savedText = $wikiPage->getContent( RevisionRecord::RAW )->getText();
|
|
|
|
|
$this->assertSame( $expectedText, $savedText, 'Correct text saved (new page)' );
|
|
|
|
|
|
|
|
|
|
// Check that the edit summary is correct
|
|
|
|
|
// (when not provided or empty, there is an autogenerated summary for page creation)
|
|
|
|
|
$savedSummary = $wikiPage->getRevisionRecord()->getComment( RevisionRecord::RAW )->text;
|
|
|
|
|
$expectedSummaryNew = $expectedSummary ?: wfMessage( 'autosumm-new' )->rawParams( $expectedText )
|
|
|
|
|
->inContentLanguage()->text();
|
|
|
|
|
$this->assertSame( $expectedSummaryNew, $savedSummary, 'Correct summary saved (new page)' );
|
|
|
|
|
|
|
|
|
|
// Clear the page
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $wikiPage, '' );
|
2022-06-13 20:53:45 +00:00
|
|
|
|
2022-06-28 20:24:09 +00:00
|
|
|
// Test edit 2 (existing page)
|
2022-06-13 20:53:45 +00:00
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2022-06-13 20:53:45 +00:00
|
|
|
'section' => 'new',
|
|
|
|
|
'text' => 'text',
|
|
|
|
|
'sectiontitle' => $sectiontitle,
|
|
|
|
|
'summary' => $summary,
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$wikiPage = $wikiPageFactory->newFromTitle( $title );
|
2022-06-13 20:53:45 +00:00
|
|
|
|
|
|
|
|
// Check the page text is correct
|
2022-06-28 20:24:09 +00:00
|
|
|
$savedText = $wikiPage->getContent( RevisionRecord::RAW )->getText();
|
|
|
|
|
$this->assertSame( $expectedText, $savedText, 'Correct text saved (existing page)' );
|
2022-06-13 20:53:45 +00:00
|
|
|
|
|
|
|
|
// Check that the edit summary is correct
|
2022-06-28 20:24:09 +00:00
|
|
|
$savedSummary = $wikiPage->getRevisionRecord()->getComment( RevisionRecord::RAW )->text;
|
|
|
|
|
$this->assertSame( $expectedSummary, $savedSummary, 'Correct summary saved (existing page)' );
|
2022-06-13 20:53:45 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideEditNewSectionSummarySectiontitle() {
|
2022-06-13 20:53:45 +00:00
|
|
|
$sectiontitleCases = [
|
|
|
|
|
'unset' => null,
|
|
|
|
|
'empty' => '',
|
|
|
|
|
'set' => 'sectiontitle',
|
|
|
|
|
];
|
|
|
|
|
$summaryCases = [
|
|
|
|
|
'unset' => null,
|
|
|
|
|
'empty' => '',
|
|
|
|
|
'set' => 'summary',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$expectedTexts = [
|
|
|
|
|
"text",
|
|
|
|
|
"text",
|
|
|
|
|
"== summary ==\n\ntext",
|
|
|
|
|
"text",
|
|
|
|
|
"text",
|
2022-06-13 21:45:47 +00:00
|
|
|
"text",
|
2022-06-13 20:53:45 +00:00
|
|
|
"== sectiontitle ==\n\ntext",
|
|
|
|
|
"== sectiontitle ==\n\ntext",
|
|
|
|
|
"== sectiontitle ==\n\ntext",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$expectedSummaries = [
|
|
|
|
|
'',
|
|
|
|
|
'',
|
|
|
|
|
'/* summary */ new section',
|
|
|
|
|
'',
|
|
|
|
|
'',
|
2022-06-13 21:45:47 +00:00
|
|
|
'summary',
|
2022-06-13 20:53:45 +00:00
|
|
|
'/* sectiontitle */ new section',
|
|
|
|
|
'/* sectiontitle */ new section',
|
|
|
|
|
'summary',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$i = 0;
|
|
|
|
|
foreach ( $sectiontitleCases as $sectiontitleDesc => $sectiontitle ) {
|
|
|
|
|
foreach ( $summaryCases as $summaryDesc => $summary ) {
|
|
|
|
|
$message = "sectiontitle $sectiontitleDesc, summary $summaryDesc";
|
|
|
|
|
yield $message => [
|
|
|
|
|
$sectiontitle,
|
|
|
|
|
$summary,
|
|
|
|
|
$expectedTexts[$i],
|
|
|
|
|
$expectedSummaries[$i],
|
|
|
|
|
];
|
|
|
|
|
$i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEdit_redirect_$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2023-07-16 23:53:31 +00:00
|
|
|
$page = $this->getExistingTestPage( $title );
|
|
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$rtitle = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEdit_redirect_r$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$rpage = $wikiPageFactory->newFromTitle( $rtitle );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
2020-04-18 02:39:58 +00:00
|
|
|
$baseTime = $page->getRevisionRecord()->getTimestamp();
|
2014-05-18 07:04:36 +00:00
|
|
|
|
|
|
|
|
// base edit for redirect
|
2021-06-24 08:42:19 +00:00
|
|
|
$rpage->doUserEditContent(
|
2023-07-28 21:47:54 +00:00
|
|
|
new WikitextContent( "#REDIRECT [[{$title->getPrefixedText()}]]" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// conflicting edit to redirect
|
2021-06-24 08:42:19 +00:00
|
|
|
$rpage->doUserEditContent(
|
2023-07-28 21:47:54 +00:00
|
|
|
new WikitextContent( "#REDIRECT [[{$title->getPrefixedText()}]]\n\n[[Category:Test]]" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit, following the redirect
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re, , ] = $this->doApiRequestWithToken( [
|
2014-05-18 07:04:36 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $rtitle->getPrefixedText(),
|
2014-05-18 07:04:36 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'redirect' => true,
|
2018-03-28 12:32:19 +00:00
|
|
|
] );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'],
|
2014-05-18 07:04:36 +00:00
|
|
|
"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
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEdit_redirectText_$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2023-07-16 23:53:31 +00:00
|
|
|
$page = $this->getExistingTestPage( $title );
|
|
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseTime = $page->getRevisionRecord()->getTimestamp();
|
2014-05-18 07:04:36 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$rtitle = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEdit_redirectText_r$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$rpage = $wikiPageFactory->newFromTitle( $rtitle );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
|
|
|
|
// base edit for redirect
|
2021-06-24 08:42:19 +00:00
|
|
|
$rpage->doUserEditContent(
|
2023-07-28 21:47:54 +00:00
|
|
|
new WikitextContent( "#REDIRECT [[{$title->getPrefixedText()}]]" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2014-05-18 07:04:36 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// conflicting edit to redirect
|
2021-06-24 08:42:19 +00:00
|
|
|
$rpage->doUserEditContent(
|
2023-07-28 21:47:54 +00:00
|
|
|
new WikitextContent( "#REDIRECT [[{$title->getPrefixedText()}]]\n\n[[Category:Test]]" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
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',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $rtitle->getPrefixedText(),
|
2014-05-18 07:04:36 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
|
|
|
|
'redirect' => true,
|
2018-03-28 12:32:19 +00:00
|
|
|
] );
|
2014-05-18 07:04:36 +00:00
|
|
|
|
|
|
|
|
$this->fail( 'redirect-appendonly error expected' );
|
2016-10-19 16:54:25 +00:00
|
|
|
} catch ( ApiUsageException $ex ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'redirect-appendonly', $ex );
|
2014-05-18 07:04:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 21:23:07 +00:00
|
|
|
public function testEditConflict_revid() {
|
|
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditConflict_$count" );
|
2020-03-05 21:23:07 +00:00
|
|
|
|
2022-09-01 21:18:41 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2020-03-05 21:23:07 +00:00
|
|
|
|
|
|
|
|
// base edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2020-03-05 21:23:07 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
2020-04-18 02:39:58 +00:00
|
|
|
$baseId = $page->getRevisionRecord()->getId();
|
2020-03-05 21:23:07 +00:00
|
|
|
|
|
|
|
|
// conflicting edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo bar" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2020-03-05 21:23:07 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit, expect conflict
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2020-03-05 21:23:07 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'baserevid' => $baseId,
|
2023-07-16 23:53:31 +00:00
|
|
|
], null, $this->getTestSysop()->getUser() );
|
2020-03-05 21:23:07 +00:00
|
|
|
|
|
|
|
|
$this->fail( 'edit conflict expected' );
|
|
|
|
|
} catch ( ApiUsageException $ex ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'editconflict', $ex );
|
2020-03-05 21:23:07 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditConflict_timestamp() {
|
2012-11-12 15:39:29 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditConflict_$count" );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2022-09-01 21:18:41 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
// base edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
2020-04-18 02:39:58 +00:00
|
|
|
$baseTime = $page->getRevisionRecord()->getTimestamp();
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
// conflicting edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo bar" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
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',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2012-11-12 15:39:29 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
2018-03-28 12:32:19 +00:00
|
|
|
] );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$this->fail( 'edit conflict expected' );
|
2016-10-19 16:54:25 +00:00
|
|
|
} catch ( ApiUsageException $ex ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'editconflict', $ex );
|
2012-11-12 15:39:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditConflict_newSection_$count" );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2022-09-01 21:18:41 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
// base edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
2020-04-18 02:39:58 +00:00
|
|
|
$baseTime = $page->getRevisionRecord()->getTimestamp();
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2014-05-18 07:04:36 +00:00
|
|
|
// conflicting edit
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo bar" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
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
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re, , ] = $this->doApiRequestWithToken( [
|
2012-11-12 15:39:29 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2012-11-12 15:39:29 +00:00
|
|
|
'text' => 'nix bar!',
|
|
|
|
|
'basetimestamp' => $baseTime,
|
2014-05-18 07:04:36 +00:00
|
|
|
'section' => 'new',
|
2018-03-28 12:32:19 +00:00
|
|
|
] );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( '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
|
|
|
}
|
|
|
|
|
|
2018-08-18 13:51:29 +00:00
|
|
|
public function testEditConflict_T43990() {
|
2012-11-12 15:39:29 +00:00
|
|
|
static $count = 0;
|
|
|
|
|
$count++;
|
|
|
|
|
|
|
|
|
|
/*
|
2019-05-30 10:29:37 +00:00
|
|
|
* T43990: if the target page has a newer revision than the redirect, then editing the
|
|
|
|
|
* redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously
|
|
|
|
|
* caused an edit conflict to be detected.
|
|
|
|
|
*/
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
// assume NS_HELP defaults to wikitext
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditConflict_redirect_T43990_$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory();
|
2023-07-16 23:53:31 +00:00
|
|
|
$page = $this->getExistingTestPage( $title );
|
|
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$rtitle = Title::makeTitle( NS_HELP, "ApiEditPageTest_testEditConflict_redirect_T43990_r$count" );
|
2022-09-01 21:18:41 +00:00
|
|
|
$rpage = $wikiPageFactory->newFromTitle( $rtitle );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
// base edit for redirect
|
2021-06-24 08:42:19 +00:00
|
|
|
$rpage->doUserEditContent(
|
2023-07-28 21:47:54 +00:00
|
|
|
new WikitextContent( "#REDIRECT [[{$title->getPrefixedText()}]]" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101000000' );
|
|
|
|
|
|
|
|
|
|
// new edit to content
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo bar" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2012-11-12 15:39:29 +00:00
|
|
|
$this->forceRevisionDate( $rpage, '20120101020202' );
|
|
|
|
|
|
|
|
|
|
// try to save edit; should work, following the redirect.
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $re, , ] = $this->doApiRequestWithToken( [
|
2012-11-12 15:39:29 +00:00
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $rtitle->getPrefixedText(),
|
2012-11-12 15:39:29 +00:00
|
|
|
'text' => 'nix bar!',
|
2014-05-18 07:04:36 +00:00
|
|
|
'section' => 'new',
|
2012-11-12 15:39:29 +00:00
|
|
|
'redirect' => true,
|
2018-03-28 12:32:19 +00:00
|
|
|
] );
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $re['edit']['result'],
|
2012-11-12 15:39:29 +00:00
|
|
|
"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 ) {
|
2023-07-14 12:37:00 +00:00
|
|
|
$dbw = $this->getDb();
|
2012-11-12 15:39:29 +00:00
|
|
|
|
2023-07-14 12:37:00 +00:00
|
|
|
$dbw->newUpdateQueryBuilder()
|
|
|
|
|
->update( 'revision' )
|
|
|
|
|
->set( [ 'rev_timestamp' => $dbw->timestamp( $timestamp ) ] )
|
|
|
|
|
->where( [ 'rev_id' => $page->getLatest() ] )
|
|
|
|
|
->caller( __METHOD__ )->execute();
|
2012-11-12 15:39:29 +00:00
|
|
|
|
|
|
|
|
$page->clear();
|
|
|
|
|
}
|
2015-04-15 08:26:22 +00:00
|
|
|
|
|
|
|
|
public function testCheckDirectApiEditingDisallowed_forNonTextContent() {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'no-direct-editing' );
|
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';
|
2021-10-20 02:08:02 +00:00
|
|
|
$data = 'some bla bla text';
|
2015-04-15 08:26:22 +00:00
|
|
|
|
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'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $apiResult['edit']['result'] );
|
2015-04-15 08:26:22 +00:00
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'new', $apiResult['edit'] );
|
|
|
|
|
$this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] );
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey( 'pageid', $apiResult['edit'] );
|
|
|
|
|
|
|
|
|
|
// validate resulting revision
|
2022-09-01 21:18:41 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( Title::newFromText( $name ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( "testing-nontext", $page->getContentModel() );
|
|
|
|
|
$this->assertSame( $data, $page->getContent()->serialize() );
|
2015-04-15 08:26:22 +00:00
|
|
|
}
|
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__;
|
2023-07-16 23:53:31 +00:00
|
|
|
$sysop = $this->getTestSysop()->getUser();
|
|
|
|
|
$otherUser = $this->getTestUser()->getUser();
|
2018-03-28 12:32:19 +00:00
|
|
|
|
2016-09-08 23:43:36 +00:00
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'some text',
|
|
|
|
|
], null, $sysop )[0];
|
|
|
|
|
|
|
|
|
|
// Check success
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $apiResult['edit']['result'] );
|
2016-09-08 23:43:36 +00:00
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
|
|
|
|
// Content model is wikitext
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'wikitext', $apiResult['edit']['contentmodel'] );
|
2016-09-08 23:43:36 +00:00
|
|
|
|
|
|
|
|
// Convert the page to JSON
|
|
|
|
|
$apiResult = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => '{}',
|
|
|
|
|
'contentmodel' => 'json',
|
2023-07-16 23:53:31 +00:00
|
|
|
], null, $otherUser )[0];
|
2016-09-08 23:43:36 +00:00
|
|
|
|
|
|
|
|
// Check success
|
|
|
|
|
$this->assertArrayHasKey( 'edit', $apiResult );
|
|
|
|
|
$this->assertArrayHasKey( 'result', $apiResult['edit'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $apiResult['edit']['result'] );
|
2016-09-08 23:43:36 +00:00
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'json', $apiResult['edit']['contentmodel'] );
|
2016-09-08 23:43:36 +00:00
|
|
|
|
|
|
|
|
$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'] );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Success', $apiResult['edit']['result'] );
|
2016-09-08 23:43:36 +00:00
|
|
|
$this->assertArrayHasKey( 'contentmodel', $apiResult['edit'] );
|
|
|
|
|
// Check that the contentmodel is back to wikitext now.
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'wikitext', $apiResult['edit']['contentmodel'] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The tests below are mostly not commented because they do exactly what
|
|
|
|
|
// you'd expect from the name.
|
|
|
|
|
|
|
|
|
|
public function testCorrectContentFormat() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestCorrectContentFormat' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'some text',
|
|
|
|
|
'contentmodel' => 'wikitext',
|
|
|
|
|
'contentformat' => 'text/x-wiki',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testUnsupportedContentFormat() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestUnsupportedContentFormat' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'badvalue' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'some text',
|
|
|
|
|
'contentformat' => 'nonexistent format',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMismatchedContentFormat() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMismatchedContentFormat' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'badformat' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'some text',
|
|
|
|
|
'contentmodel' => 'wikitext',
|
|
|
|
|
'contentformat' => 'text/plain',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testUndoToInvalidRev() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestUndoToInvalidRev' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$revId = $this->editPage( $title, 'Some text' )->getNewRevision()
|
2018-03-20 13:25:26 +00:00
|
|
|
->getId();
|
|
|
|
|
$revId++;
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'nosuchrevid' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tests what happens if the undo parameter is a valid revision, but
|
|
|
|
|
* the undoafter parameter doesn't refer to a revision that exists in the
|
|
|
|
|
* database.
|
|
|
|
|
*/
|
|
|
|
|
public function testUndoAfterToInvalidRev() {
|
|
|
|
|
// We can't just pick a large number for undoafter (as in
|
|
|
|
|
// testUndoToInvalidRev above), because then MediaWiki will helpfully
|
|
|
|
|
// assume we switched around undo and undoafter and we'll test the code
|
|
|
|
|
// path for undo being invalid, not undoafter. So instead we delete
|
|
|
|
|
// the revision from the database. In real life this case could come
|
|
|
|
|
// up if a revision number was skipped, e.g., if two transactions try
|
|
|
|
|
// to insert new revision rows at once and the first one to succeed
|
|
|
|
|
// gets rolled back.
|
2023-06-23 18:12:09 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()
|
|
|
|
|
->newFromLinkTarget( new TitleValue( NS_HELP, 'TestUndoAfterToInvalidRev' ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId1 = $this->editPage( $page, '1' )->getNewRevision()->getId();
|
|
|
|
|
$revId2 = $this->editPage( $page, '2' )->getNewRevision()->getId();
|
|
|
|
|
$revId3 = $this->editPage( $page, '3' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
// Make the middle revision disappear
|
2023-07-14 12:37:00 +00:00
|
|
|
$dbw = $this->getDb();
|
2023-07-14 12:48:42 +00:00
|
|
|
$dbw->newDeleteQueryBuilder()
|
In query builders, use insertInto() and deleteFrom() instead of insert() and delete()
The design principle for SelectQueryBuilder was to make the chained
builder calls look as much like SQL as possible, so that developers
could leverage their knowledge of SQL to understand what the query
builder is doing.
That's why SelectQueryBuilder::select() takes a list of fields, and by
the same principle, it makes sense for UpdateQueryBuilder::update() to
take a table. However with "insert" and "delete", the SQL designers
chose to add prepositions "into" and "from", and I think it makes sense
to follow that here.
In terms of natural language, we update a table, but we don't delete a
table, or insert a table. We delete rows from a table, or insert rows
into a table. The table is not the object of the verb.
So, add insertInto() as an alias for insert(), and add deleteFrom() as
an alias for delete(). Use the new methods in MW core callers where
PHPStorm knows the type.
Change-Id: Idb327a54a57a0fb2288ea067472c1e9727016000
2023-09-08 00:06:59 +00:00
|
|
|
->deleteFrom( 'revision' )
|
2023-07-14 12:48:42 +00:00
|
|
|
->where( [ 'rev_id' => $revId2 ] )
|
|
|
|
|
->caller( __METHOD__ )->execute();
|
2023-07-14 12:37:00 +00:00
|
|
|
$dbw->newUpdateQueryBuilder()
|
|
|
|
|
->update( 'revision' )
|
|
|
|
|
->set( [ 'rev_parent_id' => $revId1 ] )
|
|
|
|
|
->where( [ 'rev_id' => $revId3 ] )
|
|
|
|
|
->caller( __METHOD__ )->execute();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'nosuchrevid' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-06-23 18:12:09 +00:00
|
|
|
'title' => $page->getTitle()->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId3,
|
|
|
|
|
'undoafter' => $revId2,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tests what happens if the undo parameter is a valid revision, but
|
|
|
|
|
* undoafter is hidden (rev_deleted).
|
|
|
|
|
*/
|
|
|
|
|
public function testUndoAfterToHiddenRev() {
|
2023-06-23 18:12:09 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()
|
|
|
|
|
->newFromLinkTarget( new TitleValue( NS_HELP, 'TestUndoAfterToHiddenRev' ) );
|
|
|
|
|
$titleObj = $page->getTitle();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$this->editPage( $page, '0' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId1 = $this->editPage( $page, '1' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId2 = $this->editPage( $page, '2' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
// Hide the middle revision
|
|
|
|
|
$list = RevisionDeleter::createList( 'revision',
|
|
|
|
|
RequestContext::getMain(), $titleObj, [ $revId1 ] );
|
|
|
|
|
$list->setVisibility( [
|
2020-07-03 00:20:38 +00:00
|
|
|
'value' => [ RevisionRecord::DELETED_TEXT => 1 ],
|
2018-03-20 13:25:26 +00:00
|
|
|
'comment' => 'Bye-bye',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'nosuchrevid' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-06-23 18:12:09 +00:00
|
|
|
'title' => $titleObj->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId2,
|
|
|
|
|
'undoafter' => $revId1,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test undo when a revision with a higher id has an earlier timestamp.
|
|
|
|
|
* This can happen if importing an old revision.
|
|
|
|
|
*/
|
|
|
|
|
public function testUndoWithSwappedRevisions() {
|
2020-10-30 20:53:11 +00:00
|
|
|
$this->markTestSkippedIfNoDiff3();
|
|
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()
|
|
|
|
|
->newFromLinkTarget( new TitleValue( NS_HELP, 'TestUndoWithSwappedRevisions' ) );
|
|
|
|
|
$this->editPage( $page, '0' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId2 = $this->editPage( $page, '2' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId1 = $this->editPage( $page, '1' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
// Now monkey with the timestamp
|
2023-07-14 12:37:00 +00:00
|
|
|
$dbw = $this->getDb();
|
|
|
|
|
$dbw->newUpdateQueryBuilder()
|
|
|
|
|
->update( 'revision' )
|
|
|
|
|
->set( [ 'rev_timestamp' => $dbw->timestamp( time() - 86400 ) ] )
|
|
|
|
|
->where( [ 'rev_id' => $revId1 ] )
|
|
|
|
|
->caller( __METHOD__ )->execute();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-06-23 18:12:09 +00:00
|
|
|
'title' => $page->getTitle()->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId2,
|
|
|
|
|
'undoafter' => $revId1,
|
|
|
|
|
] );
|
|
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page->loadPageData( WikiPage::READ_LATEST );
|
|
|
|
|
$this->assertSame( '1', $page->getContent()->getText() );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testUndoWithConflicts() {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'undofailure' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()
|
|
|
|
|
->newFromLinkTarget( new TitleValue( NS_HELP, 'TestUndoWithConflicts' ) );
|
|
|
|
|
$this->editPage( $page, '1' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$revId = $this->editPage( $page, '2' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$this->editPage( $page, '3' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-06-23 18:12:09 +00:00
|
|
|
'title' => $page->getTitle()->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId,
|
|
|
|
|
] );
|
|
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page->loadPageData( WikiPage::READ_LATEST );
|
|
|
|
|
$this->assertSame( '3', $page->getContent()->getText() );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testReversedUndoAfter() {
|
2020-10-30 20:53:11 +00:00
|
|
|
$this->markTestSkippedIfNoDiff3();
|
|
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()
|
|
|
|
|
->newFromLinkTarget( new TitleValue( NS_HELP, 'TestReversedUndoAfter' ) );
|
|
|
|
|
$this->editPage( $page, '0' );
|
|
|
|
|
$revId1 = $this->editPage( $page, '1' )->getNewRevision()->getId();
|
|
|
|
|
$revId2 = $this->editPage( $page, '2' )->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-06-23 18:12:09 +00:00
|
|
|
'title' => $page->getTitle()->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId1,
|
|
|
|
|
'undoafter' => $revId2,
|
|
|
|
|
] );
|
|
|
|
|
|
2023-06-23 18:12:09 +00:00
|
|
|
$page->loadPageData( WikiPage::READ_LATEST );
|
|
|
|
|
$this->assertSame( '2', $page->getContent()->getText() );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testUndoToRevFromDifferentPage() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title1 = Title::makeTitle( NS_HELP, 'TestUndoToRevFromDifferentPage-1' );
|
|
|
|
|
$this->editPage( $title1, 'Some text' );
|
|
|
|
|
$revId = $this->editPage( $title1, 'Some more text' )
|
2022-11-14 20:17:19 +00:00
|
|
|
->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$title2 = Title::makeTitle( NS_HELP, 'TestUndoToRevFromDifferentPage-2' );
|
|
|
|
|
$this->editPage( $title2, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'revwrongpage' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title2->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testUndoAfterToRevFromDifferentPage() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title1 = Title::makeTitle( NS_HELP, 'TestUndoAfterToRevFromDifferentPage-1' );
|
|
|
|
|
$revId1 = $this->editPage( $title1, 'Some text' )
|
2022-11-14 20:17:19 +00:00
|
|
|
->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$title2 = Title::makeTitle( NS_HELP, 'TestUndoAfterToRevFromDifferentPage-2' );
|
|
|
|
|
$revId2 = $this->editPage( $title2, 'Some text' )
|
2022-11-14 20:17:19 +00:00
|
|
|
->getNewRevision()->getId();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'revwrongpage' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title2->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'undo' => $revId2,
|
|
|
|
|
'undoafter' => $revId1,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMd5Text() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMd5Text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
'md5' => md5( 'Some text' ),
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMd5PrependText() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMd5PrependText' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'prependtext' => 'Alert: ',
|
|
|
|
|
'md5' => md5( 'Alert: ' ),
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Alert: Some text', $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMd5AppendText() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMd5AppendText' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => ' is nice',
|
|
|
|
|
'md5' => md5( ' is nice' ),
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Some text is nice', $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMd5PrependAndAppendText() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMd5PrependAndAppendText' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'prependtext' => 'Alert: ',
|
|
|
|
|
'appendtext' => ' is nice',
|
|
|
|
|
'md5' => md5( 'Alert: is nice' ),
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( 'Alert: Some text is nice', $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testIncorrectMd5Text() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'badmd5' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
|
|
|
|
'md5' => md5( '' ),
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testIncorrectMd5PrependText() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'badmd5' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'prependtext' => 'Some ',
|
|
|
|
|
'appendtext' => 'text',
|
|
|
|
|
'md5' => md5( 'Some ' ),
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testIncorrectMd5AppendText() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'badmd5' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'prependtext' => 'Some ',
|
|
|
|
|
'appendtext' => 'text',
|
|
|
|
|
'md5' => md5( 'text' ),
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCreateOnly() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestCreateOnly' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'articleexists' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
|
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some more text',
|
|
|
|
|
'createonly' => '',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
|
|
|
|
// Validate that content was not changed
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( 'Some text', $text );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testNoCreate() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestNoCreate' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'missingtitle' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
'nocreate' => '',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Appending/prepending is currently only supported for TextContent. We
|
|
|
|
|
* test this right now, and when support is added this test should be
|
|
|
|
|
* replaced by tests that the support is correct.
|
|
|
|
|
*/
|
|
|
|
|
public function testAppendWithNonTextContentHandler() {
|
|
|
|
|
$name = 'MediaWiki:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'appendnotsupported' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'ContentHandlerDefaultModelFor',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function ( Title $title, &$model ) use ( $name ) {
|
2018-03-20 13:25:26 +00:00
|
|
|
if ( $title->getPrefixedText() === $name ) {
|
|
|
|
|
$model = 'testing-nontext';
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'appendtext' => 'Some text',
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendInMediaWikiNamespace() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_MEDIAWIKI, 'TestAppendInMediaWikiNamespace' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => 'Some text',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendInMediaWikiNamespaceWithSerializationError() {
|
|
|
|
|
$name = 'MediaWiki:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'parseerror' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'ContentHandlerDefaultModelFor',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function ( Title $title, &$model ) use ( $name ) {
|
2018-03-20 13:25:26 +00:00
|
|
|
if ( $title->getPrefixedText() === $name ) {
|
|
|
|
|
$model = 'testing-serialize-error';
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'appendtext' => 'Some text',
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendNewSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendNewSection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Initial content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => '== New section ==',
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "Initial content\n\n== New section ==", $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendNewSectionWithInvalidContentModel() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendNewSectionWithInvalidContentModel' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'sectionsnotsupported' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Initial content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => '== New section ==',
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'contentmodel' => 'text',
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendNewSectionWithTitle() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendNewSectionWithTitle' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Initial content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'sectiontitle' => 'My section',
|
|
|
|
|
'appendtext' => 'More content',
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "Initial content\n\n== My section ==\n\nMore content",
|
2019-02-07 00:14:23 +00:00
|
|
|
$page->getContent()->getText() );
|
2020-04-18 02:39:58 +00:00
|
|
|
$comment = $page->getRevisionRecord()->getComment();
|
|
|
|
|
$this->assertInstanceOf( CommentStoreComment::class, $comment );
|
|
|
|
|
$this->assertSame( '/* My section */ new section', $comment->text );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendNewSectionWithSummary() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendNewSectionWithSummary' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Initial content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => 'More content',
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'summary' => 'Add new section',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "Initial content\n\n== Add new section ==\n\nMore content",
|
2019-02-07 00:14:23 +00:00
|
|
|
$page->getContent()->getText() );
|
2018-03-20 13:25:26 +00:00
|
|
|
// EditPage actually assumes the summary is the section name here
|
2020-04-18 02:39:58 +00:00
|
|
|
$comment = $page->getRevisionRecord()->getComment();
|
|
|
|
|
$this->assertInstanceOf( CommentStoreComment::class, $comment );
|
|
|
|
|
$this->assertSame( '/* Add new section */ new section', $comment->text );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendNewSectionWithTitleAndSummary() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendNewSectionWithTitleAndSummary' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Initial content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'sectiontitle' => 'My section',
|
|
|
|
|
'appendtext' => 'More content',
|
|
|
|
|
'section' => 'new',
|
|
|
|
|
'summary' => 'Add new section',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "Initial content\n\n== My section ==\n\nMore content",
|
2019-02-07 00:14:23 +00:00
|
|
|
$page->getContent()->getText() );
|
2020-04-18 02:39:58 +00:00
|
|
|
$comment = $page->getRevisionRecord()->getComment();
|
|
|
|
|
$this->assertInstanceOf( CommentStoreComment::class, $comment );
|
|
|
|
|
$this->assertSame( 'Add new section', $comment->text );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendToSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendToSection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, "== Section 1 ==\n\nContent\n\n" .
|
2018-03-20 13:25:26 +00:00
|
|
|
"== Section 2 ==\n\nFascinating!" );
|
|
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => ' and more content',
|
|
|
|
|
'section' => '1',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "== Section 1 ==\n\nContent and more content\n\n" .
|
|
|
|
|
"== Section 2 ==\n\nFascinating!", $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendToFirstSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendToFirstSection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, "Content\n\n== Section 1 ==\n\nFascinating!" );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => ' and more content',
|
|
|
|
|
'section' => '0',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( "Content and more content\n\n== Section 1 ==\n\n" .
|
|
|
|
|
"Fascinating!", $text );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testAppendToNonexistentSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestAppendToNonexistentSection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'nosuchsection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'appendtext' => ' and more content',
|
|
|
|
|
'section' => '1',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( 'Content', $text );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditMalformedSection() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditMalformedSection' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'invalidsection' );
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Content' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Different content',
|
|
|
|
|
'section' => 'It is unlikely that this is valid',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$text = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )
|
2019-02-07 00:14:23 +00:00
|
|
|
->getContent()->getText();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertSame( 'Content', $text );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditWithStartTimestamp() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditWithStartTimestamp' );
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'pagedeleted' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$startTime = MWTimestamp::convert( TS_MW, time() - 1 );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$pageObj = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2021-10-30 15:45:49 +00:00
|
|
|
$this->deletePage( $pageObj );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertFalse( $pageObj->exists() );
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Different text',
|
|
|
|
|
'starttimestamp' => $startTime,
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
|
|
|
|
$this->assertFalse( $pageObj->exists() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditMinor() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditMinor' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Different text',
|
|
|
|
|
'minor' => '',
|
|
|
|
|
] );
|
|
|
|
|
|
2022-01-12 20:13:39 +00:00
|
|
|
$revisionStore = $this->getServiceContainer()->getRevisionStore();
|
2023-07-28 21:47:54 +00:00
|
|
|
$revision = $revisionStore->getRevisionByTitle( $title );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertTrue( $revision->isMinor() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditRecreate() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditRecreate' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$startTime = MWTimestamp::convert( TS_MW, time() - 1 );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->editPage( $title, 'Some text' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$pageObj = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2021-10-30 15:45:49 +00:00
|
|
|
$this->deletePage( $pageObj );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->assertFalse( $pageObj->exists() );
|
|
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Different text',
|
|
|
|
|
'starttimestamp' => $startTime,
|
|
|
|
|
'recreate' => '',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditWatch() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditWatch' );
|
2023-07-16 23:53:31 +00:00
|
|
|
$user = $this->getTestSysop()->getUser();
|
2021-04-13 03:28:23 +00:00
|
|
|
$watchlistManager = $this->getServiceContainer()->getWatchlistManager();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
'watch' => '',
|
2020-06-04 20:16:23 +00:00
|
|
|
'watchlistexpiry' => '99990123000000',
|
2018-03-20 13:25:26 +00:00
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
2021-04-13 03:28:23 +00:00
|
|
|
$this->assertTrue( $watchlistManager->isWatched( $user, $title ) );
|
|
|
|
|
$this->assertTrue( $watchlistManager->isTempWatched( $user, $title ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditUnwatch() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditUnwatch' );
|
2023-07-16 23:53:31 +00:00
|
|
|
$user = $this->getTestSysop()->getUser();
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2021-04-13 03:28:23 +00:00
|
|
|
$watchlistManager = $this->getServiceContainer()->getWatchlistManager();
|
2023-07-28 21:47:54 +00:00
|
|
|
$watchlistManager->addWatch( $user, $title );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists() );
|
|
|
|
|
$this->assertTrue( $watchlistManager->isWatched( $user, $title ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
'unwatch' => '',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertTrue( $title->exists( Title::READ_LATEST ) );
|
|
|
|
|
$this->assertFalse( $watchlistManager->isWatched( $user, $title ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditWithTag() {
|
2018-09-04 19:50:46 +00:00
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-07-29 09:44:29 +00:00
|
|
|
$this->getServiceContainer()->getChangeTagsStore()->defineTag( 'custom tag' );
|
2018-09-04 19:50:46 +00:00
|
|
|
|
|
|
|
|
$revId = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
|
|
|
|
'tags' => 'custom tag',
|
|
|
|
|
] )[0]['edit']['newrevid'];
|
|
|
|
|
|
2023-09-21 16:37:37 +00:00
|
|
|
$this->assertSame( 'custom tag', $this->getDb()->newSelectQueryBuilder()
|
|
|
|
|
->select( 'ctd_name' )
|
|
|
|
|
->from( 'change_tag' )
|
|
|
|
|
->join( 'change_tag_def', null, 'ctd_id = ct_tag_id' )
|
|
|
|
|
->where( [ 'ct_rev_id' => $revId ] )
|
|
|
|
|
->caller( __METHOD__ )->fetchField() );
|
2018-09-04 19:50:46 +00:00
|
|
|
}
|
|
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
public function testEditWithoutTagPermission() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditWithoutTagPermission' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'tags-apply-no-permission' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-29 09:44:29 +00:00
|
|
|
$this->getServiceContainer()->getChangeTagsStore()->defineTag( 'custom tag' );
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValue(
|
|
|
|
|
MainConfigNames::RevokePermissions,
|
|
|
|
|
[ 'user' => [ 'applychangetags' => true ] ]
|
|
|
|
|
);
|
2019-04-09 06:58:04 +00:00
|
|
|
|
2018-03-20 13:25:26 +00:00
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
'tags' => 'custom tag',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditAbortedByEditPageHookWithResult() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditAbortedByEditPageHookWithResult' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'EditFilterMergedContent',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function ( $unused1, $unused2, Status $status ) {
|
2018-03-20 13:25:26 +00:00
|
|
|
$status->apiHookResult = [ 'msg' => 'A message for you!' ];
|
|
|
|
|
return false;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
$res = $this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
] );
|
|
|
|
|
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
$this->assertSame( [ 'edit' => [ 'msg' => 'A message for you!',
|
|
|
|
|
'result' => 'Failure' ] ], $res[0] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditAbortedByEditPageHookWithNoResult() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestEditAbortedByEditPageHookWithNoResult' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'hookaborted' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'EditFilterMergedContent',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function () {
|
2018-03-20 13:25:26 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2018-03-20 13:25:26 +00:00
|
|
|
'text' => 'Some text',
|
|
|
|
|
] );
|
|
|
|
|
} finally {
|
2023-07-28 21:47:54 +00:00
|
|
|
$this->assertFalse( $title->exists( Title::READ_LATEST ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditWhileBlocked() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2021-11-21 19:13:24 +00:00
|
|
|
$this->assertNull( DatabaseBlock::newFromTarget( '127.0.0.1' ) );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2023-07-16 23:53:31 +00:00
|
|
|
$user = $this->getTestSysop()->getUser();
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = new DatabaseBlock( [
|
2023-07-16 23:53:31 +00:00
|
|
|
'address' => $user->getName(),
|
|
|
|
|
'by' => $user,
|
2018-03-20 13:25:26 +00:00
|
|
|
'reason' => 'Capriciousness',
|
|
|
|
|
'timestamp' => '19370101000000',
|
|
|
|
|
'expiry' => 'infinity',
|
2019-02-18 19:46:05 +00:00
|
|
|
'enableAutoblock' => true,
|
2018-03-20 13:25:26 +00:00
|
|
|
] );
|
2022-01-12 20:13:39 +00:00
|
|
|
$blockStore = $this->getServiceContainer()->getDatabaseBlockStore();
|
2020-08-27 09:27:10 +00:00
|
|
|
$blockStore->insertBlock( $block );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
|
|
|
|
] );
|
2019-02-18 19:46:05 +00:00
|
|
|
$this->fail( 'Expected exception not thrown' );
|
|
|
|
|
} catch ( ApiUsageException $ex ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'blocked', $ex );
|
2019-05-13 14:18:07 +00:00
|
|
|
$this->assertNotNull( DatabaseBlock::newFromTarget( '127.0.0.1' ), 'Autoblock spread' );
|
2018-03-20 13:25:26 +00:00
|
|
|
} finally {
|
2020-08-27 09:27:10 +00:00
|
|
|
$blockStore->deleteBlock( $block );
|
2023-07-16 23:53:31 +00:00
|
|
|
$user->clearInstanceCache();
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testEditWhileReadOnly() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-07-16 22:14:38 +00:00
|
|
|
// Create the test user before making the DB readonly
|
|
|
|
|
$user = $this->getTestSysop()->getUser();
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'readonly' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2022-01-12 20:13:39 +00:00
|
|
|
$svc = $this->getServiceContainer()->getReadOnlyMode();
|
2018-03-20 13:25:26 +00:00
|
|
|
$svc->setReason( "Read-only for testing" );
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
2023-07-16 22:14:38 +00:00
|
|
|
], null, $user );
|
2018-03-20 13:25:26 +00:00
|
|
|
} finally {
|
|
|
|
|
$svc->setReason( false );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCreateImageRedirectAnon() {
|
|
|
|
|
$name = 'File:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'noimageredirect-anon' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => '#REDIRECT [[File:Other file.png]]',
|
2018-03-28 12:32:19 +00:00
|
|
|
], null, new User() );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCreateImageRedirectLoggedIn() {
|
|
|
|
|
$name = 'File:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'noimageredirect' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValue(
|
|
|
|
|
MainConfigNames::RevokePermissions,
|
|
|
|
|
[ 'user' => [ 'upload' => true ] ]
|
|
|
|
|
);
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => '#REDIRECT [[File:Other file.png]]',
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testTooBigEdit() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'contenttoobig' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::MaxArticleSize, 1 );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$text = str_repeat( '!', 1025 );
|
|
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => $text,
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testProhibitedAnonymousEdit() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'permissiondenied' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValue(
|
|
|
|
|
MainConfigNames::RevokePermissions,
|
|
|
|
|
[ '*' => [ 'edit' => true ] ]
|
|
|
|
|
);
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
2018-03-28 12:32:19 +00:00
|
|
|
], null, new User() );
|
2018-03-20 13:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testProhibitedChangeContentModel() {
|
|
|
|
|
$name = 'Help:' . ucfirst( __FUNCTION__ );
|
|
|
|
|
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->expectApiErrorCode( 'cantchangecontentmodel' );
|
2018-03-20 13:25:26 +00:00
|
|
|
|
2022-07-06 15:05:30 +00:00
|
|
|
$this->overrideConfigValue(
|
|
|
|
|
MainConfigNames::RevokePermissions,
|
|
|
|
|
[ 'user' => [ 'editcontentmodel' => true ] ]
|
|
|
|
|
);
|
2018-03-20 13:25:26 +00:00
|
|
|
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
|
|
|
|
'title' => $name,
|
|
|
|
|
'text' => 'Some text',
|
|
|
|
|
'contentmodel' => 'json',
|
|
|
|
|
] );
|
2016-09-08 23:43:36 +00:00
|
|
|
}
|
2020-06-20 15:21:46 +00:00
|
|
|
|
|
|
|
|
public function testMidEditContentModelMismatch() {
|
2023-07-28 21:47:54 +00:00
|
|
|
$title = Title::makeTitle( NS_HELP, 'TestMidEditContentModelMismatch' );
|
2020-06-20 15:21:46 +00:00
|
|
|
|
2022-09-01 21:18:41 +00:00
|
|
|
$page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2020-06-20 15:21:46 +00:00
|
|
|
|
|
|
|
|
// base edit, currently in Wikitext
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new WikitextContent( "Foo" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 1",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_NEW
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2020-06-20 15:21:46 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101000000' );
|
|
|
|
|
$baseId = $page->getRevisionRecord()->getId();
|
|
|
|
|
|
|
|
|
|
// Attempt edit in Javascript. This may happen, for instance, if we
|
|
|
|
|
// started editing the base content while it was in Javascript and
|
|
|
|
|
// before we save it was changed to Wikitext (base edit model).
|
2021-06-24 08:42:19 +00:00
|
|
|
$page->doUserEditContent(
|
|
|
|
|
new JavaScriptContent( "Bar" ),
|
2023-07-16 23:53:31 +00:00
|
|
|
$this->getTestUser()->getUser(),
|
2021-06-24 08:42:19 +00:00
|
|
|
"testing 2",
|
2018-07-05 14:59:55 +00:00
|
|
|
EDIT_UPDATE
|
2021-06-24 08:42:19 +00:00
|
|
|
);
|
2020-06-20 15:21:46 +00:00
|
|
|
$this->forceRevisionDate( $page, '20120101020202' );
|
|
|
|
|
|
2018-07-05 14:59:55 +00:00
|
|
|
// ContentHandler may throw exception if we attempt saving the above, so we will
|
2020-06-20 15:21:46 +00:00
|
|
|
// handle that with contentmodel-mismatch error. Test this is the case.
|
|
|
|
|
try {
|
|
|
|
|
$this->doApiRequestWithToken( [
|
|
|
|
|
'action' => 'edit',
|
2023-07-28 21:47:54 +00:00
|
|
|
'title' => $title->getPrefixedText(),
|
2020-06-20 15:21:46 +00:00
|
|
|
'text' => 'different content models!',
|
|
|
|
|
'baserevid' => $baseId,
|
|
|
|
|
] );
|
|
|
|
|
$this->fail( "Should have raised an ApiUsageException" );
|
|
|
|
|
} catch ( ApiUsageException $e ) {
|
2023-04-26 09:16:20 +00:00
|
|
|
$this->assertApiErrorCode( 'contentmodel-mismatch', $e );
|
2020-06-20 15:21:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-06-25 14:09:08 +00:00
|
|
|
}
|