2026-03-04 15:56:58 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MintyPHP\Tests\Service\Access;
|
|
|
|
|
|
|
|
|
|
use MintyPHP\Service\Access\AuthorizationDecision;
|
|
|
|
|
use MintyPHP\Service\Access\AuthorizationService;
|
|
|
|
|
use MintyPHP\Service\Access\OperationsAuthorizationPolicy;
|
|
|
|
|
use MintyPHP\Service\Access\UiAccessService;
|
2026-03-05 11:17:42 +01:00
|
|
|
use MintyPHP\Service\Access\UiCapabilityMap;
|
2026-03-04 15:56:58 +01:00
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
|
|
class UiAccessServiceTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
public function testAllowCachesDecisionPerAbilityAndContext(): void
|
|
|
|
|
{
|
|
|
|
|
$authorizationService = $this->createMock(AuthorizationService::class);
|
|
|
|
|
$authorizationService->expects($this->once())
|
|
|
|
|
->method('authorize')
|
|
|
|
|
->with(OperationsAuthorizationPolicy::ABILITY_ADMIN_JOBS_VIEW, [
|
|
|
|
|
'actor_user_id' => 7,
|
|
|
|
|
'scoped_tenant_id' => 3,
|
|
|
|
|
])
|
|
|
|
|
->willReturn(AuthorizationDecision::allow());
|
|
|
|
|
|
|
|
|
|
$service = new UiAccessService($authorizationService);
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($service->allow(7, OperationsAuthorizationPolicy::ABILITY_ADMIN_JOBS_VIEW, ['scoped_tenant_id' => 3]));
|
|
|
|
|
$this->assertTrue($service->allow(7, OperationsAuthorizationPolicy::ABILITY_ADMIN_JOBS_VIEW, ['scoped_tenant_id' => 3]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testResolveMapSupportsStringAndStructuredDefinition(): void
|
|
|
|
|
{
|
|
|
|
|
$authorizationService = $this->createMock(AuthorizationService::class);
|
|
|
|
|
$authorizationService->expects($this->exactly(2))
|
|
|
|
|
->method('authorize')
|
|
|
|
|
->willReturnCallback(static function (string $ability, array $context): AuthorizationDecision {
|
|
|
|
|
if ($ability === OperationsAuthorizationPolicy::ABILITY_ADMIN_STATS_VIEW) {
|
|
|
|
|
return AuthorizationDecision::allow();
|
|
|
|
|
}
|
|
|
|
|
if ($ability === OperationsAuthorizationPolicy::ABILITY_ADMIN_MAIL_LOG_VIEW
|
|
|
|
|
&& (int) ($context['target_tenant_id'] ?? 0) === 99) {
|
|
|
|
|
return AuthorizationDecision::allow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return AuthorizationDecision::deny(403, 'forbidden');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$service = new UiAccessService($authorizationService);
|
|
|
|
|
$result = $service->resolveMap(11, [
|
|
|
|
|
'stats' => OperationsAuthorizationPolicy::ABILITY_ADMIN_STATS_VIEW,
|
|
|
|
|
'mail_log' => [
|
|
|
|
|
'ability' => OperationsAuthorizationPolicy::ABILITY_ADMIN_MAIL_LOG_VIEW,
|
|
|
|
|
'context' => ['target_tenant_id' => 99],
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertSame([
|
|
|
|
|
'stats' => true,
|
|
|
|
|
'mail_log' => true,
|
|
|
|
|
], $result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testLayoutCapabilitiesExposeExpectedKeys(): void
|
|
|
|
|
{
|
|
|
|
|
$authorizationService = $this->createMock(AuthorizationService::class);
|
|
|
|
|
$authorizationService->method('authorize')->willReturn(AuthorizationDecision::deny(403, 'forbidden'));
|
|
|
|
|
|
|
|
|
|
$service = new UiAccessService($authorizationService);
|
|
|
|
|
$result = $service->layoutCapabilities(5);
|
|
|
|
|
|
|
|
|
|
foreach (array_keys(UiCapabilityMap::LAYOUT) as $key) {
|
|
|
|
|
$this->assertArrayHasKey($key, $result);
|
|
|
|
|
$this->assertFalse($result[$key]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testPageCapabilitiesUsesResolveMapContract(): void
|
|
|
|
|
{
|
|
|
|
|
$authorizationService = $this->createMock(AuthorizationService::class);
|
|
|
|
|
$authorizationService->expects($this->once())
|
|
|
|
|
->method('authorize')
|
|
|
|
|
->with(OperationsAuthorizationPolicy::ABILITY_ADMIN_JOBS_VIEW, [
|
|
|
|
|
'actor_user_id' => 9,
|
|
|
|
|
])
|
|
|
|
|
->willReturn(AuthorizationDecision::allow());
|
|
|
|
|
|
|
|
|
|
$service = new UiAccessService($authorizationService);
|
|
|
|
|
$result = $service->pageCapabilities(9, [
|
|
|
|
|
'can_view_jobs' => OperationsAuthorizationPolicy::ABILITY_ADMIN_JOBS_VIEW,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertSame(['can_view_jobs' => true], $result);
|
|
|
|
|
}
|
|
|
|
|
}
|