crm_case-1.0.x-dev/tests/src/Unit/CrmCaseAccessControlHandlerTest.php
tests/src/Unit/CrmCaseAccessControlHandlerTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\crm_case\Unit;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\crm_case\CrmCaseAccessControlHandler;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Cache\Context\CacheContextsManager;
/**
* Tests the CrmCaseAccessControlHandler class.
*
* @group crm_case
* @coversDefaultClass \Drupal\crm_case\CrmCaseAccessControlHandler
*/
class CrmCaseAccessControlHandlerTest extends UnitTestCase {
/**
* The access control handler under test.
*
* @var \Drupal\crm_case\CrmCaseAccessControlHandler
*/
protected $accessHandler;
/**
* Mock entity type.
*
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $entityType;
/**
* Mock entity.
*
* @var \Drupal\Core\Entity\EntityInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $entity;
/**
* Mock module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $moduleHandler;
/**
* Mock cache contexts manager.
*
* @var \Drupal\Core\Cache\Context\CacheContextsManager|\PHPUnit\Framework\MockObject\MockObject
*/
protected $cacheContextsManager;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$container = new ContainerBuilder();
$this->moduleHandler = $this->createMock(ModuleHandlerInterface::class);
$container->set('module_handler', $this->moduleHandler);
$this->cacheContextsManager = $this->createMock(CacheContextsManager::class);
$this->cacheContextsManager->method('assertValidTokens')
->willReturn(TRUE);
$container->set('cache_contexts_manager', $this->cacheContextsManager);
\Drupal::setContainer($container);
$this->entityType = $this->createMock(EntityTypeInterface::class);
$this->entity = $this->createMock(EntityInterface::class);
// Mock the language object to prevent null pointer exceptions.
$language = $this->createMock(LanguageInterface::class);
$language->method('getId')->willReturn('en');
$this->entity->method('language')->willReturn($language);
$this->accessHandler = new CrmCaseAccessControlHandler($this->entityType);
}
/**
* Tests view access.
*
* @covers ::checkAccess
* @dataProvider viewAccessProvider
*/
public function testViewAccess(array $permissions, bool $expected): void {
$this->moduleHandler->expects($this->exactly(2))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$account->method('hasPermission')
->willReturnCallback(function ($permission) use ($permissions) {
return in_array($permission, $permissions);
});
$result = $this->accessHandler->access($this->entity, 'view', $account, TRUE);
if ($expected) {
$this->assertTrue($result->isAllowed());
}
else {
$this->assertTrue($result->isForbidden() || $result->isNeutral());
}
}
/**
* Data provider for view access tests.
*
* @return array
* Test data.
*/
public static function viewAccessProvider(): array {
return [
'no permissions' => [[], FALSE],
'view permission' => [['view crm case'], TRUE],
'other permissions' => [['edit crm case'], FALSE],
];
}
/**
* Tests update access.
*
* @covers ::checkAccess
* @dataProvider updateAccessProvider
*/
public function testUpdateAccess(array $permissions, bool $expected): void {
$this->moduleHandler->expects($this->exactly(2))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$account->method('hasPermission')
->willReturnCallback(function ($permission) use ($permissions) {
return in_array($permission, $permissions);
});
$result = $this->accessHandler->access($this->entity, 'update', $account, TRUE);
if ($expected) {
$this->assertTrue($result->isAllowed());
}
else {
$this->assertTrue($result->isForbidden() || $result->isNeutral());
}
}
/**
* Data provider for update access tests.
*
* @return array
* Test data.
*/
public static function updateAccessProvider(): array {
return [
'no permissions' => [[], FALSE],
'edit permission' => [['edit crm case'], TRUE],
'administer permission' => [['administer crm'], TRUE],
'both permissions' => [['edit crm case', 'administer crm'], TRUE],
'view only' => [['view crm case'], FALSE],
];
}
/**
* Tests delete access.
*
* @covers ::checkAccess
* @dataProvider deleteAccessProvider
*/
public function testDeleteAccess(array $permissions, bool $expected): void {
$this->moduleHandler->expects($this->exactly(2))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$account->method('hasPermission')
->willReturnCallback(function ($permission) use ($permissions) {
return in_array($permission, $permissions);
});
$result = $this->accessHandler->access($this->entity, 'delete', $account, TRUE);
if ($expected) {
$this->assertTrue($result->isAllowed());
}
else {
$this->assertTrue($result->isForbidden() || $result->isNeutral());
}
}
/**
* Data provider for delete access tests.
*
* @return array
* Test data.
*/
public static function deleteAccessProvider(): array {
return [
'no permissions' => [[], FALSE],
'delete permission' => [['delete crm case'], TRUE],
'administer permission' => [['administer crm'], TRUE],
'both permissions' => [['delete crm case', 'administer crm'], TRUE],
'view only' => [['view crm case'], FALSE],
'edit only' => [['edit crm case'], FALSE],
];
}
/**
* Tests create access.
*
* @covers ::checkCreateAccess
* @dataProvider createAccessProvider
*/
public function testCreateAccess(array $permissions, bool $expected): void {
$this->moduleHandler->expects($this->exactly(2))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$account->method('hasPermission')
->willReturnCallback(function ($permission) use ($permissions) {
return in_array($permission, $permissions);
});
$result = $this->accessHandler->createAccess('test_bundle', $account, [], TRUE);
if ($expected) {
$this->assertTrue($result->isAllowed());
}
else {
$this->assertTrue($result->isForbidden() || $result->isNeutral());
}
}
/**
* Data provider for create access tests.
*
* @return array
* Test data.
*/
public static function createAccessProvider(): array {
return [
'no permissions' => [[], FALSE],
'create permission' => [['create crm case'], TRUE],
'administer permission' => [['administer crm'], TRUE],
'both permissions' => [['create crm case', 'administer crm'], TRUE],
'view only' => [['view crm case'], FALSE],
'edit only' => [['edit crm case'], FALSE],
];
}
/**
* Tests unknown operation access.
*
* @covers ::checkAccess
*/
public function testUnknownOperationAccess(): void {
$this->moduleHandler->expects($this->exactly(2))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$result = $this->accessHandler->access($this->entity, 'unknown_operation', $account, TRUE);
$this->assertTrue($result->isNeutral(), 'Unknown operations should return neutral access.');
}
/**
* Tests that AccessResult objects are returned.
*
* @covers ::checkAccess
* @covers ::checkCreateAccess
*/
public function testReturnsAccessResult(): void {
$this->moduleHandler->expects($this->exactly(4))
->method('invokeAll')
->willReturn([]);
$account = $this->createMock(AccountInterface::class);
$account->method('hasPermission')->willReturn(TRUE);
// Test checkAccess returns AccessResult.
$result = $this->accessHandler->access($this->entity, 'view', $account, TRUE);
$this->assertInstanceOf(AccessResult::class, $result);
// Test checkCreateAccess returns AccessResult.
$result = $this->accessHandler->createAccess('test_bundle', $account, [], TRUE);
$this->assertInstanceOf(AccessResult::class, $result);
}
}
