Browse Source

revise tests for Services/Education,Export,Mobyt,Network/*

Olivier Massot 3 years ago
parent
commit
9e735cb9d9

+ 3 - 1
src/Enum/Education/TypeCriteriaEnum.php

@@ -8,10 +8,12 @@ use MyCLabs\Enum\Enum;
 
 /**
  * Type de critère possible pour les notations
+ * @method static WITH_NOTATION()
+ * @method static WITHOUT_NOTATION()
  */
 class TypeCriteriaEnum extends Enum
 {
     private const WITH_NOTATION   = 'WITH_NOTATION';
     private const CUSTOM_NOTATION  = 'CUSTOM_NOTATION';
     private const WITHOUT_NOTATION   = 'WITHOUT_NOTATION';
-}
+}

+ 1 - 0
src/Enum/Network/NetworkEnum.php

@@ -9,6 +9,7 @@ use MyCLabs\Enum\Enum;
  * Liste des réseaux disponibles
  * @method static CMF()
  * @method static FFEC()
+ * @method static CFBF()
  */
 class NetworkEnum extends Enum
 {

+ 6 - 0
src/Enum/Organization/PrincipalTypeEnum.php

@@ -7,6 +7,12 @@ use MyCLabs\Enum\Enum;
 
 /**
  * Types principaux d'une organisation
+ * @method static DELEGATION()
+ * @method static GROUPMENT()
+ * @method static LOCAL_FEDERATION()
+ * @method static DEPARTEMENTAL_FEDERATION()
+ * @method static REGIONAL_FEDERATION()
+ * @method static NATIONAL_FEDERATION()
  */
 class PrincipalTypeEnum extends Enum
 {

+ 2 - 3
src/Service/Cotisation/Utils.php

@@ -21,14 +21,13 @@ class Utils
     const MEMBERSHIP_NOPAYMENT = 517; // Waiting paiement
     const SUBMIT_IN_PROGRESS = 540; // Affiliation in progress
 
-    function __construct(
+    public function __construct(
         private NetworkUtils                     $networkUtils,
         private OrganizationUtils                $organizationUtils,
         private NetworkOrganizationRepository    $networkOrganizationRepository,
         private CotisationApiResourcesRepository $cotisationApiResourcesRepository
     )
-    {
-    }
+    {}
 
     /**
      * Test si l'organisation est un dernier parent ET appartient à la CMF.

+ 27 - 15
src/Service/Education/EducationNotationUtils.php

@@ -8,18 +8,19 @@ use App\Enum\Education\TypeCriteriaEnum;
 use App\Test\Service\Access\EducationNotationUtilsTest;
 
 /**
- * Classe EducationNotationUtils qui contiens les fonctions relatives aux évaluations d'un enseignement
+ * Classe EducationNotationUtils qui contient les fonctions relatives aux évaluations d'un enseignement
  */
 class EducationNotationUtils
 {
     /**
-     * Fonction permettant de retrouver la note calculé par rapport à la note maximale possible définie par la structure
+     * Fonction permettant de retrouver la note calculée par rapport à la note maximale possible définie par la structure
      * @param EducationNotation $educationNotation
      * @return float|null
      * @see EducationNotationUtilsTest::testGetNotationTransformed()
      */
-    public function getNotationTransformed(EducationNotation $educationNotation)
+    public function getNotationTransformed(EducationNotation $educationNotation): ?float
     {
+        /** @noinspection NullPointerExceptionInspection */
         $noteMax = $educationNotation->getEducationStudent()->getAccess()->getOrganization()->getParameters()->getAverage();
         return $this->calculNotationByAMaxNote($educationNotation, $noteMax);
     }
@@ -30,26 +31,37 @@ class EducationNotationUtils
      * @return float|null
      * @see EducationNotationUtilsTest::testGetNotationOriginal()
      */
-    public function getNotationOriginal(EducationNotation $educationNotation)
+    public function getNotationOriginal(EducationNotation $educationNotation): ?float
     {
-        if(!$educationNotation->getCriteriaNotation()) return null;
+        if(!$educationNotation->getCriteriaNotation()) {
+            return null;
+        }
         $noteMax = $educationNotation->getCriteriaNotation()->getNoteMax();
         return $this->calculNotationByAMaxNote($educationNotation, $noteMax);
     }
 
     /**
-     * Effectue un ratio de la note sur 100 à la base pour la cacluler par rapport à la note maximale passée en paramètre.
-     * @param $educationNotation
-     * @param $noteMax
+     * Recalcule une note sur 100 par rapport à la nouvelle note maximale passée en paramètre.
+     *
+     * Les notes sont toutes enregistrées sur 100 dans la DB, cette méthode permet de recalculer la note en fonction
+     * de la note maximale de l'école.
+     *
+     * @param EducationNotation $educationNotation
+     * @param float $noteMax
      * @return float|null
      */
-    private function calculNotationByAMaxNote($educationNotation, $noteMax){
-        if(is_null($educationNotation->getNote())) return null;
-        if(!$educationNotation->getCriteriaNotation()) return null;
-        if($educationNotation->getCriteriaNotation()->getType() !== TypeCriteriaEnum::WITH_NOTATION()->getValue()) return null;
+    protected function calculNotationByAMaxNote(EducationNotation $educationNotation, float $noteMax): ?float
+    {
+        if(
+            is_null($educationNotation->getNote()) ||
+            !$educationNotation->getCriteriaNotation() ||
+            $educationNotation->getCriteriaNotation()->getType() !== TypeCriteriaEnum::WITH_NOTATION()->getValue()
+        ) {
+            return null;
+        }
 
-        $note = (float)(($educationNotation->getNote() * $noteMax) / 100);
+        $note = ($educationNotation->getNote() * $noteMax) / 100;
 
-        return round ( $note , 2 );
+        return round ( (float)$note , 2 );
     }
-}
+}

+ 1 - 1
src/Service/Export/Encoder/PdfEncoder.php

@@ -52,7 +52,7 @@ class PdfEncoder implements EncoderInterface
      */
     public function encode(string $html, array $options = []): string
     {
-        $options = array_merge($this->defaultOptions, $options);
+        $options = array_merge($this->getDefaultOptions(), $options);
 
         return $this->knpSnappy->getOutputFromHtml($html, $options);
     }

+ 3 - 3
src/Service/Export/LicenceCmfExporter.php

@@ -22,7 +22,7 @@ class LicenceCmfExporter extends BaseExporter
     /**
      * La couleur de la carte de licence change chaque année, de manière cyclique
      */
-    public const LICENCE_CMF_COLOR_START_YEAR = "2020";
+    public const LICENCE_CMF_COLOR_START_YEAR = 2020;
     public const LICENCE_CMF_COLOR = [0 => '931572', 1 => 'C2981A', 2 =>  '003882', 3 =>  '27AAE1', 4 =>  '2BB673'];
 
     public function __construct(
@@ -40,7 +40,7 @@ class LicenceCmfExporter extends BaseExporter
     {
         $organization = $this->accessRepository->find($exportRequest->getRequesterId())?->getOrganization();
         if ($organization === null) {
-            throw new \RuntimeException('Unable to dermin the organization of the curent user; abort.');
+            throw new \RuntimeException('Unable to determine the organization of the curent user; abort.');
         }
 
         $licenceCmf = new LicenceCmf();
@@ -114,7 +114,7 @@ class LicenceCmfExporter extends BaseExporter
      * @return string
      */
     protected function getLicenceColor(int $year): string {
-        if (!(self::LICENCE_CMF_COLOR_START_YEAR > $year)) {
+        if (!($year > self::LICENCE_CMF_COLOR_START_YEAR)) {
             return self::LICENCE_CMF_COLOR[0];
         }
         return self::LICENCE_CMF_COLOR[($year - self::LICENCE_CMF_COLOR_START_YEAR) % count(self::LICENCE_CMF_COLOR)];

+ 19 - 8
src/Service/Mobyt/MobytService.php

@@ -17,8 +17,9 @@ class MobytService extends ApiRequestService
     private string $userId;
     private string $sessionKey;
 
+    /** @noinspection SenselessProxyMethodInspection */
     #[Pure]
-    function __construct(
+    public function __construct(
         HttpClientInterface $mobyt_client
     )
     {
@@ -32,27 +33,37 @@ class MobytService extends ApiRequestService
      * @param string $password
      * @return void
      */
-    private function connect(string $login, string $password): void
+    protected function connect(string $login, string $password): void
     {
         $responseContent = $this->getContent('login', ['username' => $login, 'password' => $password]);
-        list($this->userId, $this->sessionKey) = explode(';', $responseContent);
+        [$this->userId, $this->sessionKey] = explode(';', $responseContent);
+    }
+
+    protected function getUserId(): string
+    {
+        return $this->userId;
+    }
+
+    protected function getSessionKey(): string
+    {
+        return $this->sessionKey;
     }
 
     /**
-     * Get a mobyt user status by its opentalent organization id
+     * Get a mobyt user status by its opentalent organization login and password
      *
-     * @param int $organizationId
      * @param string $login
      * @param string $password
      * @return array
+     * @throws \JsonException
      */
-    public function getUserStatus(int $organizationId, string $login, string $password): array {
+    public function getUserStatus(string $login, string $password): array {
         $this->connect($login, $password);
         return $this->getJsonContent(
             'status',
             ['getMoney' => 'true', 'typeAliases' => 'true'],
             [
-                'headers' => [ 'user_key' => $this->userId, 'Session_key' => $this->sessionKey ]
+                'headers' => [ 'user_key' => $this->getUserId(), 'Session_key' => $this->getSessionKey() ]
             ]
         );
     }
@@ -69,7 +80,7 @@ class MobytService extends ApiRequestService
     {
         try{
             $this->connect($login, $password);
-        }catch (NotFoundHttpException $exception){
+        }catch (NotFoundHttpException){
             return false;
         }
         return true;

+ 8 - 1
src/Service/Mobyt/MobytUserStatusCreator.php

@@ -12,6 +12,13 @@ class MobytUserStatusCreator
         private OrganizationRepository $organizationRepository,
     ) {}
 
+    /**
+     * Retrieve the status of the user from the Mobyt Api (via MobytService)
+     *
+     * @param int $organizationId
+     * @return MobytUserStatus
+     * @throws \JsonException
+     */
     public function getUserStatus(int $organizationId): MobytUserStatus {
         $userStatus = new MobytUserStatus();
         $userStatus->setOrganizationId($organizationId);
@@ -24,7 +31,7 @@ class MobytUserStatusCreator
             return $userStatus;
         }
 
-        $userStatusData = $this->mobytService->getUserStatus($organizationId, $mobytLogin, $mobytPassword);
+        $userStatusData = $this->mobytService->getUserStatus($mobytLogin, $mobytPassword);
         $userStatus->setActive(true);
         $userStatus->setMoney($userStatusData['money']);
 

+ 3 - 3
src/Service/Network/Tree.php

@@ -29,7 +29,7 @@ class Tree
 
     /**
      * Trie les organisations par rapport à leur type principal :
-     * DELEGATION, GROUPMENT,  LOCAL_FEDERATION, DEPARTEMENTAL_FEDERATION, REGIONAL_FEDERATION, NATIONAL_FEDERATION
+     * DELEGATION, GROUPMENT, LOCAL_FEDERATION, DEPARTEMENTAL_FEDERATION, REGIONAL_FEDERATION, NATIONAL_FEDERATION
      * @param array $organizations
      * @return array
      * @see TreeTest::testSortByType()
@@ -44,10 +44,10 @@ class Tree
             PrincipalTypeEnum::NATIONAL_FEDERATION()
         ];
 
-        usort($organizations, function(Organization $organization1, Organization $organization2) use($typeOrder){
+        usort($organizations, static function(Organization $organization1, Organization $organization2) use($typeOrder) {
             return array_keys($typeOrder, $organization1->getPrincipalType()) <=> array_keys($typeOrder, $organization2->getPrincipalType());
         });
 
         return $organizations;
     }
-}
+}

+ 8 - 8
src/Service/Network/Utils.php

@@ -15,7 +15,6 @@ use App\Tests\Service\Network\UtilsTest;
  */
 class Utils
 {
-    // TODO: Renommer en NetworkUtils
     /**
      * Test si l'organisation appartient au réseau de la CMF
      * @param Organization $organization
@@ -23,7 +22,7 @@ class Utils
      * @see UtilsTest::testIsCmf()
      */
     public function isCMF(Organization $organization): bool {
-        return $this->isOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF());
+        return $this->doesOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF());
     }
 
     /**
@@ -33,23 +32,24 @@ class Utils
      * @see UtilsTest::testIsCmfAndActiveNow()
      */
     public function isCMFAndActiveNow(Organization $organization): bool {
-        return $this->isOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF(), true);
+        return $this->doesOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF(), true);
     }
 
     /**
-     * Test si l'organisation appartient à un réseau
+     * Teste si l'organisation appartient à un réseau
+     *
      * @param Organization $organization
      * @param NetworkEnum $network  id du réseau
-     * @param bool $activeNow  si true, on test en plus l'activité aujourd'hui
+     * @param bool $activeNow  si true, on teste en plus l'activité aujourd'hui
      * @return boolean
      * @see UtilsTest::testIsOrganizationBelongToTheNetwork()
      */
-    public function isOrganizationBelongToTheNetwork(Organization $organization, NetworkEnum $network, ?bool $activeNow = false): bool {
+    public function doesOrganizationBelongToTheNetwork(Organization $organization, NetworkEnum $network, ?bool $activeNow = false): bool {
         $networksOrganizations = $organization->getNetworkOrganizations();
         /** @var NetworkOrganization $networksOrganization */
         foreach ($networksOrganizations as $networksOrganization) {
             if ($networksOrganization->getNetwork()->getId() === $network->getValue()) {
-                return $activeNow ? $this->doesNetworkOrganizationIsActiveNow($networksOrganization) : true;
+                return !$activeNow || $this->isNetworkOrganizationActiveNow($networksOrganization);
             }
         }
         return false;
@@ -61,7 +61,7 @@ class Utils
      * @return bool
      * @throws \Exception
      */
-    public function doesNetworkOrganizationIsActiveNow(NetworkOrganization $networksOrganization): bool{
+    public function isNetworkOrganizationActiveNow(NetworkOrganization $networksOrganization): bool{
         return DatesUtils::isIntervalIsValidNow($networksOrganization->getStartDate(), $networksOrganization->getEndDate());
     }
 }

+ 169 - 32
tests/Service/Education/EducationNotationUtilsTest.php

@@ -12,54 +12,191 @@ use App\Enum\Education\TypeCriteriaEnum;
 use App\Service\Education\EducationNotationUtils;
 use PHPUnit\Framework\TestCase;
 
+class TestableEducationNotationUtils extends EducationNotationUtils {
+    public function calculNotationByAMaxNote(EducationNotation $educationNotation, float $noteMax): ?float {
+        return parent::calculNotationByAMaxNote($educationNotation, $noteMax);
+    }
+}
+
 class EducationNotationUtilsTest extends TestCase
 {
-    private EducationNotationUtils $educationNotationUtils;
-    private EducationNotation $educationNotation;
-
-    public function setUp():void
+    /**
+     * @see EducationNotationUtils::getNotationTransformed()
+     */
+    public function testGetNotationTransformed(): void
     {
-        $this->educationNotationUtils = new EducationNotationUtils();
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['getNotationTransformed'])
+            ->getMock();
+
+        $noteMax = 80;
 
-        $criteriaNotation = new CriteriaNotation();
-        $criteriaNotation->setType(TypeCriteriaEnum::WITH_NOTATION()->getValue());
-        $criteriaNotation->setNoteMax(50);
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getAverage')->willReturn($noteMax);
 
-        $this->educationNotation = new EducationNotation();
-        $this->educationNotation->setCriteriaNotation($criteriaNotation);
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $access = $this->getMockBuilder(Access::class)->getMock();
+        $access->method('getOrganization')->willReturn($organization);
+
+        $educationStudent = $this->getMockBuilder(EducationStudent::class)->getMock();
+        $educationStudent->method('getAccess')->willReturn($access);
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->method('getEducationStudent')->willReturn($educationStudent);
+
+        $educationNotationUtils->expects(self::once())->method('calculNotationByAMaxNote')->with($educationNotation, $noteMax);
+
+        $educationNotationUtils->getNotationTransformed($educationNotation);
     }
 
     /**
-     * @see EducationNotationUtils::getNotationTransformed()
+     * @see EducationNotationUtils::getNotationOriginal()
      */
-    public function testGetNotationTransformed()
+    public function testGetNotationOriginal(): void
     {
-        $parameters = new Parameters();
-        $parameters->setAverage(80);
-        $organization = new Organization();
-        $organization->setParameters($parameters);
-        $access = new Access();
-        $access->setOrganization($organization);
-        $educationStudent = new EducationStudent();
-        $educationStudent->setAccess($access);
-
-        $this->educationNotation->setEducationStudent($educationStudent);
-        $this->educationNotation->setNote(100);
-        $this->assertEquals(80, $this->educationNotationUtils->getNotationTransformed($this->educationNotation));
-
-        $this->educationNotation->setNote(50);
-        $this->assertEquals(40, $this->educationNotationUtils->getNotationTransformed($this->educationNotation));
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['getNotationOriginal'])
+            ->getMock();
+
+        $noteMax = 40;
+
+        $criteriaNotation = $this->getMockBuilder(CriteriaNotation::class)->getMock();
+        $criteriaNotation->method('getNoteMax')->willReturn($noteMax);
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->method('getCriteriaNotation')->willReturn($criteriaNotation);
+
+        $educationNotationUtils->expects(self::once())->method('calculNotationByAMaxNote')->with($educationNotation, $noteMax);
+
+        $educationNotationUtils->getNotationOriginal($educationNotation);
     }
 
     /**
      * @see EducationNotationUtils::getNotationOriginal()
      */
-    public function testGetNotationOriginal()
+    public function testGetNotationOriginalWithoutCriteria(): void
+    {
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['getNotationOriginal'])
+            ->getMock();
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->method('getCriteriaNotation')->willReturn(null);
+
+        $educationNotationUtils->expects(self::never())->method('calculNotationByAMaxNote');
+
+        $this->assertNull($educationNotationUtils->getNotationOriginal($educationNotation));
+    }
+
+    public function testCalculNotationByAMaxNote(): void
+    {
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['calculNotationByAMaxNote'])
+            ->getMock();
+
+        $note1 = 60.0;
+        $note2 = 0.0;
+        $note3 = 100.0;
+        $noteMax = 20;
+
+        $criteriaNotation = $this->getMockBuilder(CriteriaNotation::class)->getMock();
+        $criteriaNotation->method('getType')->willReturn(TypeCriteriaEnum::WITH_NOTATION()->getValue());
+
+        $educationNotation1 = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation1->method('getCriteriaNotation')->willReturn($criteriaNotation);
+        $educationNotation1->method('getNote')->willReturn($note1);
+
+        $educationNotation2 = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation2->method('getCriteriaNotation')->willReturn($criteriaNotation);
+        $educationNotation2->method('getNote')->willReturn($note2);
+
+        $educationNotation3 = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation3->method('getCriteriaNotation')->willReturn($criteriaNotation);
+        $educationNotation3->method('getNote')->willReturn($note3);
+
+        $this->assertEquals(
+            12,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation1, $noteMax)
+        );
+
+        $this->assertEquals(
+            0,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation2, $noteMax)
+        );
+
+        $this->assertEquals(
+            20,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation3, $noteMax)
+        );
+    }
+
+    /**
+     * If $educationNotation has no note, it should return null
+     */
+    public function testCalculNotationByAMaxNoteWithoutNote(): void
     {
-        $this->educationNotation->setNote(100);
-        $this->assertEquals(50, $this->educationNotationUtils->getNotationOriginal($this->educationNotation));
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['calculNotationByAMaxNote'])
+            ->getMock();
+
+        $note = null;
+        $noteMax = 20;
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->expects(self::atLeastOnce())->method('getNote')->willReturn($note);
+
+        $this->assertEquals(
+            null,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation, $noteMax)
+        );
+    }
+
+    /**
+     * If $educationNotation has no criteriaNotation, it should return null
+     */
+    public function testCalculNotationByAMaxNoteWithoutCriteria(): void
+    {
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['calculNotationByAMaxNote'])
+            ->getMock();
+
+        $note = 50.0;
+        $noteMax = 20;
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->expects(self::atLeastOnce())->method('getNote')->willReturn($note);
+        $educationNotation->expects(self::atLeastOnce())->method('getCriteriaNotation')->willReturn(null);
+
+        $this->assertEquals(
+            null,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation, $noteMax)
+        );
+    }
+
+    /**
+     * If $criteriaNotation has WITHOUT_NOTATION type, this should return null
+     */
+    public function testCalculNotationByAMaxNoteWithoutNotation(): void
+    {
+        $educationNotationUtils = $this->getMockBuilder(TestableEducationNotationUtils::class)
+            ->setMethodsExcept(['calculNotationByAMaxNote'])
+            ->getMock();
+
+        $note = 60.0;
+        $noteMax = 20;
+
+        $criteriaNotation = $this->getMockBuilder(CriteriaNotation::class)->getMock();
+        $criteriaNotation->expects(self::once())->method('getType')->willReturn(TypeCriteriaEnum::WITHOUT_NOTATION()->getValue());
+
+        $educationNotation = $this->getMockBuilder(EducationNotation::class)->getMock();
+        $educationNotation->expects(self::atLeastOnce())->method('getNote')->willReturn($note);
+        $educationNotation->expects(self::atLeastOnce())->method('getCriteriaNotation')->willReturn($criteriaNotation);
 
-        $this->educationNotation->setNote(50);
-        $this->assertEquals(25, $this->educationNotationUtils->getNotationOriginal($this->educationNotation));
+        $this->assertEquals(
+            null,
+            $educationNotationUtils->calculNotationByAMaxNote($educationNotation, $noteMax)
+        );
     }
 }

