2020-01-11 23:49:41 +00:00
|
|
|
<?php
|
|
|
|
|
|
2024-08-07 21:37:34 +00:00
|
|
|
use MediaWiki\Content\ContentModelChange;
|
2024-02-08 14:56:54 +00:00
|
|
|
use MediaWiki\Context\RequestContext;
|
2021-03-02 21:29:46 +00:00
|
|
|
use MediaWiki\Page\PageIdentity;
|
2022-04-10 14:37:23 +00:00
|
|
|
use MediaWiki\Page\WikiPageFactory;
|
2021-03-02 21:29:46 +00:00
|
|
|
use MediaWiki\Permissions\Authority;
|
|
|
|
|
use MediaWiki\Permissions\PermissionStatus;
|
2022-06-28 21:28:54 +00:00
|
|
|
use MediaWiki\Permissions\RateLimiter;
|
2023-08-25 12:29:41 +00:00
|
|
|
use MediaWiki\Status\Status;
|
2021-03-02 21:29:46 +00:00
|
|
|
use MediaWiki\Tests\Unit\MockServiceDependenciesTrait;
|
|
|
|
|
use MediaWiki\Tests\Unit\Permissions\MockAuthorityTrait;
|
2023-03-01 20:33:26 +00:00
|
|
|
use MediaWiki\Title\Title;
|
2020-01-11 23:49:41 +00:00
|
|
|
|
|
|
|
|
/**
|
2020-05-30 19:10:58 +00:00
|
|
|
* TODO convert to a pure unit test
|
|
|
|
|
*
|
2020-01-11 23:49:41 +00:00
|
|
|
* @group Database
|
2024-08-07 21:37:34 +00:00
|
|
|
* @covers \MediaWiki\Content\ContentModelChange
|
2020-05-30 19:10:58 +00:00
|
|
|
*
|
2020-04-11 08:10:18 +00:00
|
|
|
* @author DannyS712
|
2021-03-02 21:29:46 +00:00
|
|
|
* @method ContentModelChange newServiceInstance(string $serviceClass, array $parameterOverrides)
|
2020-01-11 23:49:41 +00:00
|
|
|
*/
|
2020-06-30 15:09:24 +00:00
|
|
|
class ContentModelChangeTest extends MediaWikiIntegrationTestCase {
|
2021-03-02 21:29:46 +00:00
|
|
|
use MockAuthorityTrait;
|
|
|
|
|
use MockServiceDependenciesTrait;
|
2020-01-11 23:49:41 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
protected function setUp(): void {
|
2020-01-11 23:49:41 +00:00
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
|
|
$this->getExistingTestPage( 'ExistingPage' );
|
|
|
|
|
$this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
|
|
|
|
|
'testing' => 'DummyContentHandlerForTesting',
|
|
|
|
|
] );
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
private function newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
Authority $performer,
|
2020-05-30 19:10:58 +00:00
|
|
|
WikiPage $page,
|
|
|
|
|
string $newModel
|
|
|
|
|
) {
|
2021-03-02 21:29:46 +00:00
|
|
|
return $this->getServiceContainer()
|
2020-05-30 19:10:58 +00:00
|
|
|
->getContentModelChangeFactory()
|
2021-03-02 21:29:46 +00:00
|
|
|
->newContentModelChange( $performer, $page, $newModel );
|
2020-05-30 19:10:58 +00:00
|
|
|
}
|
|
|
|
|
|
2020-01-11 23:49:41 +00:00
|
|
|
/**
|
|
|
|
|
* Test that the content model needs to change
|
|
|
|
|
*/
|
|
|
|
|
public function testChangeNeeded() {
|
|
|
|
|
$wikipage = $this->getExistingTestPage( 'ExistingPage' );
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'wikitext',
|
|
|
|
|
$wikipage->getTitle()->getContentModel(),
|
2021-11-21 19:13:24 +00:00
|
|
|
'`ExistingPage` should be wikitext'
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithPermissions( [ 'editcontentmodel' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$wikipage,
|
|
|
|
|
'wikitext'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->doContentModelChange(
|
|
|
|
|
RequestContext::getMain(),
|
|
|
|
|
__METHOD__ . ' comment',
|
|
|
|
|
false
|
|
|
|
|
);
|
content: Remove unclear assertEquals() on Status objects
We don't usually compare object serializations with assertEquals as
they tend to make it difficult to know what is and isn't being asserted,
giving the illusion that it checks "everything" but can in some cases
be closer to "too much" or "nothing".
Actual logic:
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Assert.php#L330
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Constraint/Equality/IsEqual.php
* https://github.com/sebastianbergmann/comparator/blob/5.0.1/src/ObjectComparator.php
* https://github.com/sebastianbergmann/exporter/blob/5.1.2/src/Exporter.php
This means sub classes or value objects are needlessly discarded,
as well as potentially irrelevant state in the object is becoming
part of the test.
It is not a surprise then, that these assertions are not comparing
against any particular desired outcome, but are literally a copy-paste
of the source code, including functions that have no effect in testing
such as `ContentHandler::getLocalizedName( 'testing' )` === 'testing',
and untested expressions like `$wikipage->getTitle()->getPrefixedText()`
instead of an explicit expectation.
Replace this with assertStatusError and limit the assertion to
being !isOK, and error using the specified interface message key.
Testing that the correct parameters are passed is imho not a part
of this test, since the test isn't actually validating it to be
correct or sensible in terms of message contents and parsed outcome,
it is only verifying that we have correctly copied the source, which
still needs the same review as it otherwise would.
Change-Id: I8c7a660489e9000f9790f8d69478a05ad8c446b6
2024-03-11 22:08:41 +00:00
|
|
|
$this->assertStatusError( 'apierror-nochanges', $status );
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test that the content needs to be valid for the requested model
|
|
|
|
|
*/
|
|
|
|
|
public function testInvalidContent() {
|
|
|
|
|
$invalidJSON = 'Foo\nBar\nEaster egg\nT22281';
|
|
|
|
|
$wikipage = $this->getExistingTestPage( 'PageWithTextThatIsNotValidJSON' );
|
2021-06-24 08:42:19 +00:00
|
|
|
$wikipage->doUserEditContent(
|
2020-01-11 23:49:41 +00:00
|
|
|
ContentHandler::makeContent( $invalidJSON, $wikipage->getTitle() ),
|
2021-06-24 08:42:19 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2020-01-11 23:49:41 +00:00
|
|
|
'EditSummaryForThisTest',
|
2021-06-24 08:42:19 +00:00
|
|
|
EDIT_UPDATE | EDIT_SUPPRESS_RC
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'wikitext',
|
|
|
|
|
$wikipage->getTitle()->getContentModel(),
|
2021-11-21 19:13:24 +00:00
|
|
|
'`PageWithTextThatIsNotValidJSON` should be wikitext at first'
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithPermissions( [ 'editcontentmodel' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$wikipage,
|
|
|
|
|
'json'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->doContentModelChange(
|
|
|
|
|
RequestContext::getMain(),
|
|
|
|
|
__METHOD__ . ' comment',
|
|
|
|
|
false
|
|
|
|
|
);
|
2022-08-14 15:49:20 +00:00
|
|
|
$this->assertStatusError( 'invalid-json-data', $status );
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test the EditFilterMergedContent hook can be intercepted
|
|
|
|
|
*
|
|
|
|
|
* @dataProvider provideTestEditFilterMergedContent
|
|
|
|
|
* @param string|bool $customMessage Hook message, or false
|
|
|
|
|
* @param string $expectedMessage expected fatal
|
|
|
|
|
*/
|
|
|
|
|
public function testEditFilterMergedContent( $customMessage, $expectedMessage ) {
|
|
|
|
|
$wikipage = $this->getExistingTestPage( 'ExistingPage' );
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'wikitext',
|
2024-01-25 14:58:57 +00:00
|
|
|
$wikipage->getTitle()->getContentModel( IDBAccessObject::READ_LATEST ),
|
2021-11-21 19:13:24 +00:00
|
|
|
'`ExistingPage` should be wikitext'
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'EditFilterMergedContent',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function ( $unused1, $unused2, Status $status ) use ( $customMessage ) {
|
2020-01-11 23:49:41 +00:00
|
|
|
if ( $customMessage !== false ) {
|
|
|
|
|
$status->fatal( $customMessage );
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithPermissions( [ 'editcontentmodel' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$wikipage,
|
|
|
|
|
'text'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->doContentModelChange(
|
|
|
|
|
RequestContext::getMain(),
|
|
|
|
|
__METHOD__ . ' comment',
|
|
|
|
|
false
|
|
|
|
|
);
|
content: Remove unclear assertEquals() on Status objects
We don't usually compare object serializations with assertEquals as
they tend to make it difficult to know what is and isn't being asserted,
giving the illusion that it checks "everything" but can in some cases
be closer to "too much" or "nothing".
Actual logic:
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Assert.php#L330
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Constraint/Equality/IsEqual.php
* https://github.com/sebastianbergmann/comparator/blob/5.0.1/src/ObjectComparator.php
* https://github.com/sebastianbergmann/exporter/blob/5.1.2/src/Exporter.php
This means sub classes or value objects are needlessly discarded,
as well as potentially irrelevant state in the object is becoming
part of the test.
It is not a surprise then, that these assertions are not comparing
against any particular desired outcome, but are literally a copy-paste
of the source code, including functions that have no effect in testing
such as `ContentHandler::getLocalizedName( 'testing' )` === 'testing',
and untested expressions like `$wikipage->getTitle()->getPrefixedText()`
instead of an explicit expectation.
Replace this with assertStatusError and limit the assertion to
being !isOK, and error using the specified interface message key.
Testing that the correct parameters are passed is imho not a part
of this test, since the test isn't actually validating it to be
correct or sensible in terms of message contents and parsed outcome,
it is only verifying that we have correctly copied the source, which
still needs the same review as it otherwise would.
Change-Id: I8c7a660489e9000f9790f8d69478a05ad8c446b6
2024-03-11 22:08:41 +00:00
|
|
|
$this->assertStatusError( $expectedMessage, $status );
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideTestEditFilterMergedContent() {
|
2020-01-11 23:49:41 +00:00
|
|
|
return [
|
|
|
|
|
[ 'DannyS712 objects to this change!', 'DannyS712 objects to this change!' ],
|
|
|
|
|
[ false, 'hookaborted' ]
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test the ContentModelCanBeUsedOn hook can be intercepted
|
|
|
|
|
*/
|
|
|
|
|
public function testContentModelCanBeUsedOn() {
|
|
|
|
|
$wikipage = $this->getExistingTestPage( 'ExistingPage' );
|
2021-06-24 08:42:19 +00:00
|
|
|
$wikipage->doUserEditContent(
|
2020-01-11 23:49:41 +00:00
|
|
|
ContentHandler::makeContent( 'Text', $wikipage->getTitle() ),
|
2021-06-24 08:42:19 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2020-01-11 23:49:41 +00:00
|
|
|
'Ensure a revision exists',
|
2021-06-24 08:42:19 +00:00
|
|
|
EDIT_UPDATE | EDIT_SUPPRESS_RC
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'wikitext',
|
2024-01-25 14:58:57 +00:00
|
|
|
$wikipage->getTitle()->getContentModel( IDBAccessObject::READ_LATEST ),
|
2021-11-21 19:13:24 +00:00
|
|
|
'`ExistingPage` should be wikitext'
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->setTemporaryHook( 'ContentModelCanBeUsedOn',
|
2021-02-07 13:10:36 +00:00
|
|
|
static function ( $unused1, $unused2, &$ok ) {
|
2020-01-11 23:49:41 +00:00
|
|
|
$ok = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithPermissions( [ 'editcontentmodel' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$wikipage,
|
|
|
|
|
'text'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->doContentModelChange(
|
|
|
|
|
RequestContext::getMain(),
|
|
|
|
|
__METHOD__ . ' comment',
|
|
|
|
|
false
|
|
|
|
|
);
|
content: Remove unclear assertEquals() on Status objects
We don't usually compare object serializations with assertEquals as
they tend to make it difficult to know what is and isn't being asserted,
giving the illusion that it checks "everything" but can in some cases
be closer to "too much" or "nothing".
Actual logic:
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Assert.php#L330
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Constraint/Equality/IsEqual.php
* https://github.com/sebastianbergmann/comparator/blob/5.0.1/src/ObjectComparator.php
* https://github.com/sebastianbergmann/exporter/blob/5.1.2/src/Exporter.php
This means sub classes or value objects are needlessly discarded,
as well as potentially irrelevant state in the object is becoming
part of the test.
It is not a surprise then, that these assertions are not comparing
against any particular desired outcome, but are literally a copy-paste
of the source code, including functions that have no effect in testing
such as `ContentHandler::getLocalizedName( 'testing' )` === 'testing',
and untested expressions like `$wikipage->getTitle()->getPrefixedText()`
instead of an explicit expectation.
Replace this with assertStatusError and limit the assertion to
being !isOK, and error using the specified interface message key.
Testing that the correct parameters are passed is imho not a part
of this test, since the test isn't actually validating it to be
correct or sensible in terms of message contents and parsed outcome,
it is only verifying that we have correctly copied the source, which
still needs the same review as it otherwise would.
Change-Id: I8c7a660489e9000f9790f8d69478a05ad8c446b6
2024-03-11 22:08:41 +00:00
|
|
|
$this->assertStatusError( 'apierror-changecontentmodel-cannotbeused', $status );
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test that content handler must support direct editing
|
|
|
|
|
*/
|
|
|
|
|
public function testNoDirectEditing() {
|
|
|
|
|
$title = Title::newFromText( 'Dummy:NoDirectEditing' );
|
2022-09-01 21:18:41 +00:00
|
|
|
$wikipage = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title );
|
2020-01-11 23:49:41 +00:00
|
|
|
|
2023-11-20 10:32:09 +00:00
|
|
|
$dummyContent = $this->getServiceContainer()
|
|
|
|
|
->getContentHandlerFactory()
|
|
|
|
|
->getContentHandler( 'testing' )
|
|
|
|
|
->makeEmptyContent();
|
|
|
|
|
|
2021-06-24 08:42:19 +00:00
|
|
|
$wikipage->doUserEditContent(
|
2020-01-11 23:49:41 +00:00
|
|
|
$dummyContent,
|
2021-06-24 08:42:19 +00:00
|
|
|
$this->getTestSysop()->getUser(),
|
2020-01-11 23:49:41 +00:00
|
|
|
'EditSummaryForThisTest',
|
2021-06-24 08:42:19 +00:00
|
|
|
EDIT_NEW | EDIT_SUPPRESS_RC
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'testing',
|
2024-01-25 14:58:57 +00:00
|
|
|
$title->getContentModel( IDBAccessObject::READ_LATEST ),
|
2020-01-11 23:49:41 +00:00
|
|
|
'Dummy:NoDirectEditing should start with the `testing` content model'
|
|
|
|
|
);
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithPermissions( [ 'editcontentmodel' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$wikipage,
|
|
|
|
|
'text'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->doContentModelChange(
|
|
|
|
|
RequestContext::getMain(),
|
|
|
|
|
__METHOD__ . ' comment',
|
|
|
|
|
false
|
|
|
|
|
);
|
content: Remove unclear assertEquals() on Status objects
We don't usually compare object serializations with assertEquals as
they tend to make it difficult to know what is and isn't being asserted,
giving the illusion that it checks "everything" but can in some cases
be closer to "too much" or "nothing".
Actual logic:
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Assert.php#L330
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Constraint/Equality/IsEqual.php
* https://github.com/sebastianbergmann/comparator/blob/5.0.1/src/ObjectComparator.php
* https://github.com/sebastianbergmann/exporter/blob/5.1.2/src/Exporter.php
This means sub classes or value objects are needlessly discarded,
as well as potentially irrelevant state in the object is becoming
part of the test.
It is not a surprise then, that these assertions are not comparing
against any particular desired outcome, but are literally a copy-paste
of the source code, including functions that have no effect in testing
such as `ContentHandler::getLocalizedName( 'testing' )` === 'testing',
and untested expressions like `$wikipage->getTitle()->getPrefixedText()`
instead of an explicit expectation.
Replace this with assertStatusError and limit the assertion to
being !isOK, and error using the specified interface message key.
Testing that the correct parameters are passed is imho not a part
of this test, since the test isn't actually validating it to be
correct or sensible in terms of message contents and parsed outcome,
it is only verifying that we have correctly copied the source, which
still needs the same review as it otherwise would.
Change-Id: I8c7a660489e9000f9790f8d69478a05ad8c446b6
2024-03-11 22:08:41 +00:00
|
|
|
$this->assertStatusError(
|
|
|
|
|
'apierror-changecontentmodel-nodirectediting',
|
2020-01-11 23:49:41 +00:00
|
|
|
$status
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCannotApplyTags() {
|
|
|
|
|
ChangeTags::defineTag( 'edit content model tag' );
|
|
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2021-03-02 21:29:46 +00:00
|
|
|
$this->mockRegisteredAuthorityWithoutPermissions( [ 'applychangetags' ] ),
|
2020-01-11 23:49:41 +00:00
|
|
|
$this->getExistingTestPage( 'ExistingPage' ),
|
|
|
|
|
'text'
|
|
|
|
|
);
|
|
|
|
|
$status = $change->setTags( [ 'edit content model tag' ] );
|
content: Remove unclear assertEquals() on Status objects
We don't usually compare object serializations with assertEquals as
they tend to make it difficult to know what is and isn't being asserted,
giving the illusion that it checks "everything" but can in some cases
be closer to "too much" or "nothing".
Actual logic:
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Assert.php#L330
* https://github.com/sebastianbergmann/phpunit/blob/9.6.17/src/Framework/Constraint/Equality/IsEqual.php
* https://github.com/sebastianbergmann/comparator/blob/5.0.1/src/ObjectComparator.php
* https://github.com/sebastianbergmann/exporter/blob/5.1.2/src/Exporter.php
This means sub classes or value objects are needlessly discarded,
as well as potentially irrelevant state in the object is becoming
part of the test.
It is not a surprise then, that these assertions are not comparing
against any particular desired outcome, but are literally a copy-paste
of the source code, including functions that have no effect in testing
such as `ContentHandler::getLocalizedName( 'testing' )` === 'testing',
and untested expressions like `$wikipage->getTitle()->getPrefixedText()`
instead of an explicit expectation.
Replace this with assertStatusError and limit the assertion to
being !isOK, and error using the specified interface message key.
Testing that the correct parameters are passed is imho not a part
of this test, since the test isn't actually validating it to be
correct or sensible in terms of message contents and parsed outcome,
it is only verifying that we have correctly copied the source, which
still needs the same review as it otherwise would.
Change-Id: I8c7a660489e9000f9790f8d69478a05ad8c446b6
2024-03-11 22:08:41 +00:00
|
|
|
$this->assertStatusError(
|
|
|
|
|
'tags-apply-no-permission',
|
2020-01-11 23:49:41 +00:00
|
|
|
$status
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCheckPermissions() {
|
|
|
|
|
$wikipage = $this->getExistingTestPage( 'ExistingPage' );
|
|
|
|
|
$title = $wikipage->getTitle();
|
2024-01-25 14:58:57 +00:00
|
|
|
$currentContentModel = $title->getContentModel( IDBAccessObject::READ_LATEST );
|
2021-03-02 21:29:46 +00:00
|
|
|
$newContentModel = 'text';
|
2020-01-11 23:49:41 +00:00
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'wikitext',
|
|
|
|
|
$currentContentModel,
|
2021-11-21 19:13:24 +00:00
|
|
|
'`ExistingPage` should be wikitext'
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
2021-04-29 16:24:12 +00:00
|
|
|
$performer = $this->mockRegisteredAuthority( static function (
|
2021-03-02 21:29:46 +00:00
|
|
|
string $permission,
|
|
|
|
|
PageIdentity $page,
|
|
|
|
|
PermissionStatus $status
|
|
|
|
|
) use ( $currentContentModel, $newContentModel ) {
|
2023-04-22 13:57:00 +00:00
|
|
|
$title = Title::newFromPageIdentity( $page );
|
2021-03-02 21:29:46 +00:00
|
|
|
if ( $permission === 'editcontentmodel' && $title->hasContentModel( $currentContentModel ) ) {
|
|
|
|
|
$status->fatal( 'no edit old content model' );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( $permission === 'editcontentmodel' && $title->hasContentModel( $newContentModel ) ) {
|
|
|
|
|
$status->fatal( 'no edit new content model' );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( $permission === 'edit' && $title->hasContentModel( $currentContentModel ) ) {
|
|
|
|
|
$status->fatal( 'no edit at all old content model' );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( $permission === 'edit' && $title->hasContentModel( $newContentModel ) ) {
|
|
|
|
|
$status->fatal( 'no edit at all new content model' );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
} );
|
2020-01-11 23:49:41 +00:00
|
|
|
|
2022-04-10 14:37:23 +00:00
|
|
|
$wpFactory = $this->createMock( WikiPageFactory::class );
|
|
|
|
|
$wpFactory->method( 'newFromTitle' )->willReturn( $wikipage );
|
2021-03-02 21:29:46 +00:00
|
|
|
$change = $this->newServiceInstance(
|
|
|
|
|
ContentModelChange::class,
|
2020-01-11 23:49:41 +00:00
|
|
|
[
|
2021-03-02 21:29:46 +00:00
|
|
|
'performer' => $performer,
|
|
|
|
|
'page' => $wikipage,
|
2022-04-10 14:37:23 +00:00
|
|
|
'newModel' => $newContentModel,
|
|
|
|
|
'wikiPageFactory' => $wpFactory,
|
2021-03-02 21:29:46 +00:00
|
|
|
]
|
2020-01-11 23:49:41 +00:00
|
|
|
);
|
2021-03-02 21:29:46 +00:00
|
|
|
|
|
|
|
|
foreach ( [ 'probablyCanChange', 'authorizeChange' ] as $method ) {
|
|
|
|
|
$status = $change->$method();
|
|
|
|
|
$this->assertArrayEquals(
|
|
|
|
|
[
|
|
|
|
|
[ 'no edit new content model' ],
|
|
|
|
|
[ 'no edit old content model' ],
|
|
|
|
|
[ 'no edit at all old content model' ],
|
|
|
|
|
[ 'no edit at all new content model' ],
|
|
|
|
|
],
|
|
|
|
|
$status->toLegacyErrorArray()
|
|
|
|
|
);
|
|
|
|
|
}
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCheckPermissionsThrottle() {
|
2022-06-28 21:28:54 +00:00
|
|
|
$user = $this->getTestUser()->getUser();
|
|
|
|
|
|
|
|
|
|
$limiter = $this->createNoOpMock( RateLimiter::class, [ 'limit', 'isLimitable' ] );
|
|
|
|
|
$limiter->method( 'isLimitable' )->willReturn( true );
|
|
|
|
|
$limiter->method( 'limit' )
|
|
|
|
|
->willReturnCallback( function ( $user, $action, $incr ) {
|
|
|
|
|
if ( $action === 'editcontentmodel' ) {
|
|
|
|
|
$this->assertSame( 1, $incr );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
$this->setService( 'RateLimiter', $limiter );
|
2020-01-11 23:49:41 +00:00
|
|
|
|
2020-05-30 19:10:58 +00:00
|
|
|
$change = $this->newContentModelChange(
|
2022-06-28 21:28:54 +00:00
|
|
|
$user,
|
2020-01-11 23:49:41 +00:00
|
|
|
$this->getNonexistingTestPage( 'NonExistingPage' ),
|
|
|
|
|
'text'
|
|
|
|
|
);
|
|
|
|
|
|
2022-06-28 21:28:54 +00:00
|
|
|
$status = $change->authorizeChange();
|
|
|
|
|
$this->assertFalse( $status->isOK() );
|
|
|
|
|
$this->assertTrue( $status->isRateLimitExceeded() );
|
2020-01-11 23:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|