gplx/mediawiki/extensions/BlueSpicePermissionManager/tests/phpunit/GroupManagerTest.php

262 lines
7.1 KiB
PHP

<?php
namespace BlueSpice\PermissionManager\Tests;
use BlueSpice\PermissionManager\GroupManager;
use BlueSpice\PermissionManager\Logging\GroupManagerSpecialLogLogger;
use Exception;
use MediaWiki\Config\Config;
use MediaWiki\HookContainer\HookContainer;
use MediaWiki\Permissions\Authority;
use MWStake\MediaWiki\Component\DynamicConfig\DynamicConfigManager;
use MWStake\MediaWiki\Component\DynamicConfig\GlobalsDynamicConfig;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Wikimedia\Rdbms\IDatabase;
use Wikimedia\Rdbms\ILoadBalancer;
class GroupManagerTest extends TestCase {
/**
* @param string $group
* @param bool $expectSuccess
* @return void
* @throws Exception
* @dataProvider provideAddData
* @covers \BlueSpice\PermissionManager\GroupManager::addGroup
*/
public function testAddGroup( string $group, bool $expectSuccess ) {
$authority = $this->getAuthorityMock();
$configMock = $this->getConfigMock();
$dynamicConfigMock = $this->getDynamicConfigMock(
$expectSuccess ? $this->compileConfigData( $group, $configMock ) : null
);
$lbMock = $this->getLBMock();
if ( $expectSuccess ) {
$hcMock = $this->getHookContainerMock( 'BSPermissionManagerGroupAdded', [ $group, $authority ] );
} else {
$hcMock = $this->getHookContainerMock();
}
$loggerMock = $this->getLoggerMock( $expectSuccess );
$spLoggerMock = $this->getSpLoggerMock( $expectSuccess );
$manager = new GroupManager( $dynamicConfigMock, $lbMock, $configMock, $hcMock, $loggerMock, $spLoggerMock );
if ( !$expectSuccess ) {
$this->expectException( Exception::class );
}
$manager->addGroup( $group, $authority );
}
/**
* @param string $new
* @param bool $expectSuccess
* @return void
* @throws Exception
* @dataProvider provideEditData
* @covers \BlueSpice\PermissionManager\GroupManager::editGroup
*/
public function testEditGroup( string $new, bool $expectSuccess ) {
$old = 'Dummy';
$authority = $this->getAuthorityMock();
$configMock = $this->getConfigMock();
$dynamicConfigMock = $this->getDynamicConfigMock(
$expectSuccess ? [ $new => true ] : null
);
if ( $expectSuccess ) {
$lbMock = $this->getLBMock( 'update', [
'user_groups',
[ 'ug_group' => $new ],
[ 'ug_group' => $old ],
GroupManager::class . '::renameGroup'
] );
} else {
$lbMock = $this->getLBMock();
}
if ( $expectSuccess ) {
$hcMock = $this->getHookContainerMock( 'BSPermissionManagerGroupEdited', [ $old, $new, $authority ] );
} else {
$hcMock = $this->getHookContainerMock();
}
$loggerMock = $this->getLoggerMock( $expectSuccess );
$spLoggerMock = $this->getSpLoggerMock( $expectSuccess );
$manager = new GroupManager( $dynamicConfigMock, $lbMock, $configMock, $hcMock, $loggerMock, $spLoggerMock );
if ( !$expectSuccess ) {
$this->expectException( Exception::class );
}
$manager->editGroup( $old, $new, $authority );
}
/**
* @return void
* @throws Exception
* @covers \BlueSpice\PermissionManager\GroupManager::removeGroup
*/
public function testRemoveGroup() {
$authority = $this->getAuthorityMock();
$configMock = $this->getConfigMock();
$dynamicConfigMock = $this->getDynamicConfigMock( [] );
$lbMock = $this->getLBMock( 'delete', [
'user_groups',
[ 'ug_group' => 'Dummy' ],
GroupManager::class . '::unassignUsers'
] );
$hcMock = $this->getHookContainerMock( 'BSPermissionManagerGroupDeleted', [ 'Dummy', $authority ] );
$loggerMock = $this->getLoggerMock( true );
$spLoggerMock = $this->getSpLoggerMock( true );
$manager = new GroupManager( $dynamicConfigMock, $lbMock, $configMock, $hcMock, $loggerMock, $spLoggerMock );
$manager->removeGroup( 'Dummy', $authority );
}
/**
* @return array[]
*/
public function provideAddData(): array {
// "old name" is always "Dummy"
return [
[ 'foo', true ],
[ 'foo123', true ],
// same name
[ 'Dummy', false ]
];
}
public function provideEditData(): array {
return [
[ 'foo', true ],
[ 'Dummy"""', false ],
[ 'foo123', true ],
];
}
/**
* @return Config|MockObject
*/
private function getConfigMock() {
$mock = $this->createMock( Config::class );
$mock->method( 'get' )->willReturnCallback( static function ( $key ) {
if ( $key === 'AdditionalGroups' ) {
return [ 'Dummy' => true ];
}
if ( $key === 'GroupPermissions' ) {
return [ '*' => [], 'sysop' => [], 'Dummy' => [] ];
}
return null;
} );
return $mock;
}
/**
* @param array|null $data
* @return DynamicConfigManager|MockObject
*/
private function getDynamicConfigMock( ?array $data ) {
$configMock = $this->createMock( GlobalsDynamicConfig::class );
$mock = $this->createMock( DynamicConfigManager::class );
if ( is_array( $data ) ) {
$mock->expects( $this->once() )
->method( 'storeConfig' )
->with( $configMock, $data );
} else {
$mock->expects( $this->never() )
->method( 'storeConfig' );
}
$mock->method( 'getConfigObject' )->willReturnCallback( static function ( $key ) use ( $configMock ) {
if ( $key === 'bs-groupmanager-groups' ) {
return $configMock;
}
return null;
} );
return $mock;
}
/**
* @param string|null $method
* @param array $data
* @return ILoadBalancer|MockObject
*/
private function getLBMock( ?string $method = null, array $data = [] ) {
$dbMock = $this->createMock( IDatabase::class );
$mock = $this->createMock( ILoadBalancer::class );
if ( $method !== null ) {
$dbMock->expects( $this->once() )
->method( $method )
->with( ...$data )
->willReturn( true );
}
$mock->method( 'getConnection' )->willReturn( $dbMock );
return $mock;
}
/**
* @param string $group
* @param Config $config
* @return array[]
*/
private function compileConfigData( string $group, Config $config ): array {
$groups = $config->get( 'AdditionalGroups' ) ?? [];
$groups[$group] = true;
return $groups;
}
private function getHookContainerMock( string $hook = '', array $args = [] ) {
$mock = $this->createMock( HookContainer::class );
if ( $hook ) {
$mock->expects( $this->once() )
->method( 'run' )
->with( $hook, $args );
} else {
$mock->expects( $this->never() )
->method( 'run' );
}
return $mock;
}
/**
* @return Authority|MockObject
*/
private function getAuthorityMock() {
$mock = $this->createMock( Authority::class );
$mock->expects( $this->once() )
->method( 'isAllowed' )
->willReturn( true );
return $mock;
}
/**
* @param bool $expectSuccess
* @return LoggerInterface|MockObject
*/
private function getLoggerMock( bool $expectSuccess ) {
$mock = $this->createMock( LoggerInterface::class );
if ( $expectSuccess ) {
$mock->expects( $this->once() )
->method( 'info' );
} else {
$mock->expects( $this->never() )
->method( 'log' );
}
return $mock;
}
/**
* @param bool $expectSuccess
* @return GroupManagerSpecialLogLogger|MockObject
*/
private function getSpLoggerMock( bool $expectSuccess ) {
$mock = $this->createMock( GroupManagerSpecialLogLogger::class );
if ( $expectSuccess ) {
$mock->expects( $this->once() )
->method( 'log' );
} else {
$mock->expects( $this->never() )
->method( 'log' );
}
return $mock;
}
}