<?php

namespace MintyPHP\Tests\Module\Notifications;

use MintyPHP\Module\Notifications\NotificationsAuthorizationPolicy;
use MintyPHP\Service\Access\PermissionService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

final class NotificationsAuthorizationPolicyTest extends TestCase
{
    private PermissionService&MockObject $permissionService;
    private NotificationsAuthorizationPolicy $policy;

    protected function setUp(): void
    {
        $this->permissionService = $this->createMock(PermissionService::class);
        $this->policy = new NotificationsAuthorizationPolicy($this->permissionService);
    }

    public function testSupportsNotificationsAbilityOnly(): void
    {
        self::assertTrue($this->policy->supports(NotificationsAuthorizationPolicy::ABILITY_VIEW));
        self::assertFalse($this->policy->supports('users.view'));
    }

    public function testAuthorizeAllowsUserWithPermission(): void
    {
        $this->permissionService->expects($this->once())
            ->method('userHas')
            ->with(11, NotificationsAuthorizationPolicy::PERMISSION_KEY)
            ->willReturn(true);

        $decision = $this->policy->authorize(NotificationsAuthorizationPolicy::ABILITY_VIEW, [
            'actor_user_id' => 11,
        ]);

        self::assertTrue($decision->isAllowed());
    }

    public function testAuthorizeDeniesWithoutPermission(): void
    {
        $this->permissionService->expects($this->once())
            ->method('userHas')
            ->with(11, NotificationsAuthorizationPolicy::PERMISSION_KEY)
            ->willReturn(false);

        $decision = $this->policy->authorize(NotificationsAuthorizationPolicy::ABILITY_VIEW, [
            'actor_user_id' => 11,
        ]);

        self::assertFalse($decision->isAllowed());
        self::assertSame(403, $decision->status());
    }
}
