aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorTim Starling <tstarling@wikimedia.org>2024-12-11 12:29:29 +1100
committerTim Starling <tstarling@wikimedia.org>2024-12-16 12:35:24 +1100
commitcf1198155c27e1cb4b02ec9ab01d91c0820f0667 (patch)
tree1b141a4f45cf3aec7b9a4de696510326980261c7 /tests
parentf69f8de8d2b561b8ff1e019eb94a09c62c3d3ad9 (diff)
downloadmediawikicore-cf1198155c27e1cb4b02ec9ab01d91c0820f0667.tar.gz
mediawikicore-cf1198155c27e1cb4b02ec9ab01d91c0820f0667.zip
block: Multiblocks block API
In ApiBlock: * Add an "id" parameter. If this is given, update the specified block. * Add a "newblock" parameter. If this is given, always add a new block, don't check if the target is already blocked. * If "reblock" is given and the target has more than one block, fail with an "ambiguous-block" error. Supporting changes: * Add BlockUserFactory::newUpdateBlock(), which takes a DatabaseBlock instead of a target union to act on. The block is passed through to the BlockUser constructor. * Rename the first parameter to BlockUser::placeBlock() from $reblock to $conflictMode, and style it like an enum. Add the CONFLICT_NEW value, to support the "newblock" API option. * In DatabaseBlockStore::newFromId(), add $fromPrimary, so that ApiBlock can pass data to BlockUserFactory with equivalent freshness to the LHS. Also: * In BlockUser, memoize prior blocks loaded from the DB * Move T287798 autoblock check to the memoized accessor. Just don't return autoblocks. * Move "TODO handle failure" comment in BlockUser to the called method. It really can't fail. * In DatabaseBlockStore::newFromId(), add an $includeExpired parameter and default to false although it was previously implicitly true. Based on a brief review of callers, I think this is beneficial. Bug: T378147 Change-Id: Iea5b77cb27006b33f3dde61660be5ad2c374a425
Diffstat (limited to 'tests')
-rw-r--r--tests/phpunit/includes/api/ApiBlockTest.php97
-rw-r--r--tests/phpunit/integration/includes/block/BlockUserTest.php51
2 files changed, 144 insertions, 4 deletions
diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php
index adbeb4bdf796..aa5025b12f7c 100644
--- a/tests/phpunit/includes/api/ApiBlockTest.php
+++ b/tests/phpunit/includes/api/ApiBlockTest.php
@@ -3,6 +3,7 @@
namespace MediaWiki\Tests\Api;
use MediaWiki\Block\DatabaseBlock;
+use MediaWiki\Block\DatabaseBlockStore;
use MediaWiki\Block\Restriction\ActionRestriction;
use MediaWiki\Block\Restriction\NamespaceRestriction;
use MediaWiki\Block\Restriction\PageRestriction;
@@ -28,6 +29,8 @@ class ApiBlockTest extends ApiTestCase {
protected $mUser = null;
/** @var DatabaseBlockStore */
private $blockStore;
+ /** @var DatabaseBlock|null */
+ private $block;
protected function setUp(): void {
parent::setUp();
@@ -40,6 +43,7 @@ class ApiBlockTest extends ApiTestCase {
'IPv6' => 19,
]
);
+ $this->overrideConfigValue( MainConfigNames::EnableMultiBlocks, true );
$this->blockStore = $this->getServiceContainer()->getDatabaseBlockStore();
}
@@ -62,12 +66,12 @@ class ApiBlockTest extends ApiTestCase {
}
$ret = $this->doApiRequestWithToken( array_merge( $params, $extraParams ), null, $blocker );
- $block = $this->blockStore->newFromTarget( $this->mUser->getName() );
+ $this->block = $this->blockStore->newFromId( $ret[0]['block']['id'] );
- $this->assertInstanceOf( DatabaseBlock::class, $block, 'Block is valid' );
+ $this->assertInstanceOf( DatabaseBlock::class, $this->block, 'Block is valid' );
- $this->assertSame( $this->mUser->getName(), $block->getTargetName() );
- $this->assertSame( 'Some reason', $block->getReasonComment()->text );
+ $this->assertSame( $this->mUser->getName(), $this->block->getTargetName() );
+ $this->assertSame( 'Some reason', $this->block->getReasonComment()->text );
return $ret;
}
@@ -344,4 +348,89 @@ class ApiBlockTest extends ApiTestCase {
$this->assertArrayHasKey( 'userID', $blockResult );
$this->assertSame( $userId, $blockResult['userID'] );
}
+
+ public function testConflict() {
+ $this->doBlock();
+ $this->expectApiErrorCode( 'alreadyblocked' );
+ $this->doBlock( [ 'noemail' => '' ] );
+ }
+
+ public function testReblock() {
+ $this->doBlock();
+ $this->assertFalse( $this->block->isEmailBlocked() );
+ $this->doBlock( [ 'noemail' => '', 'reblock' => true ] );
+ $this->assertTrue( $this->block->isEmailBlocked() );
+ }
+
+ public function testMultiBlocks() {
+ $this->doBlock();
+ $this->doBlock( [ 'noemail' => '', 'newblock' => '' ] );
+ $this->assertTrue( $this->block->isEmailBlocked() );
+ $this->assertCount( 2, $this->blockStore->newListFromTarget( $this->mUser ) );
+ }
+
+ public function testMultiRedundant() {
+ $this->expectApiErrorCode( 'alreadyblocked' );
+ $this->doBlock();
+ $this->doBlock( [ 'newblock' => '' ] );
+ }
+
+ public function testReblockMulti() {
+ $this->doBlock();
+ $this->doBlock( [ 'noemail' => '', 'newblock' => '' ] );
+ $this->expectApiErrorCode( 'ambiguous-block' );
+ $this->doBlock( [ 'reblock' => true ] );
+ }
+
+ public function testId() {
+ $this->doBlock();
+ $this->assertFalse( $this->block->isEmailBlocked() );
+ $this->doBlock( [ 'noemail' => '', 'id' => $this->block->getId(), 'user' => null ] );
+ $this->assertTrue( $this->block->isEmailBlocked() );
+ }
+
+ public function testIdConflictsWithUser() {
+ $this->expectApiErrorCode( 'invalidparammix' );
+ $this->doBlock( [ 'noemail' => '', 'id' => '1' ] );
+ }
+
+ public function testIdConflictsWithNewblock() {
+ $this->expectApiErrorCode( 'invalidparammix' );
+ $this->doBlock( [ 'newblock' => '', 'id' => '1' ] );
+ }
+
+ public function testIdConflictsWithReblock() {
+ $this->expectApiErrorCode( 'invalidparammix' );
+ $this->doBlock( [ 'reblock' => '', 'id' => '1' ] );
+ }
+
+ public function testIdMulti() {
+ $this->doBlock();
+ $block1 = $this->block->getId();
+ $this->doBlock( [ 'allowusertalk' => '', 'newblock' => '' ] );
+ $block2 = $this->block->getId();
+ $this->assertFalse( $this->blockStore->newFromId( $block2 )->isEmailBlocked() );
+
+ $this->doBlock( [ 'id' => $block2, 'user' => null, 'noemail' => '' ] );
+ $this->assertFalse( $this->blockStore->newFromId( $block1 )->isEmailBlocked() );
+ $this->assertTrue( $this->blockStore->newFromId( $block2 )->isEmailBlocked() );
+ }
+
+ public function testNoSuchBlockId() {
+ $this->expectApiErrorCode( 'nosuchblockid' );
+ $this->doBlock( [ 'id' => '1', 'user' => null ] );
+ }
+
+ public function testModifyAutoblock() {
+ $this->doBlock( [ 'autoblock' => '' ] );
+ $autoId = $this->blockStore->doAutoblock( $this->block, '127.0.0.1' );
+ $this->expectApiErrorCode( 'modify-autoblock' );
+ $this->doBlock( [ 'id' => $autoId, 'user' => null, 'noemail' => '' ] );
+ }
+
+ public function testNoOpBlockUpdate() {
+ $this->doBlock();
+ $this->expectApiErrorCode( 'alreadyblocked' );
+ $this->doBlock( [ 'id' => $this->block->getId(), 'user' => null ] );
+ }
}
diff --git a/tests/phpunit/integration/includes/block/BlockUserTest.php b/tests/phpunit/integration/includes/block/BlockUserTest.php
index 0957a9e0f52c..5b9f78c382a1 100644
--- a/tests/phpunit/integration/includes/block/BlockUserTest.php
+++ b/tests/phpunit/integration/includes/block/BlockUserTest.php
@@ -3,6 +3,7 @@
use MediaWiki\Block\BlockUserFactory;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\MainConfigNames;
use MediaWiki\Tests\Unit\Permissions\MockAuthorityTrait;
use MediaWiki\User\User;
@@ -244,4 +245,54 @@ class BlockUserTest extends MediaWikiIntegrationTestCase {
$this->assertContains( $IPBlock->getId(), $blockIds );
}
+ /**
+ * @covers \MediaWiki\Block\BlockUser::placeBlockUnsafe
+ */
+ public function testTooManyContribs() {
+ // Set the contrib limit to zero so that it fails with one edit
+ $this->overrideConfigValue( MainConfigNames::HideUserContribLimit, 0 );
+ // Reset the stored instance
+ $this->blockUserFactory = $this->getServiceContainer()->getBlockUserFactory();
+ // Make the edit
+ $this->editPage( 'BlockUserTest', 'test', '', NS_MAIN, $this->user );
+ // Try to block the user with the hideuser option
+ $blockStatus = $this->blockUserFactory->newBlockUser(
+ $this->user,
+ $this->getTestUser( [ 'sysop', 'suppress' ] )->getUser(),
+ 'infinity',
+ 'test block',
+ [ 'isHideUser' => true ]
+ )->placeBlockUnsafe();
+ $this->assertStatusError( 'ipb_hide_invalid', $blockStatus );
+ }
+
+ /**
+ * @covers \MediaWiki\Block\BlockUser::placeBlockUnsafe
+ */
+ public function testUpdateWithTooManyContribs() {
+ $this->overrideConfigValue( MainConfigNames::HideUserContribLimit, 0 );
+ $this->blockUserFactory = $this->getServiceContainer()->getBlockUserFactory();
+ $this->editPage( 'BlockUserTest', 'test', '', NS_MAIN, $this->user );
+ $performer = $this->getTestUser( [ 'sysop', 'suppress' ] )->getUser();
+ // Make a regular block, without the hideuser option
+ $blockStatus = $this->blockUserFactory->newBlockUser(
+ $this->user,
+ $performer,
+ 'infinity',
+ 'test block'
+ )->placeBlockUnsafe();
+ $this->assertStatusGood( $blockStatus );
+
+ // Try to change the block to include the hideuser option, which should
+ // fail due to the edit
+ $blockStatus = $this->blockUserFactory->newUpdateBlock(
+ $blockStatus->value,
+ $performer,
+ 'infinity',
+ 'test block',
+ [ 'isHideUser' => true ]
+ )->placeBlockUnsafe();
+ $this->assertStatusError( 'ipb_hide_invalid', $blockStatus );
+ }
+
}