<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Tests\Security\Resolver;

use Chill\MainBundle\Entity\HasScopeInterface;
use Chill\MainBundle\Entity\HasScopesInterface;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Security\Resolver\DefaultScopeResolver;
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
use PHPUnit\Framework\TestCase;

/**
 * @internal
 *
 * @coversNothing
 */
final class ScopeResolverDispatcherTest extends TestCase
{
    private ScopeResolverDispatcher $scopeResolverDispatcher;

    protected function setUp(): void
    {
        $this->scopeResolverDispatcher = new ScopeResolverDispatcher([new DefaultScopeResolver()]);
    }

    public function testHasScopeInterface()
    {
        $scope = new Scope();
        $entity = new class ($scope) implements HasScopeInterface {
            public function __construct(private readonly Scope $scope) {}

            public function getScope()
            {
                return $this->scope;
            }
        };

        $this->assertTrue($this->scopeResolverDispatcher->isConcerned($entity));
        $this->assertSame($scope, $this->scopeResolverDispatcher->resolveScope($entity));
    }

    public function testHasScopesInterface()
    {
        $entity = new class ($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface {
            /**
             * @var Scope[]
             */
            private array $scopes = [];

            public function __construct(Scope $scopeA, Scope $scopeB)
            {
                $this->scopes = [$scopeA, $scopeB];
            }

            public function getScopes(): iterable
            {
                return $this->scopes;
            }
        };

        $this->assertTrue($this->scopeResolverDispatcher->isConcerned($entity));
        $this->assertIsArray($this->scopeResolverDispatcher->resolveScope($entity));
        $this->assertSame($scopeA, $this->scopeResolverDispatcher->resolveScope($entity)[0]);
        $this->assertSame($scopeB, $this->scopeResolverDispatcher->resolveScope($entity)[1]);
    }
}