+ 35 - 16
tests/Service/Export/Encoder/PdfEncoderTest.php

@@ -2,38 +2,57 @@
 
 use App\Service\Export\Encoder\PdfEncoder;
 use Knp\Snappy\Pdf;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
 
 class PdfEncoderTest extends TestCase
 {
-    public function testSupport() {
-        $mocker = $this->getMockBuilder(Pdf::class);
-        $knpSnappy = $mocker->getMock();
-        $encoder = new PdfEncoder($knpSnappy);
+    private MockObject | Pdf $knpSnappy;
+
+    public function setUp(): void
+    {
+        $this->knpSnappy = $this->getMockBuilder(Pdf::class)->getMock();
+    }
+
+    public function testSupport(): void
+    {
+        $encoder = $this->getMockBuilder(PdfEncoder::class)
+            ->setConstructorArgs([$this->knpSnappy])
+            ->setMethodsExcept(['support'])
+            ->getMock();
 
         $this->assertTrue($encoder->support('pdf'));
         $this->assertFalse($encoder->support('txt'));
     }
 
-    public function testGetDefaultOptions() {
-        $mocker = $this->getMockBuilder(Pdf::class);
-        $knpSnappy = $mocker->getMock();
-        $encoder = new PdfEncoder($knpSnappy);
+    public function testGetDefaultOptions(): void
+    {
+        $encoder = $this->getMockBuilder(PdfEncoder::class)
+            ->setConstructorArgs([$this->knpSnappy])
+            ->setMethodsExcept(['getDefaultOptions'])
+            ->getMock();
 
         $this->assertIsArray($encoder->getDefaultOptions());
     }
 
-    public function testEncode() {
-        $mocker = $this->getMockBuilder(Pdf::class);
-        $knpSnappy = $mocker->getMock();
-        $knpSnappy
+    public function testEncode(): void
+    {
+        $encoder = $this->getMockBuilder(PdfEncoder::class)
+            ->setConstructorArgs([$this->knpSnappy])
+            ->setMethodsExcept(['encode'])
+            ->getMock();
+
+        $encoder->method('getDefaultOptions')->willReturn(['defaultOption' => 1]);
+
+        $this->knpSnappy
             ->expects(self::once())
             ->method('getOutputFromHtml')
-            ->with('<div>content</div>')
+            ->with('<div>content</div>', ['defaultOption' => 1, 'additionalOption' => 2])
             ->willReturn('%%encoded%%');
 
-        $encoder = new PdfEncoder($knpSnappy);
-
-        $this->assertEquals('%%encoded%%', $encoder->encode('<div>content</div>'));
+        $this->assertEquals(
+            '%%encoded%%',
+            $encoder->encode('<div>content</div>', ['additionalOption' => 2])
+        );
     }
 }

+ 134 - 59
tests/Service/Export/LicenceCmfExporterTest.php

@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection PhpUnhandledExceptionInspection */
 
 use App\ApiResources\Export\ExportRequest;
 use App\ApiResources\Export\LicenceCmf\LicenceCmfOrganizationER;
@@ -13,37 +13,43 @@ use App\Repository\Access\AccessRepository;
 use App\Repository\Organization\OrganizationRepository;
 use App\Service\Export\Encoder\PdfEncoder;
 use App\Service\Export\LicenceCmfExporter;
+use App\Service\Export\Model\ExportModelInterface;
+use App\Service\Export\Model\LicenceCmf;
+use App\Service\Export\Model\LicenceCmfCollection;
 use App\Service\ServiceIterator\EncoderIterator;
 use App\Service\Storage\TemporaryFileStorage;
 use App\Service\Storage\UploadStorage;
+use App\Tests\TestToolsTrait;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\EntityManagerInterface;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
 use Twig\Environment;
 
 class LicenceCmfExporterTest extends TestCase
 {
-    private mixed $exportRequest;
-    private mixed $accessRepo;
-    private mixed $twig;
-    private mixed $encoderIterator;
-    private mixed $em;
-    private mixed $storage;
-    private mixed $organizationRepo;
-    private mixed $uploadStorage;
-    private mixed $access;
-    private mixed $organization;
-    private mixed $cmf;
-    private mixed $networkOrgs;
-    private mixed $collection;
-    private mixed $parent;
-    private mixed $logo;
-    private mixed $presidentAccess;
-    private mixed $president;
-    private mixed $cmfParameters;
-    private mixed $qrCode;
-    private LicenceCmfExporter $exporter;
-    private mixed $encoder;
+    use TestToolsTrait;
+
+    private MockObject | LicenceCmfOrganizationER $exportRequest;
+    private MockObject | AccessRepository $accessRepo;
+    private MockObject | Environment $twig;
+    private MockObject | EncoderIterator $encoderIterator;
+    private MockObject | EntityManagerInterface $em;
+    private MockObject | TemporaryFileStorage $storage;
+    private MockObject | OrganizationRepository $organizationRepo;
+    private MockObject | UploadStorage $uploadStorage;
+    private MockObject | Access $access;
+    private MockObject | Organization $organization;
+    private MockObject | Organization $cmf;
+    private MockObject | NetworkOrganization $networkOrgs;
+    private MockObject | Collection $collection;
+    private MockObject | Organization $parent;
+    private MockObject | File $logo;
+    private MockObject | Access $presidentAccess;
+    private MockObject | Person $president;
+    private MockObject | Parameters $cmfParameters;
+    private MockObject | File $qrCode;
+    private MockObject | PdfEncoder $encoder;
 
     public function setUp(): void {
         $this->exportRequest = $this->getMockBuilder(LicenceCmfOrganizationER::class)->getMock();
@@ -66,20 +72,33 @@ class LicenceCmfExporterTest extends TestCase
         $this->president = $this->getMockBuilder(Person::class)->getMock();
         $this->cmfParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $this->qrCode = $this->getMockBuilder(File::class)->getMock();
+    }
 
-        $this->exporter = new LicenceCmfExporter($this->organizationRepo, $this->uploadStorage);
-        $this->exporter->setAccessRepository($this->accessRepo);
-        $this->exporter->setTwig($this->twig);
-        $this->exporter->setEncoderIterator($this->encoderIterator);
-        $this->exporter->setEntityManager($this->em);
-        $this->exporter->setStorage($this->storage);
+    private function makeExporterMock(string $methodUnderTest): LicenceCmfExporter | MockObject
+    {
+        $exporter = $this->getMockBuilder(LicenceCmfExporter::class)
+            ->setConstructorArgs([$this->organizationRepo, $this->uploadStorage])
+            ->setMethodsExcept(['setAccessRepository', 'setTwig', 'setEncoderIterator',
+                'setEntityManager', 'setEntityManager', 'setStorage', $methodUnderTest])
+            ->getMock();
+
+        $exporter->setAccessRepository($this->accessRepo);
+        $exporter->setTwig($this->twig);
+        $exporter->setEncoderIterator($this->encoderIterator);
+        $exporter->setEntityManager($this->em);
+        $exporter->setStorage($this->storage);
+
+        return $exporter;
     }
 
-    public function testSupport() {
+    public function testSupport(): void
+    {
+        $exporter = $this->makeExporterMock('support');
+
         $unsupportedExportRequest = $this->getMockBuilder(ExportRequest::class)->disableOriginalConstructor()->getMock();
 
-        $this->assertTrue($this->exporter->support($this->exportRequest));
-        $this->assertFalse($this->exporter->support($unsupportedExportRequest));
+        $this->assertTrue($exporter->support($this->exportRequest));
+        $this->assertFalse($exporter->support($unsupportedExportRequest));
     }
 
     private function prepareModelBuilding() {
@@ -115,14 +134,14 @@ class LicenceCmfExporterTest extends TestCase
         $this->organizationRepo->expects(self::once())->method('find')->with(12097)->willReturn($this->cmf);
     }
 
-    public function testBuildModel() {
+    public function testBuildModel(): void
+    {
+        $exporter = $this->makeExporterMock('buildModel');
+
         $this->prepareModelBuilding();
 
-        $reflection = new ReflectionClass('App\Service\Export\LicenceCmfExporter');
-        $this->buildModelMethod = $reflection->getMethod('buildModel');
-        $this->buildModelMethod->setAccessible(true);
+        $modelCollection = $this->invokeMethod($exporter, 'buildModel', [$this->exportRequest]);
 
-        $modelCollection = $this->buildModelMethod->invokeArgs($this->exporter, [$this->exportRequest]);
         $licence = $modelCollection->getLicences()[0];
 
         $this->assertEquals('my_network', $licence->getFederationName());
@@ -133,35 +152,91 @@ class LicenceCmfExporterTest extends TestCase
         $this->assertEquals('http:://foo.bar/1', $licence->getLogoUri());
     }
 
-    public function testExport() {
-        $this->prepareModelBuilding();
+    /**
+     * If the organization cannot be determined from the exportRequest author, an error should be thrown
+     */
+    public function testBuildModelWithoutOrganization(): void
+    {
+        $exporter = $this->makeExporterMock('buildModel');
 
-        $this->twig
-            ->expects(self::once())
-            ->method('render')
-            ->with('@templates/export/licence_cmf.html.twig')
-            ->willReturn('<div>rendered html</div>');
+        $this->exportRequest->method('getRequesterId')->willReturn(1);
+        $this->accessRepo->method('find')->with(1)->willReturn(null);
 
-        $this->encoderIterator
-            ->expects(self::once())
-            ->method('getEncoderFor')
-            ->with('pdf')
-            ->willReturn($this->encoder);
+        $this->expectException(RuntimeException::class);
 
-        $this->encoder
-            ->expects(self::once())
-            ->method('encode')
-            ->with('<div>rendered html</div>')
-            ->willReturn('%%encoded%%');
+        $this->invokeMethod($exporter, 'buildModel', [$this->exportRequest]);
+    }
 
-        $this->storage
-            ->expects(self::once())
-            ->method('write')
-            ->willReturn('/temp/abcd/licence_cmf_2020.pdf');
+    public function testGetFileBasename(): void
+    {
+        $exporter = $this->makeExporterMock('getFileBasename');
+
+        $licence = $this->getMockBuilder(LicenceCmf::class)->getMock();
+        $licence->method('getYear')->willReturn(2020);
+
+        $model = $this->getMockBuilder(LicenceCmfCollection::class)->getMock();
+        $model->method('getLicences')->willReturn([$licence]);
+
+        $result = $this->invokeMethod($exporter, 'getFileBasename', [$model]);
 
-        $file = $this->exporter->export($this->exportRequest);
+        $this->assertEquals(
+            'licence_cmf_2020.pdf',
+            $result
+        );
+    }
+
+    public function testGetFileType(): void
+    {
+        $exporter = $this->makeExporterMock('getFileType');
 
-        $this->assertMatchesRegularExpression('/licence_cmf_\d{4}.pdf/', $file->getName());
+        $this->assertEquals(
+            'LICENCE_CMF',
+            $this->invokeMethod($exporter, 'getFileType')
+        );
     }
 
+    /**
+     * Given year is before the start year, first color is used
+     */
+    public function testGetLicenceColorPastYear(): void
+    {
+        $exporter = $this->makeExporterMock('getLicenceColor');
+
+        $year = LicenceCmfExporter::LICENCE_CMF_COLOR_START_YEAR - 10;
+
+        $this->assertEquals(
+            LicenceCmfExporter::LICENCE_CMF_COLOR[0],
+            $this->invokeMethod($exporter, 'getLicenceColor', [$year])
+        );
+    }
+
+    /**
+     * Given year is within the 5 first years
+     */
+    public function testGetLicenceColorFirstYears(): void
+    {
+        $exporter = $this->makeExporterMock('getLicenceColor');
+
+        $year = LicenceCmfExporter::LICENCE_CMF_COLOR_START_YEAR + 3;
+
+        $this->assertEquals(
+            LicenceCmfExporter::LICENCE_CMF_COLOR[3],
+            $this->invokeMethod($exporter, 'getLicenceColor', [$year])
+        );
+    }
+
+    /**
+     * Given year is beyond the 5 first years
+     */
+    public function testGetLicenceColorNExtYears(): void
+    {
+        $exporter = $this->makeExporterMock('getLicenceColor');
+
+        $year = LicenceCmfExporter::LICENCE_CMF_COLOR_START_YEAR + 8;
+
+        $this->assertEquals(
+            LicenceCmfExporter::LICENCE_CMF_COLOR[3],
+            $this->invokeMethod($exporter, 'getLicenceColor', [$year])
+        );
+    }
 }

+ 76 - 56
tests/Service/Mobyt/MobytServiceTest.php

@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection PhpUnhandledExceptionInspection */
 
 namespace App\Tests\Service\Mobyt;
 
@@ -8,101 +8,121 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Symfony\Contracts\HttpClient\HttpClientInterface;
 use Symfony\Contracts\HttpClient\ResponseInterface;
 
+class TestableMobytService extends MobytService {
+    public function connect(string $login, string $password): void { parent::connect($login, $password); }
+    public function getUserId(): string { return parent::getUserId(); }
+    public function getSessionKey(): string { return parent::getSessionKey(); }
+}
+
 class MobytServiceTest extends TestCase
 {
     private HttpClientInterface $client;
-    private MobytService $mobytService;
 
     public function setUp():void
     {
         $this->client = $this->getMockBuilder(HttpClientInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-
-        $this->mobytService = new MobytService($this->client);
-    }
-
-    private function getContentFromFixture(string $filename): string {
-        $filepath = dirname(__FILE__) . '/fixtures/' . $filename;
-        return file_get_contents($filepath);
     }
 
     /**
      * @see MobytService::getUserStatus()
      */
-    public function testGetUserStatus(): void {
+    public function testConnect(): void {
 
-        // Mock the response that will be returned by the connection request
-        $connectResponse = $this->getMockBuilder(ResponseInterface::class)
-            ->disableOriginalConstructor()
+        $mobytService = $this->getMockBuilder(TestableMobytService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['connect', 'getUserId', 'getSessionKey'])
             ->getMock();
-        $connectResponse->method('getContent')->willReturn('userId;sessionKey');
 
-        // Mock the response that will be returned by the user_status request
-        $responseContent = $this->getContentFromFixture('user_status.json');
-        $response = $this->getMockBuilder(ResponseInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $response->method('getContent')->willReturn($responseContent);
+        $login = 'foo';
+        $password = 'bar';
 
-        $this->client
-            ->method('request')
-            ->withConsecutive(
-                ["GET", "login?username=user&password=pwd"],
-                ["GET", "status?getMoney=true&typeAliases=true", ['headers' => [ 'user_key' => 'userId', 'Session_key' => 'sessionKey' ]]]
+        $mobytService
+            ->expects(self::once())
+            ->method('getContent')
+            ->with(
+                'login',
+                ['username' => $login, 'password' => $password]
             )
-            ->willReturnOnConsecutiveCalls(
-                $connectResponse,
-                $response
-            );
+            ->willReturn('123;456');
+
+        $mobytService->connect($login, $password);
 
-        $data = $this->mobytService->getUserStatus(1, 'user', 'pwd');
+        $this->assertEquals(
+            '123',
+            $mobytService->getUserId()
+        );
 
         $this->assertEquals(
-            $data['money'],
-            33.0
+            '456',
+            $mobytService->getSessionKey()
         );
     }
 
     /**
-     * @see MobytService::hasCredentialsCorrect()
+     * @see MobytService::getUserStatus()
      */
-    public function testHasCredentialsCorrect(): void {
+    public function testGetUserStatus(): void {
 
-        // Mock the response that will be returned by the connection request
-        $connectResponse = $this->getMockBuilder(ResponseInterface::class)
-            ->disableOriginalConstructor()
+        $mobytService = $this->getMockBuilder(TestableMobytService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['getUserStatus'])
             ->getMock();
-        $connectResponse->method('getContent')->willReturn('userId;sessionKey');
 
-        $this->client
-            ->method('request')
-            ->with("GET", "login?username=user&password=pwd")
-            ->willReturnOnConsecutiveCalls(
-                $connectResponse
+        $login = 'foo';
+        $password = 'bar';
+
+        $mobytService->expects(self::once())->method('connect')->with($login, $password);
+
+        $mobytService->method('getUserId')->willReturn('123');
+        $mobytService->method('getSessionKey')->willReturn('456');
+
+        $mobytService
+            ->expects(self::once())
+            ->method('getJsonContent')
+            ->with(
+                'status',
+                ['getMoney' => 'true', 'typeAliases' => 'true'],
+                [
+                    'headers' => [ 'user_key' => '123', 'Session_key' => '456' ]
+                ]
             );
 
-        $this->assertTrue($this->mobytService->hasCredentialsCorrect('user', 'pwd'));
+        $mobytService->getUserStatus($login, $password);
     }
 
     /**
      * @see MobytService::hasCredentialsCorrect()
      */
-    public function testHasCredentialsUnCorrect(): void {
+    public function testHasCredentialsCorrect(): void {
+        $mobytService = $this->getMockBuilder(TestableMobytService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['hasCredentialsCorrect'])
+            ->getMock();
 
-        // Mock the response that will be returned by the connection request
-        $connectResponse = $this->getMockBuilder(ResponseInterface::class)
-            ->disableOriginalConstructor()
+        $login = 'foo';
+        $password = 'bar';
+
+        $mobytService->expects(self::once())->method('connect')->with($login, $password);
+
+        $this->assertTrue($mobytService->hasCredentialsCorrect($login, $password));
+    }
+
+    /**
+     * @see MobytService::hasCredentialsCorrect()
+     */
+    public function testHasCredentialsNotCorrect(): void {
+        $mobytService = $this->getMockBuilder(TestableMobytService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['hasCredentialsCorrect'])
             ->getMock();
-        $connectResponse->method('getContent')->willThrowException(new NotFoundHttpException());
 
-        $this->client
-            ->method('request')
-            ->with("GET", "login?username=user&password=pwd")
-            ->willReturnOnConsecutiveCalls(
-                $connectResponse
-            );
+        $login = 'foo';
+        $password = 'bar';
+
+        $mobytService->expects(self::once())->method('connect')->with($login, $password)->willThrowException(new NotFoundHttpException());
 
-        $this->assertFalse($this->mobytService->hasCredentialsCorrect('user', 'pwd'));
+        $this->assertFalse($mobytService->hasCredentialsCorrect($login, $password));
     }
 }

+ 26 - 20
tests/Service/Mobyt/MobytUserStatusCreatorTest.php

@@ -13,7 +13,6 @@ class MobytUserStatusCreatorTest extends TestCase
 {
     private MobytService $mobytService;
     private OrganizationRepository $organizationRepository;
-    private MobytUserStatusCreator $mobytUserStatusCreator;
 
     public function setUp(): void {
         $this->mobytService = $this->getMockBuilder(MobytService::class)
@@ -23,41 +22,48 @@ class MobytUserStatusCreatorTest extends TestCase
         $this->organizationRepository = $this->getMockBuilder(OrganizationRepository::class)
             ->disableOriginalConstructor()
             ->getMock();
-
-        $this->mobytUserStatusCreator = new MobytUserStatusCreator(
-            $this->mobytService,
-            $this->organizationRepository
-        );
     }
 
-    private function getJsonContentFromFixture(string $filename): array {
-        $filepath = dirname(__FILE__) . '/fixtures/' . $filename;
-        return json_decode(file_get_contents($filepath), true);
-    }
+    public function testGetUserStatus(): void
+    {
+        $mobytUserStatusCreator = $this->getMockBuilder(MobytUserStatusCreator::class)
+            ->setConstructorArgs([$this->mobytService, $this->organizationRepository])
+            ->setMethodsExcept(['getUserStatus'])
+            ->getMock();
 
-    public function testGetUserStatus() {
-        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
-        $parameters->expects($this->once())->method('getUsernameSMS')->willReturn('user');
-        $parameters->expects($this->once())->method('getPasswordSMS')->willReturn('pwd');
+        $organizationId = 123;
+        $mobytLogin = 'foo';
+        $mobytPassword = 'bar';
 
         $organization = $this->getMockBuilder(Organization::class)->getMock();
-        $organization->expects($this->once())->method('getParameters')->willReturn($parameters);
-
         $this->organizationRepository
             ->expects($this->once())
             ->method('find')
-            ->with(1)
+            ->with($organizationId)
             ->willReturn($organization);
 
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $organization->expects($this->once())->method('getParameters')->willReturn($parameters);
+
+        $parameters->expects($this->once())->method('getUsernameSMS')->willReturn($mobytLogin);
+        $parameters->expects($this->once())->method('getPasswordSMS')->willReturn($mobytPassword);
+
         $this->mobytService
             ->expects($this->once())
             ->method('getUserStatus')
-            ->with(1, 'user', 'pwd')
+            ->with($mobytLogin, $mobytPassword)
             ->willReturn(
-                $this->getJsonContentFromFixture('user_status.json')
+                [
+                    'money' => 33.0,
+                    'sms' => [
+                        ['type' => 'N', 'quantity' => '300'],
+                        ['type' => 'EE', 'quantity' => '301'],  // this type of sms should be ignored by the method
+                    ],
+                    'email' => null
+                ]
             );
 
-        $mobytUserStatus = $this->mobytUserStatusCreator->getUserStatus(1);
+        $mobytUserStatus = $mobytUserStatusCreator->getUserStatus($organizationId);
 
         $this->assertEquals(
             $mobytUserStatus->getMoney(),

+ 0 - 14
tests/Service/Mobyt/fixtures/user_status.json

@@ -1,14 +0,0 @@
-{
-  "money": 33.0,
-  "sms": [
-    {
-      "type": "N",
-      "quantity": 300
-    },
-    {
-      "type": "EE",
-      "quantity": 300
-    }
-  ],
-  "email": null
-}

+ 41 - 36
tests/Service/Network/TreeTest.php

@@ -8,17 +8,14 @@ use App\Service\Network\Tree;
 
 class TreeTest extends TestCase
 {
-    private Tree $tree;
-    private NetworkOrganizationRepository $networkOrganizationRepositoryMock;
+    private NetworkOrganizationRepository $networkOrganizationRepository;
 
     public function setUp():void
     {
-        $this->networkOrganizationRepositoryMock =
-            $this
+        $this->networkOrganizationRepository = $this
                 ->getMockBuilder(NetworkOrganizationRepository::class)
                 ->disableOriginalConstructor()
                 ->getMock();
-        $this->tree = new Tree($this->networkOrganizationRepositoryMock);
     }
 
     /**
@@ -26,25 +23,28 @@ class TreeTest extends TestCase
      */
     public function testFindAllParentsAndSortByType():void
     {
-        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock
-            ->method('getId')
-            ->willReturn(1);
-        $this->networkOrganizationRepositoryMock
-            ->expects($this->once())
+        $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($organizationMock)
-            ->willReturn([$organizationMock]);
+            ->with($organization)
+            ->willReturn($parents);
 
-        $treeMock = $this
-            ->getMockBuilder(Tree::class)
-            ->setConstructorArgs([$this->networkOrganizationRepositoryMock])
-            ->onlyMethods(['sortByType'])
-            ->getMock();
-        $treeMock
-            ->expects($this->once())
-            ->method('sortByType');
-        $treeMock->findAllParentsAndSortByType($organizationMock);
+        $tree
+            ->expects(self::once())
+            ->method('sortByType')
+            ->with($parents);
+
+        $tree->findAllParentsAndSortByType($organization);
     }
 
     /**
@@ -52,25 +52,30 @@ class TreeTest extends TestCase
      */
     public function testSortByType():void
     {
-        $organizationMock1 = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock1->method('getId')->willReturn(2);
-        $organizationMock1->method('getPrincipalType')->willReturn('REGIONAL_FEDERATION');
+        $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');
 
-        $organizationMock2 = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock2->method('getId')->willReturn(3);
-        $organizationMock2->method('getPrincipalType')->willReturn('NATIONAL_FEDERATION');
+        $organization2 = $this->getMockBuilder(Organization::class)->getMock();
+        $organization2->method('getId')->willReturn(3);
+        $organization2->method('getPrincipalType')->willReturn('NATIONAL_FEDERATION');
 
-        $organizationMock3 = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock3->method('getId')->willReturn(4);
-        $organizationMock3->method('getPrincipalType')->willReturn('DEPARTEMENTAL_FEDERATION');
+        $organization3 = $this->getMockBuilder(Organization::class)->getMock();
+        $organization3->method('getId')->willReturn(4);
+        $organization3->method('getPrincipalType')->willReturn('DEPARTEMENTAL_FEDERATION');
 
         $organizations = [
-            $organizationMock2,
-            $organizationMock1,
-            $organizationMock3
+            $organization2,
+            $organization1,
+            $organization3
         ];
 
-        $result = $this->tree->sortByType($organizations);
+        $result = $tree->sortByType($organizations);
 
         $this->assertIsArray($result);
         $this->assertContainsOnlyInstancesOf(Organization::class, $result);
@@ -78,4 +83,4 @@ class TreeTest extends TestCase
         $this->assertEquals(2, $result[1]->getId());
         $this->assertEquals(3, $result[2]->getId());
     }
-}
+}

+ 203 - 54
tests/Service/Network/UtilsTest.php

@@ -1,47 +1,37 @@
-<?php
+<?php /** @noinspection PhpUnhandledExceptionInspection */
+
 namespace App\Tests\Service\Network;
 
 use App\Entity\Network\Network;
 use App\Entity\Network\NetworkOrganization;
 use App\Entity\Organization\Organization;
 use App\Enum\Network\NetworkEnum;
+use DateTime;
+use Doctrine\Common\Collections\ArrayCollection;
 use PHPUnit\Framework\TestCase;
-use App\Service\Network\Utils;
+use App\Service\Network\Utils as NetworkUtils;
 
 class UtilsTest extends TestCase
 {
-    private Utils $utils;
-    private Organization $organizationCmf;
-    private Organization $organizationFfec;
-
-    public function setUp():void
-    {
-        $networkCmf = new Network();
-        $networkCmf->setId(3);
-        $networkCmf->setName('CMF');
-        $networkOrganization = new NetworkOrganization();
-        $networkOrganization->setNetwork($networkCmf);
-        $networkOrganization->setStartDate(new \DateTime('2000-09-11'));
-        $this->organizationCmf = new Organization();
-        $this->organizationCmf->addNetworkOrganization($networkOrganization);
-
-        $networkFfec = new Network();
-        $networkFfec->setId(4);
-        $networkFfec->setName('FFEC');
-        $networkOrganization = new NetworkOrganization();
-        $networkOrganization->setNetwork($networkFfec);
-        $this->organizationFfec = new Organization();
-        $this->organizationFfec->addNetworkOrganization($networkOrganization);
-
-        $this->utils = new Utils();
-    }
-
     /**
      * @see Utils::isCMF()
      */
     public function testIsCmf():void
     {
-        $result = $this->utils->isCmf($this->organizationCmf);
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['isCMF'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+
+        $networkUtils
+            ->expects(self::once())
+            ->method('doesOrganizationBelongToTheNetwork')
+            ->with($organization, NetworkEnum::CMF())
+            ->willReturn(true);
+
+        $result = $networkUtils->isCmf($organization);
         $this->assertTrue($result);
     }
 
@@ -50,53 +40,212 @@ class UtilsTest extends TestCase
      */
     public function testIsNotCmf():void
     {
-        $result = $this->utils->isCmf($this->organizationFfec);
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['isCMF'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $networkUtils
+            ->expects(self::once())
+            ->method('doesOrganizationBelongToTheNetwork')
+            ->with($organization, NetworkEnum::CMF())
+            ->willReturn(false);
+
+        $result = $networkUtils->isCmf($organization);
         $this->assertFalse($result);
     }
 
     /**
-     * @see Utils::isCMFAndActiveNow()
+     * @see Utils::isCMF()
      */
     public function testIsCmfAndActiveNow():void
     {
-        $result = $this->utils->isCMFAndActiveNow($this->organizationCmf);
-        $this->assertTrue($result);
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['isCMFAndActiveNow'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $networkUtils
+            ->expects(self::once())
+            ->method('doesOrganizationBelongToTheNetwork')
+            ->with($organization, NetworkEnum::CMF(), true)
+            ->willReturn(false);
+
+        $result = $networkUtils->isCMFAndActiveNow($organization);
+        $this->assertFalse($result);
     }
 
     /**
-     * @see Utils::isCMFAndActiveNow()
+     * @see Utils::doesOrganizationBelongToTheNetwork()
      */
-    public function testIsCmfAndNotActiveNow():void
+    public function testDoesOrganizationBelongToTheNetwork():void
     {
-        $networkCmf = new Network();
-        $networkCmf->setId(3);
-        $networkCmf->setName('CMF');
-        $networkOrganization = new NetworkOrganization();
-        $networkOrganization->setNetwork($networkCmf);
-        $networkOrganization->setStartDate(new \DateTime('2000-09-11'));
-        $networkOrganization->setEndDate(new \DateTime('2020-09-11'));
-        $organizationCmfNotActive = new Organization();
-        $organizationCmfNotActive->addNetworkOrganization($networkOrganization);
-
-        $result = $this->utils->isCMFAndActiveNow($organizationCmfNotActive);
-        $this->assertFalse($result);
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['doesOrganizationBelongToTheNetwork'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+
+        $network1 = $this->getMockBuilder(Network::class)->getMock();
+        $network1->method('getId')->willReturn(NetworkEnum::CMF()->getValue());
+
+        $networkOrganization1 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization1->method('getNetwork')->willReturn($network1);
+
+        $network2 = $this->getMockBuilder(Network::class)->getMock();
+        $network2->method('getId')->willReturn(NetworkEnum::FFEC()->getValue());
+
+        $networkOrganization2 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization2->method('getNetwork')->willReturn($network2);
+
+        $organization
+            ->expects(self::once())
+            ->method('getNetworkOrganizations')
+            ->willReturn(new ArrayCollection([$networkOrganization1, $networkOrganization2]));
+
+        $networkUtils->expects(self::never())->method('isNetworkOrganizationActiveNow');
+
+        $result = $networkUtils->doesOrganizationBelongToTheNetwork($organization, NetworkEnum::FFEC());
+
+        $this->assertTrue($result);
     }
 
     /**
-     * @see Utils::isOrganizationBelongToTheNetwork()
+     * @see Utils::doesOrganizationBelongToTheNetwork()
      */
-    public function testIsOrganizationBelongToTheNetwork():void
+    public function testDoesOrganizationBelongToTheNetworkAndActive():void
     {
-        $result = $this->utils->isOrganizationBelongToTheNetwork($this->organizationCmf, NetworkEnum::CMF());
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['doesOrganizationBelongToTheNetwork'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+
+        $network1 = $this->getMockBuilder(Network::class)->getMock();
+        $network1->method('getId')->willReturn(NetworkEnum::CMF()->getValue());
+
+        $networkOrganization1 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization1->method('getNetwork')->willReturn($network1);
+
+        $network2 = $this->getMockBuilder(Network::class)->getMock();
+        $network2->method('getId')->willReturn(NetworkEnum::FFEC()->getValue());
+
+        $networkOrganization2 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization2->method('getNetwork')->willReturn($network2);
+
+        $organization
+            ->expects(self::once())
+            ->method('getNetworkOrganizations')
+            ->willReturn(new ArrayCollection([$networkOrganization1, $networkOrganization2]));
+
+        $networkUtils->expects(self::once())->method('isNetworkOrganizationActiveNow')->with($networkOrganization2)->willReturn(true);
+
+        $result = $networkUtils->doesOrganizationBelongToTheNetwork($organization, NetworkEnum::FFEC(), true);
+
         $this->assertTrue($result);
     }
 
     /**
-     * @see Utils::isOrganizationBelongToTheNetwork()
+     * @see Utils::doesOrganizationBelongToTheNetwork()
      */
-    public function testIsOrganizationNotBelongToTheNetwork():void
+    public function testDoesOrganizationBelongToTheNetworkFalse():void
     {
-        $result = $this->utils->isOrganizationBelongToTheNetwork($this->organizationCmf, NetworkEnum::FFEC());
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['doesOrganizationBelongToTheNetwork'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+
+        $network1 = $this->getMockBuilder(Network::class)->getMock();
+        $network1->method('getId')->willReturn(NetworkEnum::CMF()->getValue());
+
+        $networkOrganization1 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization1->method('getNetwork')->willReturn($network1);
+
+        $network2 = $this->getMockBuilder(Network::class)->getMock();
+        $network2->method('getId')->willReturn(NetworkEnum::FFEC()->getValue());
+
+        $networkOrganization2 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization2->method('getNetwork')->willReturn($network2);
+
+        $organization
+            ->expects(self::once())
+            ->method('getNetworkOrganizations')
+            ->willReturn(new ArrayCollection([$networkOrganization1, $networkOrganization2]));
+
+        $networkUtils->expects(self::never())->method('isNetworkOrganizationActiveNow');
+
+        $result = $networkUtils->doesOrganizationBelongToTheNetwork($organization, NetworkEnum::CFBF());
+
         $this->assertFalse($result);
     }
-}
+
+    /**
+     * @see Utils::doesOrganizationBelongToTheNetwork()
+     */
+    public function testIsOrganizationActiveNow():void
+    {
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['isNetworkOrganizationActiveNow'])
+            ->getMock();
+
+        $date1 = new DateTime('now');
+        $date1->modify('-1 year');
+
+        $date2 = new DateTime('now');
+        $date2->modify('+1 year');
+
+        $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization
+            ->expects(self::once())
+            ->method('getStartDate')
+            ->willReturn($date1);
+
+        $networkOrganization
+            ->expects(self::once())
+            ->method('getEndDate')
+            ->willReturn($date2);
+
+        $this->assertTrue(
+            $networkUtils->isNetworkOrganizationActiveNow($networkOrganization)
+        );
+    }
+
+    /**
+     * @see Utils::doesOrganizationBelongToTheNetwork()
+     */
+    public function testIsOrganizationActiveNowNotActive():void
+    {
+        $networkUtils = $this
+            ->getMockBuilder(NetworkUtils::class)
+            ->setMethodsExcept(['isNetworkOrganizationActiveNow'])
+            ->getMock();
+
+        $date1 = new DateTime('now');
+        $date1->modify('-3 year');
+
+        $date2 = new DateTime('now');
+        $date2->modify('-1 year');
+
+        $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization
+            ->expects(self::once())
+            ->method('getStartDate')
+            ->willReturn($date1);
+
+        $networkOrganization
+            ->expects(self::once())
+            ->method('getEndDate')
+            ->willReturn($date2);
+
+        $this->assertFalse(
+            $networkUtils->isNetworkOrganizationActiveNow($networkOrganization)
+        );
+    }
+}