2020-12-09 15:51:59 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
|
|
|
|
use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Degroup;
|
|
|
|
use MediaWiki\Extension\AbuseFilter\Consequences\Parameters;
|
|
|
|
use MediaWiki\Extension\AbuseFilter\FilterUser;
|
2021-01-02 14:01:00 +00:00
|
|
|
use MediaWiki\Extension\AbuseFilter\Variables\VariableHolder;
|
2020-12-09 15:51:59 +00:00
|
|
|
use MediaWiki\User\UserGroupManager;
|
2023-07-26 14:22:30 +00:00
|
|
|
use MediaWiki\User\UserIdentityUtils;
|
2020-12-09 15:51:59 +00:00
|
|
|
use MediaWiki\User\UserIdentityValue;
|
|
|
|
|
|
|
|
/**
|
2023-07-17 17:58:42 +00:00
|
|
|
* @group Database
|
2024-04-17 00:44:40 +00:00
|
|
|
* @covers \MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Degroup
|
2023-07-17 17:58:42 +00:00
|
|
|
* @todo Make this a unit test once ManualLogEntry is servicified (T253717) and DI is possible for User::newSystemUser
|
2020-12-09 15:51:59 +00:00
|
|
|
*/
|
|
|
|
class DegroupTest extends MediaWikiIntegrationTestCase {
|
2021-01-06 13:07:02 +00:00
|
|
|
use ConsequenceGetMessageTestTrait;
|
2020-12-09 15:51:59 +00:00
|
|
|
|
2021-07-21 18:51:12 +00:00
|
|
|
private function getMsgLocalizer(): MessageLocalizer {
|
2021-01-09 23:26:29 +00:00
|
|
|
$ml = $this->createMock( MessageLocalizer::class );
|
2024-04-11 11:52:27 +00:00
|
|
|
$ml->method( 'msg' )->willReturnCallback( function ( $k, ...$p ) {
|
2021-01-09 23:26:29 +00:00
|
|
|
return $this->getMockMessage( $k, $p );
|
|
|
|
} );
|
|
|
|
return $ml;
|
|
|
|
}
|
|
|
|
|
2021-07-21 18:51:12 +00:00
|
|
|
private function getFilterUser(): FilterUser {
|
2021-01-09 23:26:29 +00:00
|
|
|
// TODO: Can't use mocks until ManualLogEntry is servicified (T253717)
|
|
|
|
return AbuseFilterServices::getFilterUser();
|
|
|
|
}
|
|
|
|
|
2020-12-09 15:51:59 +00:00
|
|
|
public function testExecute() {
|
2021-03-26 10:00:56 +00:00
|
|
|
$user = new UserIdentityValue( 1, 'Degrouped user' );
|
2021-01-06 13:07:02 +00:00
|
|
|
$params = $this->provideGetMessageParameters( $user )->current()[0];
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->method( 'listAllImplicitGroups' )
|
|
|
|
->willReturn( [ '*', 'user' ] );
|
|
|
|
$userGroupManager->expects( $this->once() )
|
|
|
|
->method( 'removeUserFromGroup' )
|
|
|
|
->with( $user, 'sysop' );
|
2021-01-09 23:26:29 +00:00
|
|
|
$filterUser = $this->getFilterUser();
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils = $this->createMock( UserIdentityUtils::class );
|
|
|
|
$userIdentityUtils->method( 'isNamed' )->willReturn( true );
|
2020-12-09 15:51:59 +00:00
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
2021-01-02 14:01:00 +00:00
|
|
|
VariableHolder::newFromArray( [ 'user_groups' => [ '*', 'user', 'sysop' ] ] ),
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils,
|
2021-01-09 23:26:29 +00:00
|
|
|
$filterUser,
|
|
|
|
$this->getMsgLocalizer()
|
2020-12-09 15:51:59 +00:00
|
|
|
);
|
|
|
|
$this->assertTrue( $degroup->execute() );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testExecute_noGroups() {
|
2021-01-06 13:07:02 +00:00
|
|
|
$params = $this->provideGetMessageParameters()->current()[0];
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->method( 'listAllImplicitGroups' )
|
|
|
|
->willReturn( [ '*', 'user' ] );
|
|
|
|
$userGroupManager->expects( $this->never() )
|
|
|
|
->method( 'removeUserFromGroup' );
|
|
|
|
|
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
2021-01-02 14:01:00 +00:00
|
|
|
VariableHolder::newFromArray( [ 'user_groups' => [ '*', 'user' ] ] ),
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$this->createMock( UserIdentityUtils::class ),
|
2021-01-09 23:26:29 +00:00
|
|
|
$this->createMock( FilterUser::class ),
|
|
|
|
$this->getMsgLocalizer()
|
2020-12-09 15:51:59 +00:00
|
|
|
);
|
|
|
|
$this->assertFalse( $degroup->execute() );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testExecute_variableNotSet() {
|
2021-03-26 10:00:56 +00:00
|
|
|
$user = new UserIdentityValue( 1, 'Degrouped user' );
|
2021-01-06 13:07:02 +00:00
|
|
|
$params = $this->provideGetMessageParameters( $user )->current()[0];
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->method( 'listAllImplicitGroups' )
|
|
|
|
->willReturn( [ '*', 'user' ] );
|
|
|
|
$userGroupManager->method( 'getUserEffectiveGroups' )
|
|
|
|
->with( $user )
|
|
|
|
->willReturn( [ '*', 'user', 'sysop' ] );
|
|
|
|
$userGroupManager->expects( $this->once() )
|
|
|
|
->method( 'removeUserFromGroup' )
|
|
|
|
->with( $user, 'sysop' );
|
2021-01-09 23:26:29 +00:00
|
|
|
$filterUser = $this->getFilterUser();
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils = $this->createMock( UserIdentityUtils::class );
|
|
|
|
$userIdentityUtils->method( 'isNamed' )->willReturn( true );
|
2020-12-09 15:51:59 +00:00
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
2021-01-02 14:01:00 +00:00
|
|
|
new VariableHolder(),
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils,
|
2021-01-09 23:26:29 +00:00
|
|
|
$filterUser,
|
|
|
|
$this->getMsgLocalizer()
|
2020-12-09 15:51:59 +00:00
|
|
|
);
|
|
|
|
$this->assertTrue( $degroup->execute() );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testExecute_anonymous() {
|
2021-03-26 10:00:56 +00:00
|
|
|
$user = new UserIdentityValue( 0, 'Anonymous user' );
|
2021-01-06 13:07:02 +00:00
|
|
|
$params = $this->provideGetMessageParameters( $user )->current()[0];
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->expects( $this->never() )->method( $this->anything() );
|
|
|
|
$filterUser = $this->createMock( FilterUser::class );
|
|
|
|
$filterUser->expects( $this->never() )->method( $this->anything() );
|
|
|
|
|
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
2021-01-02 14:01:00 +00:00
|
|
|
$this->createMock( VariableHolder::class ),
|
2020-12-09 15:51:59 +00:00
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$this->createMock( UserIdentityUtils::class ),
|
2023-05-30 11:37:38 +00:00
|
|
|
$filterUser,
|
|
|
|
$this->getMsgLocalizer()
|
|
|
|
);
|
|
|
|
$this->assertFalse( $degroup->execute() );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testExecute_temp() {
|
|
|
|
$user = new UserIdentityValue( 10, '*12345' );
|
|
|
|
$params = $this->provideGetMessageParameters( $user )->current()[0];
|
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->expects( $this->never() )->method( $this->anything() );
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils = $this->createMock( UserIdentityUtils::class );
|
|
|
|
$userIdentityUtils->method( 'isNamed' )->willReturn( false );
|
2023-05-30 11:37:38 +00:00
|
|
|
$filterUser = $this->createMock( FilterUser::class );
|
|
|
|
$filterUser->expects( $this->never() )->method( $this->anything() );
|
|
|
|
|
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
|
|
|
$this->createMock( VariableHolder::class ),
|
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$userIdentityUtils,
|
2021-01-09 23:26:29 +00:00
|
|
|
$filterUser,
|
|
|
|
$this->getMsgLocalizer()
|
2020-12-09 15:51:59 +00:00
|
|
|
);
|
|
|
|
$this->assertFalse( $degroup->execute() );
|
|
|
|
}
|
|
|
|
|
2023-05-20 19:44:55 +00:00
|
|
|
public static function provideRevert(): array {
|
2020-11-29 15:18:32 +00:00
|
|
|
return [
|
|
|
|
[ true, [ '*', 'user', 'sysop' ] ],
|
|
|
|
[ true, [ '*', 'user', 'canceled', 'sysop' ] ],
|
|
|
|
[ false, [ '*', 'user', 'sysop' ], [ 'sysop' ] ],
|
|
|
|
[ false, [ '*', 'user', 'canceled' ] ],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideRevert
|
|
|
|
*/
|
|
|
|
public function testRevert( bool $success, array $hadGroups, array $hasGroups = [] ) {
|
2021-03-26 10:00:56 +00:00
|
|
|
$user = new UserIdentityValue( 1, 'Degrouped user' );
|
2021-01-06 13:07:02 +00:00
|
|
|
$params = $this->provideGetMessageParameters( $user )->current()[0];
|
2020-11-29 15:18:32 +00:00
|
|
|
$userGroupManager = $this->createMock( UserGroupManager::class );
|
|
|
|
$userGroupManager->method( 'listAllImplicitGroups' )
|
|
|
|
->willReturn( [ '*', 'user' ] );
|
|
|
|
$userGroupManager->method( 'getUserGroups' )
|
|
|
|
->with( $user )
|
|
|
|
->willReturn( $hasGroups );
|
|
|
|
$userGroupManager->method( 'addUserToGroup' )
|
2021-04-30 18:54:17 +00:00
|
|
|
->willReturnCallback( static function ( $_, $group ) use ( $hasGroups ) {
|
2020-11-29 15:18:32 +00:00
|
|
|
return $group === 'sysop';
|
|
|
|
} );
|
|
|
|
$degroup = new Degroup(
|
|
|
|
$params,
|
2022-06-08 09:59:18 +00:00
|
|
|
VariableHolder::newFromArray( [ 'user_groups' => $hadGroups ] ),
|
2020-11-29 15:18:32 +00:00
|
|
|
$userGroupManager,
|
2023-07-26 14:22:30 +00:00
|
|
|
$this->createMock( UserIdentityUtils::class ),
|
2021-01-09 23:26:29 +00:00
|
|
|
$this->createMock( FilterUser::class ),
|
|
|
|
$this->getMsgLocalizer()
|
2020-11-29 15:18:32 +00:00
|
|
|
);
|
|
|
|
|
2023-07-17 17:58:42 +00:00
|
|
|
$performer = new UserIdentityValue( 42, 'Foo' );
|
2020-11-29 15:18:32 +00:00
|
|
|
$this->assertSame(
|
|
|
|
$success,
|
2022-06-08 09:59:18 +00:00
|
|
|
$degroup->revert( $performer, 'reason' )
|
2020-11-29 15:18:32 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-06 13:07:02 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideGetMessageParameters
|
|
|
|
*/
|
|
|
|
public function testGetMessage( Parameters $params ) {
|
|
|
|
$rangeBlock = new Degroup(
|
|
|
|
$params,
|
|
|
|
new VariableHolder(),
|
|
|
|
$this->createMock( UserGroupManager::class ),
|
2023-07-26 14:22:30 +00:00
|
|
|
$this->createMock( UserIdentityUtils::class ),
|
2021-01-09 23:26:29 +00:00
|
|
|
$this->createMock( FilterUser::class ),
|
|
|
|
$this->getMsgLocalizer()
|
2021-01-06 13:07:02 +00:00
|
|
|
);
|
|
|
|
$this->doTestGetMessage( $rangeBlock, $params, 'abusefilter-degrouped' );
|
|
|
|
}
|
2020-12-09 15:51:59 +00:00
|
|
|
}
|