<?php
namespace App\Tests\Unit\Service\Network;

use App\Entity\Organization\Organization;
use App\Repository\Network\NetworkOrganizationRepository;
use App\Service\Network\Tree;
use PHPUnit\Framework\TestCase;

class TreeTest extends TestCase
{
    private NetworkOrganizationRepository $networkOrganizationRepository;

    public function setUp():void
    {
        $this->networkOrganizationRepository = $this
                ->getMockBuilder(NetworkOrganizationRepository::class)
                ->disableOriginalConstructor()
                ->getMock();
    }

    /**
     * @see Tree::findAllParentsAndSortByType()
     */
    public function testFindAllParentsAndSortByType():void
    {
        $tree = $this->getMockBuilder(Tree::class)
            ->setConstructorArgs([$this->networkOrganizationRepository])
            ->setMethodsExcept(['findAllParentsAndSortByType'])
            ->getMock();

        $organization = $this->getMockBuilder(Organization::class)->getMock();
        $parent1 = $this->getMockBuilder(Organization::class)->getMock();
        $parent2 = $this->getMockBuilder(Organization::class)->getMock();
        $parents = [$parent1, $parent2];

        $this->networkOrganizationRepository
            ->expects(self::once())
            ->method('findAllParents')
            ->with($organization)
            ->willReturn($parents);

        $tree
            ->expects(self::once())
            ->method('sortByType')
            ->with($parents);

        $tree->findAllParentsAndSortByType($organization);
    }

    /**
     * @see Tree::sortByType()
     */
    public function testSortByType():void
    {
        $tree = $this->getMockBuilder(Tree::class)
            ->setConstructorArgs([$this->networkOrganizationRepository])
            ->setMethodsExcept(['sortByType'])
            ->getMock();

        $organization1 = $this->getMockBuilder(Organization::class)->getMock();
        $organization1->method('getId')->willReturn(2);
        $organization1->method('getPrincipalType')->willReturn('REGIONAL_FEDERATION');

        $organization2 = $this->getMockBuilder(Organization::class)->getMock();
        $organization2->method('getId')->willReturn(3);
        $organization2->method('getPrincipalType')->willReturn('NATIONAL_FEDERATION');

        $organization3 = $this->getMockBuilder(Organization::class)->getMock();
        $organization3->method('getId')->willReturn(4);
        $organization3->method('getPrincipalType')->willReturn('DEPARTEMENTAL_FEDERATION');

        $organizations = [
            $organization2,
            $organization1,
            $organization3
        ];

        $result = $tree->sortByType($organizations);

        $this->assertIsArray($result);
        $this->assertContainsOnlyInstancesOf(Organization::class, $result);
        $this->assertEquals(4, $result[0]->getId());
        $this->assertEquals(2, $result[1]->getId());
        $this->assertEquals(3, $result[2]->getId());
    }
}
