<?php

namespace App\Tests\Unit\Service\Access\OptionalsRoles;

use App\Entity\Access\Access;
use App\Entity\Organization\Organization;
use App\Entity\Organization\Parameters;
use App\Enum\Access\FunctionEnum;
use App\Repository\Access\AccessRepository;
use App\Service\Access\OptionalsRoles\CriteriaNotationOptionalRole;
use DateTime;
use PHPUnit\Framework\TestCase;

class CriteriaNotationOptionalRoleTest extends TestCase
{
    private AccessRepository $accessRepository;

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

    /**
     * @see CriteriaNotationOptionalRole::support()
     */
    public function testSupportIsSupported(): void
    {
        $criteriaNotationOptionalRole = $this
            ->getMockBuilder(CriteriaNotationOptionalRole::class)
            ->setConstructorArgs([$this->accessRepository])
            ->setMethodsExcept(['support'])
            ->getMock();

        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
        $parameters->method('getEditCriteriaNotationByAdminOnly')->willReturn(false);

        $organization = $this->getMockBuilder(Organization::class)->getMock();
        $organization->method('getParameters')->willReturn($parameters);

        $access = $this->getMockBuilder(Access::class)->getMock();
        $access->method('getOrganization')->willReturn($organization);

        $this->accessRepository
            ->method('hasGotFunctionAtThisDate')
            ->with($access, FunctionEnum::TEACHER(), self::isInstanceOf(DateTime::class))
            ->willReturn(true);

        $this->assertTrue(
            $criteriaNotationOptionalRole->support($access)
        );
    }

    /**
     * @see CriteriaNotationOptionalRole::support()
     */
    public function testSupportIsNotActiveTeacher(): void
    {
        $criteriaNotationOptionalRole = $this
            ->getMockBuilder(CriteriaNotationOptionalRole::class)
            ->setConstructorArgs([$this->accessRepository])
            ->setMethodsExcept(['support'])
            ->getMock();

        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
        $parameters->method('getEditCriteriaNotationByAdminOnly')->willReturn(false);

        $organization = $this->getMockBuilder(Organization::class)->getMock();
        $organization->method('getParameters')->willReturn($parameters);

        $access = $this->getMockBuilder(Access::class)->getMock();
        $access->method('getOrganization')->willReturn($organization);

        $this->accessRepository
            ->method('hasGotFunctionAtThisDate')
            ->with($access, FunctionEnum::TEACHER(), self::isInstanceOf(DateTime::class))
            ->willReturn(false);

        $this->assertFalse(
            $criteriaNotationOptionalRole->support($access)
        );
    }

    /**
     * @see CriteriaNotationOptionalRole::support()
     */
    public function testSupportIsActiveTeacherButAdminOnly(): void
    {
        $criteriaNotationOptionalRole = $this
            ->getMockBuilder(CriteriaNotationOptionalRole::class)
            ->setConstructorArgs([$this->accessRepository])
            ->setMethodsExcept(['support'])
            ->getMock();

        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
        $parameters->method('getEditCriteriaNotationByAdminOnly')->willReturn(true);

        $organization = $this->getMockBuilder(Organization::class)->getMock();
        $organization->method('getParameters')->willReturn($parameters);

        $access = $this->getMockBuilder(Access::class)->getMock();
        $access->method('getOrganization')->willReturn($organization);

        $this->accessRepository
            ->method('hasGotFunctionAtThisDate')
            ->with($access, FunctionEnum::TEACHER(), self::isInstanceOf(DateTime::class))
            ->willReturn(true);

        $this->assertFalse(
            $criteriaNotationOptionalRole->support($access)
        );
    }

    /**
     * @see CriteriaNotationOptionalRole::getRole()
     */
    public function testGetRole(): void
    {
        $criteriaNotationOptionalRole = $this
            ->getMockBuilder(CriteriaNotationOptionalRole::class)
            ->setConstructorArgs([$this->accessRepository])
            ->setMethodsExcept(['getRole'])
            ->getMock();

        $this->assertEquals("ROLE_CRITERIANOTATION", $criteriaNotationOptionalRole->getRole());
    }
}
