From d67121f6d3961bb7dfc44f71e8b5a4b8b9279eef Mon Sep 17 00:00:00 2001 From: Dayllan Maza Date: Sun, 26 Aug 2018 21:45:18 -0400 Subject: [PATCH] Enforce partial blocks Enforce partial blocks and display a slightly different block notice depending on if the block is sitewide or not Bug: T197117 Depends-On: I675316dddf272fd0d6172ecad3882160752bf780 Change-Id: I8a3635a4a04a33912eb139b7b13c4bd874183d31 --- includes/Block.php | 74 ++++++++++-- includes/api/ApiBase.php | 12 ++ includes/api/ApiEditPage.php | 6 +- includes/api/i18n/en.json | 1 + includes/api/i18n/qqq.json | 1 + includes/specials/SpecialEmailuser.php | 15 ++- includes/specials/SpecialUpload.php | 2 +- includes/user/User.php | 35 ++++-- languages/i18n/en.json | 2 + languages/i18n/qqq.json | 2 + tests/phpunit/includes/BlockTest.php | 112 ++++++++++++++++++ .../phpunit/includes/TitlePermissionTest.php | 17 +++ .../phpunit/includes/api/ApiQueryInfoTest.php | 2 +- 13 files changed, 254 insertions(+), 27 deletions(-) diff --git a/includes/Block.php b/includes/Block.php index d1de85b9cb..befc50c889 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -1146,7 +1146,10 @@ class Block { * @return bool|null Null for unrecognized rights. */ public function prevents( $action, $x = null ) { - global $wgBlockDisablesLogin; + $config = RequestContext::getMain()->getConfig(); + $blockDisablesLogin = $config->get( 'BlockDisablesLogin' ); + $blockAllowsUTEdit = $config->get( 'BlockAllowsUTEdit' ); + $res = null; switch ( $action ) { case 'edit': @@ -1159,14 +1162,22 @@ class Block { case 'sendemail': $res = wfSetVar( $this->mBlockEmail, $x ); break; + case 'upload': + // Until T6995 is completed + $res = $this->isSitewide(); + break; case 'editownusertalk': $res = wfSetVar( $this->mDisableUsertalk, $x ); + // edit own user talk can be disabled by config + if ( !$blockAllowsUTEdit ) { + $res = true; + } break; case 'read': $res = false; break; } - if ( !$res && $wgBlockDisablesLogin ) { + if ( !$res && $blockDisablesLogin ) { // If a block would disable login, then it should // prevent any action that all users cannot do $anon = new User; @@ -1692,6 +1703,29 @@ class Block { * @return array */ public function getPermissionsError( IContextSource $context ) { + $params = $this->getBlockErrorParams( $context ); + + $msg = 'blockedtext'; + if ( $this->getSystemBlockType() !== null ) { + $msg = 'systemblockedtext'; + } elseif ( $this->mAuto ) { + $msg = 'autoblockedtext'; + } elseif ( !$this->isSitewide() ) { + $msg = 'blockedtext-partial'; + } + + array_unshift( $params, $msg ); + + return $params; + } + + /** + * Get block information used in different block error messages + * + * @param IContextSource $context + * @return array + */ + public function getBlockErrorParams( IContextSource $context ) { $blocker = $this->getBlocker(); if ( $blocker instanceof User ) { // local user $blockerUserpage = $blocker->getUserPage(); @@ -1708,14 +1742,10 @@ class Block { /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked. * This could be a username, an IP range, or a single IP. */ $intended = $this->getTarget(); - $systemBlockType = $this->getSystemBlockType(); - $lang = $context->getLanguage(); + return [ - $systemBlockType !== null - ? 'systemblockedtext' - : ( $this->mAuto ? 'autoblockedtext' : 'blockedtext' ), $link, $reason, $context->getRequest()->getIP(), @@ -1762,4 +1792,34 @@ class Block { return $this; } + + /** + * Checks if a block prevents an edit on a given article + * + * @param \Title $title + * @return bool + */ + public function preventsEdit( \Title $title ) { + $blocked = $this->isSitewide(); + + // user talk page has it's own rules + // This check happens before partial blocks because the flag + // to allow user to edit their user talk page could be + // overwritten by a partial block restriction (E.g. user talk namespace) + $user = $this->getTarget(); + if ( $title->equals( $user->getTalkPage() ) ) { + $blocked = $this->prevents( 'editownusertalk' ); + } + + if ( !$this->isSitewide() ) { + $restrictions = $this->getRestrictions(); + foreach ( $restrictions as $restriction ) { + if ( $restriction->matches( $title ) ) { + $blocked = true; + } + } + } + + return $blocked; + } } diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index bb86536cb3..1ca54c1c14 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1853,6 +1853,12 @@ abstract class ApiBase extends ContextSource { 'blocked', [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] ) ); + } elseif ( is_array( $error ) && $error[0] === 'blockedtext-partial' && $user->getBlock() ) { + $status->fatal( ApiMessage::create( + 'apierror-blocked-partial', + 'blocked', + [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] + ) ); } elseif ( is_array( $error ) && $error[0] === 'autoblockedtext' && $user->getBlock() ) { $status->fatal( ApiMessage::create( 'apierror-autoblocked', @@ -2027,6 +2033,12 @@ abstract class ApiBase extends ContextSource { 'autoblocked', [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $block ) ] ); + } elseif ( !$block->isSitewide() ) { + $this->dieWithError( + 'apierror-blocked-partial', + 'blocked', + [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $block ) ] + ); } else { $this->dieWithError( 'apierror-blocked', diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php index 83f72e54c1..5e5efa5b6a 100644 --- a/includes/api/ApiEditPage.php +++ b/includes/api/ApiEditPage.php @@ -414,11 +414,7 @@ class ApiEditPage extends ApiBase { // obvious that this is even possible. // @codeCoverageIgnoreStart case EditPage::AS_BLOCKED_PAGE_FOR_USER: - $this->dieWithError( - 'apierror-blocked', - 'blocked', - [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] - ); + $this->dieBlocked( $user->getBlock() ); case EditPage::AS_READ_ONLY_PAGE: $this->dieReadOnly(); diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index 25bf3f74a7..c50aa41d87 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -1706,6 +1706,7 @@ "apierror-bad-watchlist-token": "Incorrect watchlist token provided. Please set a correct token in [[Special:Preferences]].", "apierror-blockedfrommail": "You have been blocked from sending email.", "apierror-blocked": "You have been blocked from editing.", + "apierror-blocked-partial": "You have been blocked from editing this page.", "apierror-botsnotsupported": "This interface is not supported for bots.", "apierror-cannot-async-upload-file": "The parameters async and file cannot be combined. If you want asynchronous processing of your uploaded file, first upload it to stash (using the stash parameter) and then publish the stashed file asynchronously (using filekey and async).", "apierror-cannotreauthenticate": "This action is not available as your identity cannot be verified.", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index d27933051a..ec60dbf34c 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -1594,6 +1594,7 @@ "apierror-bad-watchlist-token": "{{doc-apierror}}", "apierror-blockedfrommail": "{{doc-apierror}}", "apierror-blocked": "{{doc-apierror}}", + "apierror-blocked-partial": "{{doc-apierror}}", "apierror-botsnotsupported": "{{doc-apierror}}", "apierror-cannot-async-upload-file": "{{doc-apierror}}", "apierror-cannotreauthenticate": "{{doc-apierror}}", diff --git a/includes/specials/SpecialEmailuser.php b/includes/specials/SpecialEmailuser.php index 7de44d8ae2..f1a20d52f7 100644 --- a/includes/specials/SpecialEmailuser.php +++ b/includes/specials/SpecialEmailuser.php @@ -131,7 +131,7 @@ class SpecialEmailUser extends UnlistedSpecialPage { case 'badaccess': throw new PermissionsError( 'sendemail' ); case 'blockedemailuser': - throw new UserBlockedError( $this->getUser()->mBlock ); + throw $this->getBlockedEmailError(); case 'actionthrottledtext': throw new ThrottledError; case 'mailnologin': @@ -524,4 +524,17 @@ class SpecialEmailUser extends UnlistedSpecialPage { protected function getGroupName() { return 'users'; } + + /** + * Builds an error message based on the block params + * + * @return ErrorPageError + */ + private function getBlockedEmailError() { + $block = $this->getUser()->mBlock; + $params = $block->getBlockErrorParams( $this->getContext() ); + + $msg = $block->isSitewide() ? 'blockedtext' : 'blocked-email-user'; + return new ErrorPageError( 'blockedtitle', $msg, $params ); + } } diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index f9d6b5f86e..836b6df47e 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -177,7 +177,7 @@ class SpecialUpload extends SpecialPage { } # Check blocks - if ( $user->isBlocked() ) { + if ( $user->isBlockedFromUpload() ) { throw new UserBlockedError( $user->getBlock() ); } diff --git a/includes/user/User.php b/includes/user/User.php index 5e5ca1b6f7..48d54ec04f 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -2297,21 +2297,22 @@ class User implements IDBAccessObject, UserIdentity { * Check if user is blocked from editing a particular article * * @param Title $title Title to check - * @param bool $bFromSlave Whether to check the replica DB instead of the master + * @param bool $fromSlave Whether to check the replica DB instead of the master * @return bool */ - public function isBlockedFrom( $title, $bFromSlave = false ) { - global $wgBlockAllowsUTEdit; + public function isBlockedFrom( $title, $fromSlave = false ) { + $blocked = $this->isHidden(); - $blocked = $this->isBlocked( $bFromSlave ); - $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk : false ); - // If a user's name is suppressed, they cannot make edits anywhere - if ( !$this->mHideName && $allowUsertalk && $title->getText() === $this->getName() - && $title->getNamespace() == NS_USER_TALK ) { - $blocked = false; - wfDebug( __METHOD__ . ": self-talk page, ignoring any blocks\n" ); + if ( !$blocked ) { + $block = $this->getBlock( $fromSlave ); + if ( $block ) { + $blocked = $block->preventsEdit( $title ); + } } + // only for the purpose of the hook. We really don't need this here. + $allowUsertalk = $this->mAllowUsertalk; + Hooks::run( 'UserIsBlockedFrom', [ $this, $title, &$blocked, &$allowUsertalk ] ); return $blocked; @@ -2418,7 +2419,7 @@ class User implements IDBAccessObject, UserIdentity { */ public function isHidden() { if ( $this->mHideName !== null ) { - return $this->mHideName; + return (bool)$this->mHideName; } $this->getBlockedStatus(); if ( !$this->mHideName ) { @@ -2428,7 +2429,7 @@ class User implements IDBAccessObject, UserIdentity { $this->mHideName = $authUser && $authUser->isHidden(); Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] ); } - return $this->mHideName; + return (bool)$this->mHideName; } /** @@ -4518,6 +4519,16 @@ class User implements IDBAccessObject, UserIdentity { return $this->mBlock && $this->mBlock->prevents( 'sendemail' ); } + /** + * Get whether the user is blocked from using Special:Upload + * + * @return bool + */ + public function isBlockedFromUpload() { + $this->getBlockedStatus(); + return $this->mBlock && $this->mBlock->prevents( 'upload' ); + } + /** * Get whether the user is allowed to create an account. * @return bool diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 5283a5bb06..14f39a6c69 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -666,6 +666,8 @@ "subject-preview": "Preview of subject:", "previewerrortext": "An error occurred while attempting to preview your changes.", "blockedtitle": "User is blocked", + "blocked-email-user": "Your username has been blocked from sending email. You can still edit other pages on this wiki. You can view the full block details at [[Special:MyContributions|account contributions]].\n\nThe block was made by $1.\n\nThe reason given is $2.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n* Block ID #$5", + "blockedtext-partial": "Your username or IP address has been blocked from making changes to this page. You can still edit other pages on this wiki. You can view the full block details at [[Special:MyContributions|account contributions]].\n\nThe block was made by $1.\n\nThe reason given is $2.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n* Block ID #$5", "blockedtext": "Your username or IP address has been blocked.\n\nThe block was made by $1.\nThe reason given is $2.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"{{int:emailuser}}\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.", "autoblockedtext": "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.\nThe reason given is:\n\n:$2\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.\n\nNote that you may not use the \"{{int:emailuser}}\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.\n\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.", "systemblockedtext": "Your username or IP address has been automatically blocked by MediaWiki.\nThe reason given is:\n\n:$2\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYour current IP address is $3.\nPlease include all above details in any queries you make.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index a17cfca049..91d228cc10 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -868,6 +868,8 @@ "subject-preview": "Used as label for preview of the section title when adding a new section on a talk page.\n\nShould match {{msg-mw|subject}}.\n\nSee also:\n* {{msg-mw|Summary-preview}}\n\n{{Identical|Subject}}", "previewerrortext": "When a user has the editing preference LivePreview enabled, clicked the Preview or Show Changes button in the edit page and the action did not succeed.", "blockedtitle": "Used as title displayed for blocked users. The corresponding message body is one of the following messages:\n* {{msg-mw|Blockedtext|notext=1}}\n* {{msg-mw|Autoblockedtext|notext=1}}\n* {{msg-mw|Systemblockedtext}}", + "blocked-email-user": "Text displayed to partially blocked users that are blocked from sending email.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - the blocking sysop (with a link to his/her userpage)\n* $2 - the reason for the block\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the blocking sysop's username (plain text, without the link)\n* $5 - the unique numeric identifier of the applied autoblock\n* $6 - the expiry of the block\n* $7 - the intended target of the block (what the blocking user specified in the blocking form)\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Autoblockedtext}}\n* {{msg-mw|Systemblockedtext}}", + "blockedtext-partial": "Text displayed to partially blocked users.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - the blocking sysop (with a link to his/her userpage)\n* $2 - the reason for the block\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the blocking sysop's username (plain text, without the link)\n* $5 - the unique numeric identifier of the applied autoblock\n* $6 - the expiry of the block\n* $7 - the intended target of the block (what the blocking user specified in the blocking form)\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Autoblockedtext}}\n* {{msg-mw|Systemblockedtext}}", "blockedtext": "Text displayed to blocked users.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - the blocking sysop (with a link to his/her userpage)\n* $2 - the reason for the block\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the blocking sysop's username (plain text, without the link)\n* $5 - the unique numeric identifier of the applied autoblock\n* $6 - the expiry of the block\n* $7 - the intended target of the block (what the blocking user specified in the blocking form)\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Autoblockedtext}}\n* {{msg-mw|Systemblockedtext}}", "autoblockedtext": "Text displayed to automatically blocked users.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - the blocking sysop (with a link to his/her userpage)\n* $2 - the reason for the block (in case of autoblocks: {{msg-mw|autoblocker}})\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the blocking sysop's username (plain text, without the link). Use it for GENDER.\n* $5 - the unique numeric identifier of the applied autoblock\n* $6 - the expiry of the block\n* $7 - the intended target of the block (what the blocking user specified in the blocking form)\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Blockedtext}}\n* {{msg-mw|Systemblockedtext}}", "systemblockedtext": "Text displayed to requests blocked by MediaWiki configuration.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - (Unused) A dummy user attributed as the blocker, possibly as a link to a user page.\n* $2 - the reason for the block\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the dummy blocking user's username (plain text, without the link).\n* $5 - A short string indicating the type of system block.\n* $6 - the expiry of the block\n* $7 - the intended target of the block\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Blockedtext}}\n* {{msg-mw|Autoblockedtext}}", diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index 8760d5e01c..9954425651 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -1,5 +1,6 @@ delete(); } + /** + * @covers Block::preventsEdit + */ + public function testPreventsEditReturnsTrueOnSitewideBlock() { + $user = $this->getTestUser()->getUser(); + $block = new Block( [ + 'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ), + 'allowUsertalk' => true, + 'sitewide' => true + ] ); + + $block->setTarget( $user ); + $block->setBlocker( $this->getTestSysop()->getUser() ); + $block->insert(); + + $title = $this->getExistingTestPage( 'Foo' )->getTitle(); + + $this->assertTrue( $block->preventsEdit( $title ) ); + + $block->delete(); + } + + /** + * @covers Block::preventsEdit + */ + public function testPreventsEditOnPartialBlock() { + $user = $this->getTestUser()->getUser(); + $block = new Block( [ + 'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ), + 'allowUsertalk' => true, + 'sitewide' => false + ] ); + + $block->setTarget( $user ); + $block->setBlocker( $this->getTestSysop()->getUser() ); + $block->insert(); + + $pageFoo = $this->getExistingTestPage( 'Foo' ); + $pageBar = $this->getExistingTestPage( 'Bar' ); + + $pageRestriction = new PageRestriction( $block->getId(), $pageFoo->getId() ); + BlockRestriction::insert( [ $pageRestriction ] ); + + $this->assertTrue( $block->preventsEdit( $pageFoo->getTitle() ) ); + $this->assertFalse( $block->preventsEdit( $pageBar->getTitle() ) ); + + $block->delete(); + } + + /** + * @covers Block::preventsEdit + * @dataProvider preventsEditOnUserTalkProvider + */ + public function testPreventsEditOnUserTalkPage( + $allowUsertalk, $sitewide, $result, $blockAllowsUTEdit = true + ) { + $this->setMwGlobals( [ + 'wgBlockAllowsUTEdit' => $blockAllowsUTEdit, + ] ); + + $user = $this->getTestUser()->getUser(); + $block = new Block( [ + 'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ), + 'allowUsertalk' => $allowUsertalk, + 'sitewide' => $sitewide + ] ); + + $block->setTarget( $user ); + $block->setBlocker( $this->getTestSysop()->getUser() ); + $block->insert(); + + $this->assertEquals( $result, $block->preventsEdit( $user->getTalkPage() ) ); + $block->delete(); + } + + public function preventsEditOnUserTalkProvider() { + return [ + [ + 'allowUsertalk' => false, + 'sitewide' => true, + 'result' => true, + ], + [ + 'allowUsertalk' => true, + 'sitewide' => true, + 'result' => false, + ], + [ + 'allowUsertalk' => true, + 'sitewide' => false, + 'result' => false, + ], + [ + 'allowUsertalk' => false, + 'sitewide' => false, + 'result' => true, + ], + [ + 'allowUsertalk' => true, + 'sitewide' => true, + 'result' => true, + 'blockAllowsUTEdit' => false + ], + [ + 'allowUsertalk' => true, + 'sitewide' => false, + 'result' => true, + 'blockAllowsUTEdit' => false + ], + ]; + } } diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index 5aa24e597d..11b9c012f8 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -969,5 +969,22 @@ class TitlePermissionTest extends MediaWikiLangTestCase { 'Useruser', 'test', '23:00, 31 December 1969', '127.0.8.1', $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ], $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); + + // partial block message test + $this->user->mBlockedby = $this->user->getName(); + $this->user->mBlock = new Block( [ + 'address' => '127.0.8.1', + 'by' => $this->user->getId(), + 'reason' => 'no reason given', + 'timestamp' => $now, + 'sitewide' => false, + 'expiry' => 10, + ] ); + + $this->assertEquals( [ [ 'blockedtext-partial', + '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', + 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1', + $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ], + $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); } } diff --git a/tests/phpunit/includes/api/ApiQueryInfoTest.php b/tests/phpunit/includes/api/ApiQueryInfoTest.php index 80043daee4..3aaad486e9 100644 --- a/tests/phpunit/includes/api/ApiQueryInfoTest.php +++ b/tests/phpunit/includes/api/ApiQueryInfoTest.php @@ -107,7 +107,7 @@ class ApiQueryInfoTest extends ApiTestCase { 'user' => $badActor->getId(), 'by' => $sysop->getId(), 'expiry' => 'infinity', - 'sitewide' => 0, + 'sitewide' => 1, 'enableAutoblock' => true, ] ); -- 2.20.1