Pārlūkot izejas kodu

minor fixes and revise multiple tests for Services

Olivier Massot 3 gadi atpakaļ
vecāks
revīzija
d8a6079d43
27 mainītis faili ar 968 papildinājumiem un 501 dzēšanām
  1. 1 0
      src/Enum/Education/AdvancedEducationNotationTypeEnum.php
  2. 1 0
      src/Enum/Organization/OrganizationIdsEnum.php
  3. 2 0
      src/Enum/Organization/PrincipalTypeEnum.php
  4. 4 0
      src/Enum/Organization/SettingsProductEnum.php
  5. 18 10
      src/Service/OnChange/Organization/OnParametersChange.php
  6. 4 1
      src/Service/Organization/OrganizationProfileCreator.php
  7. 23 19
      src/Service/Organization/Utils.php
  8. 2 3
      src/Service/Utils/GpsCoordinateUtils.php
  9. 5 3
      tests/Service/OnChange/OnChangeDefaultTest.php
  10. 51 24
      tests/Service/OnChange/Organization/OnOrganizationChangeTest.php
  11. 217 111
      tests/Service/OnChange/Organization/OnParametersChangeTest.php
  12. 36 40
      tests/Service/OnChange/Organization/OnSubdomainChangeTest.php
  13. 140 56
      tests/Service/Organization/OrganizationProfileCreatorTest.php
  14. 130 78
      tests/Service/Organization/UtilsTest.php
  15. 34 21
      tests/Service/Rest/ApiRequestServiceTest.php
  16. 19 13
      tests/Service/Rest/Operation/BaseRestOperationTest.php
  17. 4 2
      tests/Service/Rest/Operation/CreateOperationTest.php
  18. 24 10
      tests/Service/Security/ModuleTest.php
  19. 21 21
      tests/Service/Security/SwitchUserTest.php
  20. 7 2
      tests/Service/ServiceIterator/CurrentAccessExtensionIteratorTest.php
  21. 13 4
      tests/Service/ServiceIterator/EncoderIteratorTest.php
  22. 13 4
      tests/Service/ServiceIterator/ExporterIteratorTest.php
  23. 29 7
      tests/Service/ServiceIterator/OptionalsRolesIteratorTest.php
  24. 7 2
      tests/Service/Storage/TemporaryFileStorageTest.php
  25. 48 29
      tests/Service/Typo3/Typo3ServiceTest.php
  26. 9 7
      tests/Service/Utils/ArrayUtilsTest.php
  27. 106 34
      tests/Service/Utils/GpsCoordinateUtilsTest.php

+ 1 - 0
src/Enum/Education/AdvancedEducationNotationTypeEnum.php

@@ -7,6 +7,7 @@ use MyCLabs\Enum\Enum;
 
 /**
  * Type possible sur lesquels les grilles péda doivent se baser
+ * @method static BY_TEACHER()
  */
 class AdvancedEducationNotationTypeEnum extends Enum
 {

+ 1 - 0
src/Enum/Organization/OrganizationIdsEnum.php

@@ -9,6 +9,7 @@ use MyCLabs\Enum\Enum;
  * Id de structure spécifiques
  * @method static CMF()
  * @method static FFEC()
+ * @method static _2IOS()
  */
 class OrganizationIdsEnum extends Enum
 {

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

@@ -13,6 +13,8 @@ use MyCLabs\Enum\Enum;
  * @method static DEPARTEMENTAL_FEDERATION()
  * @method static REGIONAL_FEDERATION()
  * @method static NATIONAL_FEDERATION()
+ * @method static ARTISTIC_EDUCATION_ONLY()
+ * @method static ARTISTIC_PRACTICE_ONLY()
  */
 class PrincipalTypeEnum extends Enum
 {

+ 4 - 0
src/Enum/Organization/SettingsProductEnum.php

@@ -9,6 +9,10 @@ use MyCLabs\Enum\Enum;
  * Type de produit disponible pour une organisation
  * @method static SCHOOL()
  * @method static ARTIST()
+ * @method static MANAGER()
+ * @method static MANAGER_PREMIUM()
+ * @method static ARTIST_PREMIUM()
+ * @method static SCHOOL_PREMIUM()
  */
 class SettingsProductEnum extends Enum
 {

+ 18 - 10
src/Service/OnChange/Organization/OnParametersChange.php

@@ -32,6 +32,7 @@ class OnParametersChange extends OnChangeDefault
         private MessageBusInterface $messageBus
     ){ }
 
+    /** @noinspection PhpParameterNameChangedDuringInheritanceInspection */
     public function validate($parameters, OnChangeContext $context): void
     {
         // Une structure CMF n'a pas le droit de désactiver son site typo3
@@ -45,8 +46,12 @@ class OnParametersChange extends OnChangeDefault
 
     /**
      * @param Parameters $parameters
+     * @throws \Exception
+     * @noinspection PhpParameterNameChangedDuringInheritanceInspection
      */
-    public function beforeChange($parameters, OnChangeContext $context): void{
+    public function beforeChange($parameters, OnChangeContext $context): void
+    {
+        // Le type de notation a changé
         if(
             $context->previousData() &&
             $context->previousData()->getAdvancedEducationNotationType() !== $parameters->getAdvancedEducationNotationType()
@@ -54,7 +59,7 @@ class OnParametersChange extends OnChangeDefault
             $this->onAdvancedEducationNotationTypeChange($parameters);
         }
 
-        //La date de début d'activité change
+        // La date de début d'activité change
         if(
             $context->previousData() &&
             $context->previousData()->getMusicalDate() !== $parameters->getMusicalDate()
@@ -68,9 +73,11 @@ class OnParametersChange extends OnChangeDefault
 
     /**
      * @param Parameters $parameters
+     * @noinspection PhpParameterNameChangedDuringInheritanceInspection
      */
-    public function onChange($parameters, OnChangeContext $context): void{
-        //La note maximale du suivi pédagogique change
+    public function onChange($parameters, OnChangeContext $context): void
+    {
+        // La note maximale du suivi pédagogique change
         if(
             $context->previousData() &&
             $context->previousData()->getAverage() !== $parameters->getAverage()
@@ -112,20 +119,21 @@ class OnParametersChange extends OnChangeDefault
     }
 
     /**
-     * Si le le type de grilles d'évaluation évolue, il faut "nettoyer" les curriculums/teachers associés au type précédent
+     * Si le type de grilles d'évaluation évolue, il faut "nettoyer" les curriculums/teachers associés au type précédent
+     *
      * @param Parameters $parameters
      * @see OnParametersChangeTest::testOnAdvancedEducationNotationTypeByTeachersChange()
      * @see OnParametersChangeTest::testOnAdvancedEducationNotationTypeByEducationChange()
      */
     public function onAdvancedEducationNotationTypeChange(Parameters $parameters): void {
-        foreach ($parameters->getOrganization()->getEducationNotationConfigs() as $educationNotationConfig){
+        foreach ($parameters->getOrganization()->getEducationNotationConfigs() as $educationNotationConfig) {
             /** @var EducationNotationConfig $educationNotationConfig */
-            if($parameters->getAdvancedEducationNotationType() === AdvancedEducationNotationTypeEnum::BY_TEACHER()->getValue()){
-                foreach ($educationNotationConfig->getEducationCurriculums() as $educationCurriculum){
+            if ($parameters->getAdvancedEducationNotationType() === AdvancedEducationNotationTypeEnum::BY_TEACHER()->getValue()) {
+                foreach ($educationNotationConfig->getEducationCurriculums() as $educationCurriculum) {
                     $educationCurriculum->setEducationNotationConfig(null);
                 }
-            }else{
-                foreach ($educationNotationConfig->getTeachers() as $teacher){
+            } else {
+                foreach ($educationNotationConfig->getTeachers() as $teacher) {
                     $teacher->setEducationNotationConfig(null);
                 }
             }

+ 4 - 1
src/Service/Organization/OrganizationProfileCreator.php

@@ -37,7 +37,10 @@ class OrganizationProfileCreator
         $organizationProfile->setParametersId($organization->getParameters()->getId());
         $organizationProfile->setLegalStatus($organization->getLegalStatus());
         $organizationProfile->setHasChildren($organization->getNetworkOrganizationChildren()->count() > 1);
-        $organizationProfile->setShowAdherentList($organization->getParameters()->getShowAdherentList() && $organization->getPrincipalType() != PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY());
+        $organizationProfile->setShowAdherentList(
+            $organization->getParameters()->getShowAdherentList() &&
+            $organization->getPrincipalType() !== PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY()->getValue()
+        );
 
         foreach ($organization->getNetworkOrganizations() as $networkOrganization){
             $organizationProfile->addNetwork($networkOrganization->getNetwork()->getName());

+ 23 - 19
src/Service/Organization/Utils.php

@@ -11,45 +11,47 @@ use App\Test\Service\Organization\UtilsTest;
 use Doctrine\Common\Collections\Criteria;
 
 /**
- * Class OrganizationUtils : service rassemblant des fonctions d'aides pour les questions se rapportant à l'organisation
- * @package App\Service\Resource
+ * Service rassemblant des fonctions d'aide pour les questions se rapportant à l'organisation
  */
 class Utils
 {
-    // TODO: Renommer en OrganizationUtils
-
-    const START_DATE_KEY = 'dateStart';
-    const END_DATE_KEY = 'dateEnd';
+    private const START_DATE_KEY = 'dateStart';
+    private const END_DATE_KEY = 'dateEnd';
 
     /**
-     * Test si l'organisation est considérée comme une structure == n'a pas un produit manager
+     * Teste si l'organisation est considérée comme une structure == n'a pas un produit manager
+     *
      * @param Organization $organization
      * @return bool
      * @see UtilsTest::testIsStructureTest()
      */
-    public function isStructure(Organization $organization): bool{
-        return $organization->getSettings()->getProduct() != SettingsProductEnum::MANAGER()
-            && $organization->getSettings()->getProduct() != SettingsProductEnum::MANAGER_PREMIUM();
+    public function isStructure(Organization $organization): bool
+    {
+        return $organization->getSettings()->getProduct() !== SettingsProductEnum::MANAGER()->getValue() &&
+               $organization->getSettings()->getProduct() !== SettingsProductEnum::MANAGER_PREMIUM()->getValue();
     }
 
     /**
-     * Test si l'organisation est considérée comme un manager == a un produit manager standard
+     * Teste si l'organisation est considérée comme un manager == a un produit manager standard
+     *
      * @param Organization $organization
      * @return bool
      * @see UtilsTest::testIsManagerTest()
      */
-    public function isManager(Organization $organization): bool{
-        return $organization->getSettings()->getProduct() == SettingsProductEnum::MANAGER();
+    public function isManager(Organization $organization): bool
+    {
+        return $organization->getSettings()->getProduct() === SettingsProductEnum::MANAGER()->getValue();
     }
 
     /**
-     * Test si l'organisation est la structure 2iOpenservice
+     * Teste si l'organisation est la structure 2iOpenservice
      * @param Organization $organization
      * @return bool
      * @see UtilsTest::testIsOrganizationIs2ios()
      */
-    public function isOrganizationIs2ios(Organization $organization): bool{
-        return $this->isOrganizationIdIs($organization, OrganizationIdsEnum::_2IOS());
+    public function is2iosOrganization(Organization $organization): bool
+    {
+        return $this->isOrganizationIdEqualTo($organization, OrganizationIdsEnum::_2IOS());
     }
 
     /**
@@ -58,8 +60,9 @@ class Utils
      * @return bool
      * @see UtilsTest::testIsOrganizationIsCMF()
      */
-    public function isOrganizationIsCMF(Organization $organization): bool{
-        return $this->isOrganizationIdIs($organization, OrganizationIdsEnum::CMF());
+    public function isOrganizationCMF(Organization $organization): bool
+    {
+        return $this->isOrganizationIdEqualTo($organization, OrganizationIdsEnum::CMF());
     }
 
     /**
@@ -68,7 +71,8 @@ class Utils
      * @param OrganizationIdsEnum $organizationIdsEnum
      * @return bool
      */
-    private function isOrganizationIdIs(Organization $organization, OrganizationIdsEnum $organizationIdsEnum){
+    protected function isOrganizationIdEqualTo(Organization $organization, OrganizationIdsEnum $organizationIdsEnum): bool
+    {
         return $organization->getId() === $organizationIdsEnum->getValue();
     }
 

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

@@ -42,8 +42,7 @@ class GpsCoordinateUtils
         }catch(\Exception $e){
             throw new NotFoundHttpException('no_reverse_gps_coordinate', $e, 404);
         }
-
-        return json_decode($response, true);
+        return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
     }
 
     /**
@@ -65,7 +64,7 @@ class GpsCoordinateUtils
             throw new NotFoundHttpException('no_reverse_gps_coordinate', $e, 404);
         }
 
-        return json_decode($response, true);
+        return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
     }
 
     /**

+ 5 - 3
tests/Service/OnChange/OnChangeDefaultTest.php

@@ -7,11 +7,13 @@ use PHPUnit\Framework\TestCase;
 class OnChangeDefaultTest extends TestCase
 {
     /**
-     * Default OnChange service does nothing; it shouldn't change anything to the data nor raise excemptions
+     * Default OnChange service does nothing; it shouldn't change anything to the data nor raise exceptions
      */
-    public function testDoesNothing() {
+    public function testDoesNothing(): void
+    {
         $data = 1;
-        $context = new OnChangeContext([]);
+
+        $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
 
         $onChange = new OnChangeDefault();
         $onChange->validate($data, $context);

+ 51 - 24
tests/Service/OnChange/Organization/OnOrganizationChangeTest.php

@@ -11,22 +11,14 @@ use PHPUnit\Framework\TestCase;
 
 class OnOrganizationChangeTest extends TestCase
 {
-    private Organization $organization;
-    private OnOrganizationChange $onOrganizationChange;
-
-    public function setUp():void
-    {
-        $this->organization = new Organization();
-        $this->onOrganizationChange = new OnOrganizationChange();
-    }
-
     public function testBeforeChangeNoChange(): void
     {
         $onOrganizationChange =  $this
             ->getMockBuilder(OnOrganizationChange::class)
-            ->onlyMethods(['onLegalStatusChange'])
+            ->setMethodsExcept(['beforeChange'])
             ->disableOriginalConstructor()
             ->getMock();
+
         $onOrganizationChange
             ->expects(self::never())
             ->method('onLegalStatusChange')
@@ -48,9 +40,10 @@ class OnOrganizationChangeTest extends TestCase
     {
         $onOrganizationChange =  $this
             ->getMockBuilder(OnOrganizationChange::class)
-            ->onlyMethods(['onLegalStatusChange'])
+            ->setMethodsExcept(['beforeChange'])
             ->disableOriginalConstructor()
             ->getMock();
+
         $onOrganizationChange
             ->expects(self::once())
             ->method('onLegalStatusChange')
@@ -71,18 +64,52 @@ class OnOrganizationChangeTest extends TestCase
     /**
      * @see OnOrganizationChange::onLegalStatusChange()
      */
-    public function testOnLegalStatusChange(){
-        $this->organization->setLegalStatus(LegalEnum::COMMERCIAL_SOCIETY()->getValue());
-        $parameters = new Parameters();
-        $parameters->setShowAdherentList(true);
-        $billingSettings = new BillingSetting();
-        $billingSettings->setApplyVat(false);
-        $this->organization->setParameters($parameters);
-        $this->organization->setBillingSetting($billingSettings);
-
-        $this->onOrganizationChange->onLegalStatusChange($this->organization);
-
-        $this->assertFalse($this->organization->getParameters()->getShowAdherentList());
-        $this->assertTrue($this->organization->getBillingSetting()->getApplyVat());
+    public function testOnLegalStatusChangeToAsso(){
+
+        $onOrganizationChange =  $this
+            ->getMockBuilder(OnOrganizationChange::class)
+            ->setMethodsExcept(['onLegalStatusChange'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901()->getValue());
+
+        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $billingSettings = $this->getMockBuilder(BillingSetting::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getBillingSetting')->willReturn($billingSettings);
+
+        $parameters->expects(self::never())->method('setShowAdherentList');
+        $billingSettings->expects(self::never())->method('setApplyVat');
+
+        $onOrganizationChange->onLegalStatusChange($organization);
+    }
+
+    /**
+     * @see OnOrganizationChange::onLegalStatusChange()
+     */
+    public function testOnLegalStatusChangeToSociety(){
+
+        $onOrganizationChange =  $this
+            ->getMockBuilder(OnOrganizationChange::class)
+            ->setMethodsExcept(['onLegalStatusChange'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getLegalStatus')->willReturn(LegalEnum::COMMERCIAL_SOCIETY()->getValue());
+
+        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $billingSettings = $this->getMockBuilder(BillingSetting::class)->disableOriginalConstructor()->getMock();
+        $organization->method('getBillingSetting')->willReturn($billingSettings);
+
+        $parameters->expects(self::once())->method('setShowAdherentList')->with(false);
+        $billingSettings->expects(self::once())->method('setApplyVat')->with(true);
+
+        $onOrganizationChange->onLegalStatusChange($organization);
     }
 }

+ 217 - 111
tests/Service/OnChange/Organization/OnParametersChangeTest.php

@@ -1,4 +1,7 @@
-<?php
+<?php /** @noinspection DuplicatedCode */
+
+/** @noinspection PhpUnhandledExceptionInspection */
+
 namespace App\Test\Service\OnChange\Organization;
 
 use App\Entity\Access\Access;
@@ -13,99 +16,133 @@ use App\Message\Command\Typo3\Typo3DeleteCommand;
 use App\Message\Command\Typo3\Typo3UndeleteCommand;
 use App\Message\Command\Typo3\Typo3UpdateCommand;
 use App\Repository\Booking\CourseRepository;
+use App\Service\Network\Utils as NetworkUtils;
 use App\Service\OnChange\OnChangeContext;
 use App\Service\OnChange\Organization\OnParametersChange;
+use App\Service\Organization\Utils as OrganizationUtils;
 use AssertionError;
+use Doctrine\Common\Collections\ArrayCollection;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\Messenger\Envelope;
 use Symfony\Component\Messenger\MessageBusInterface;
 
 class OnParametersChangeTest extends TestCase
 {
-    private Parameters $parameters;
-    private OnParametersChange $onParametersChange;
-    private CourseRepository $courseRepositoryMock;
-    private \App\Service\Network\Utils $networkUtils;
+    private CourseRepository $courseRepository;
+    private NetworkUtils $networkUtils;
     private MessageBusInterface $messageBus;
-    private \App\Service\Organization\Utils $organizationUtils;
+    private OrganizationUtils $organizationUtils;
 
     public function setUp(): void
     {
-        $this->courseRepositoryMock = $this->getMockBuilder(CourseRepository::class)->disableOriginalConstructor()->getMock();
-        $this->networkUtils = $this->getMockBuilder(\App\Service\Network\Utils::class)->disableOriginalConstructor()->getMock();
-        $this->organizationUtils = $this->getMockBuilder(\App\Service\Organization\Utils::class)->disableOriginalConstructor()->getMock();
+        $this->courseRepository = $this->getMockBuilder(CourseRepository::class)->disableOriginalConstructor()->getMock();
+        $this->networkUtils = $this->getMockBuilder(NetworkUtils::class)->disableOriginalConstructor()->getMock();
+        $this->organizationUtils = $this->getMockBuilder(OrganizationUtils::class)->disableOriginalConstructor()->getMock();
         $this->messageBus = $this->getMockBuilder(MessageBusInterface::class)->disableOriginalConstructor()->getMock();
-        $this->parameters = new Parameters();
-        $this->onParametersChange = new OnParametersChange(
-            $this->courseRepositoryMock,
-            $this->networkUtils,
-            $this->organizationUtils,
-            $this->messageBus
-        );
     }
 
-    public function testValidate(): void
+    public function testValidateValid(): void
     {
+        $onParametersChange = $this->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['validate'])
+            ->getMock();
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
 
-        // 1. Is CMF and site web enabled ; 2. Is not CMF and site web disabled ; 3. Is not CMF and site web enabled
-        foreach ([[false, true], [true, false], [false, false]] as $params) {
-            $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $consecutiveParams = [
+            [false, true],  // Is CMF and site web enabled
+            [true, false],  // Is not CMF and site web disabled
+            [false, false]  // Is not CMF and site web enabled
+        ];
+
+        foreach ($consecutiveParams as $params) {
+            $organization = $this->getMockBuilder(Organization::class)->getMock();
+            $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+            $parameters->method('getOrganization')->willReturn($organization);
+
             $parameters->expects(self::once())->method('getDesactivateOpentalentSiteWeb')->willReturn($params[0]);
 
-            $this->networkUtils = $this->getMockBuilder(\App\Service\Network\Utils::class)->disableOriginalConstructor()->getMock();
-            $this->networkUtils->method('isCMFAndActiveNow')->willReturn($params[1]);
+            $this->networkUtils = $this->getMockBuilder(NetworkUtils::class)->getMock();
+            $this->networkUtils->method('isCMFAndActiveNow')->with($organization)->willReturn($params[1]);
 
-            $this->onParametersChange->validate($parameters, $context);
+            $onParametersChange->validate($parameters, $context);
         }
     }
 
     public function testValidateInvalid(): void
     {
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $onParametersChange = $this->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['validate'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getOrganization')->willReturn($organization);
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
 
         // Is CMF and site web disabled
         $parameters->expects(self::once())->method('getDesactivateOpentalentSiteWeb')->willReturn(true);
-        $this->networkUtils->expects(self::once())->method('isCMFAndActiveNow')->willReturn(true);
+        $this->networkUtils->expects(self::once())->method('isCMFAndActiveNow')->with($organization)->willReturn(true);
 
         $this->expectException(\RuntimeException::class);
 
-        $this->onParametersChange->validate($parameters, $context);
+        $onParametersChange->validate($parameters, $context);
     }
 
     public function testBeforeChange(): void
     {
-        $onParametersChange =  $this
+        $onParametersChange = $this
             ->getMockBuilder(OnParametersChange::class)
-            ->onlyMethods(['onAdvancedEducationNotationTypeChange', 'onMusicalDateChange'])
-            ->disableOriginalConstructor()
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['beforeChange'])
             ->getMock();
 
-        $onParametersChange
-            ->expects(self::once())
-            ->method('onAdvancedEducationNotationTypeChange')
-            ->willReturnSelf();
-        $onParametersChange
-            ->expects(self::once())
-            ->method('onMusicalDateChange')
-            ->willReturnSelf();
+        $onParametersChange->expects(self::once())->method('onAdvancedEducationNotationTypeChange');
+
+        $onParametersChange->expects(self::once())->method('onMusicalDateChange');
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
-        $previousParameters->method('getAdvancedEducationNotationType')->willReturn('BY_EDUCATION');
         $musicalDate = new \DateTime('2022-01-01');
+
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $previousParameters->method('getAdvancedEducationNotationType')->willReturn('BY_EDUCATION');
         $previousParameters->method('getMusicalDate')->willReturn($musicalDate);
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getAdvancedEducationNotationType')->willReturn('SOMETHING_ELSE');
         $parameters->method('getMusicalDate')->willReturn(new \DateTime('2023-01-01'));
 
         // Both mocked methods should be called once here
         $onParametersChange->beforeChange($parameters, $context);
+    }
+
+    public function testBeforeChangeNoChange(): void
+    {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['beforeChange'])
+            ->getMock();
+
+        $onParametersChange->expects(self::never())->method('onAdvancedEducationNotationTypeChange');
+
+        $onParametersChange->expects(self::never())->method('onMusicalDateChange');
+
+        $musicalDate = new \DateTime('2022-01-01');
+
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $previousParameters->method('getAdvancedEducationNotationType')->willReturn('BY_EDUCATION');
+        $previousParameters->method('getMusicalDate')->willReturn($musicalDate);
+
+        $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
+        $context->method('previousData')->willReturn($previousParameters);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getAdvancedEducationNotationType')->willReturn('BY_EDUCATION');
         $parameters->method('getMusicalDate')->willReturn($musicalDate);
@@ -116,35 +153,47 @@ class OnParametersChangeTest extends TestCase
 
     public function testOnChangeNoChange(): void
     {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onChange'])
+            ->getMock();
+
         $this->messageBus->expects($this->never())->method('dispatch');
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $previousParameters->method('getId')->willReturn(1);
-        $previousParameters->expects(self::once())->method('getAverage')->willReturn(20);
-        $previousParameters->expects(self::once())->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
-        $previousParameters->expects(self::once())->method('getCustomDomain')->willReturn(null);
+        $previousParameters->method('getAverage')->willReturn(20);
+        $previousParameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
+        $previousParameters->method('getCustomDomain')->willReturn(null);
 
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getAverage')->willReturn(20);
         $parameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
         $parameters->method('getCustomDomain')->willReturn(null);
 
-        $this->onParametersChange->onChange($parameters, $context);
+        $onParametersChange->onChange($parameters, $context);
     }
 
     public function testOnChangeAverageChanged(): void
     {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onChange'])
+            ->getMock();
+
         $this->messageBus
             ->expects(self::once())
             ->method('dispatch')
             ->with(self::isInstanceOf(AverageChange::class))
             ->willReturn(new Envelope(new AverageChange(1)));
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $previousParameters->method('getId')->willReturn(1);
         $previousParameters->expects(self::once())->method('getAverage')->willReturn(20);
         $previousParameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
@@ -153,24 +202,30 @@ class OnParametersChangeTest extends TestCase
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
         $parameters->method('getCustomDomain')->willReturn(null);
         $parameters->expects(self::once())->method('getAverage')->willReturn(30);
 
-        $this->onParametersChange->onChange($parameters, $context);
+        $onParametersChange->onChange($parameters, $context);
     }
 
     public function testOnChangeCustomDomainChanged(): void
     {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onChange'])
+            ->getMock();
+
         $this->messageBus
             ->expects(self::once())
             ->method('dispatch')
             ->with(self::isInstanceOf(Typo3UpdateCommand::class))
             ->willReturn(new Envelope(new Typo3UpdateCommand(1)));
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $previousParameters->method('getId')->willReturn(1);
         $previousParameters->method('getAverage')->willReturn(20);
         $previousParameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
@@ -179,28 +234,34 @@ class OnParametersChangeTest extends TestCase
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
         $organization->method('getId')->willReturn(1);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getOrganization')->willReturn($organization);
         $parameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
         $parameters->expects(self::once())->method('getCustomDomain')->willReturn('custom');
         $parameters->method('getAverage')->willReturn(20);
 
-        $this->onParametersChange->onChange($parameters, $context);
+        $onParametersChange->onChange($parameters, $context);
     }
 
     public function testOnChangeWebsiteDisabled(): void
     {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onChange'])
+            ->getMock();
+
         $this->messageBus
             ->expects(self::once())
             ->method('dispatch')
             ->with(self::isInstanceOf(Typo3DeleteCommand::class))
             ->willReturn(new Envelope(new Typo3DeleteCommand(1)));
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $previousParameters->method('getId')->willReturn(1);
         $previousParameters->method('getAverage')->willReturn(20);
         $previousParameters->expects(self::once())->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
@@ -209,21 +270,27 @@ class OnParametersChangeTest extends TestCase
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
         $organization->method('getId')->willReturn(1);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getOrganization')->willReturn($organization);
         $parameters->method('getDesactivateOpentalentSiteWeb')->willReturn(true);
         $parameters->method('getCustomDomain')->willReturn(null);
         $parameters->method('getAverage')->willReturn(20);
 
-        $this->onParametersChange->onChange($parameters, $context);
+        $onParametersChange->onChange($parameters, $context);
     }
 
     public function testOnChangeWebsiteEnabled(): void
     {
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onChange'])
+            ->getMock();
+
         $this->messageBus
             ->expects(self::exactly(2))
             ->method('dispatch')
@@ -237,7 +304,7 @@ class OnParametersChangeTest extends TestCase
                 throw new AssertionError('unexpected message : ' . $message::class);
             });
 
-        $previousParameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $previousParameters = $this->getMockBuilder(Parameters::class)->getMock();
         $previousParameters->method('getId')->willReturn(1);
         $previousParameters->method('getAverage')->willReturn(20);
         $previousParameters->expects(self::once())->method('getDesactivateOpentalentSiteWeb')->willReturn(true);
@@ -246,17 +313,17 @@ class OnParametersChangeTest extends TestCase
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('previousData')->willReturn($previousParameters);
 
-        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
         $organization->method('getId')->willReturn(1);
 
-        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
         $parameters->method('getId')->willReturn(1);
         $parameters->method('getOrganization')->willReturn($organization);
         $parameters->method('getDesactivateOpentalentSiteWeb')->willReturn(false);
         $parameters->method('getCustomDomain')->willReturn(null);
         $parameters->method('getAverage')->willReturn(20);
 
-        $this->onParametersChange->onChange($parameters, $context);
+        $onParametersChange->onChange($parameters, $context);
     }
 
     /**
@@ -264,19 +331,27 @@ class OnParametersChangeTest extends TestCase
      */
     public function testOnAdvancedEducationNotationTypeByTeachersChange(): void
     {
-        $educationNotationConfig = new EducationNotationConfig();
-        $educationCurriculum = new EducationCurriculum();
-        $educationNotationConfig->addEducationCurriculum($educationCurriculum);
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onAdvancedEducationNotationTypeChange'])
+            ->getMock();
 
-        $organization = new Organization();
-        $organization->addEducationNotationConfig($educationNotationConfig);
+        $educationCurriculum = $this->getMockBuilder(EducationCurriculum::class)->getMock();
 
-        $this->parameters->setAdvancedEducationNotationType(AdvancedEducationNotationTypeEnum::BY_TEACHER()->getValue());
-        $this->parameters->setOrganization($organization);
+        $educationNotationConfig = $this->getMockBuilder(EducationNotationConfig::class)->getMock();
+        $educationNotationConfig->method('getEducationCurriculums')->willReturn(new ArrayCollection([$educationCurriculum]));
 
-        $this->assertCount(1, $educationNotationConfig->getEducationCurriculums());
-        $this->onParametersChange->onAdvancedEducationNotationTypeChange($this->parameters);
-        $this->assertNull($educationNotationConfig->getEducationCurriculums()->first()->getEducationNotationConfig());
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getEducationNotationConfigs')->willReturn(new ArrayCollection([$educationNotationConfig]));
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getOrganization')->willReturn($organization);
+        $parameters->method('getAdvancedEducationNotationType')->willReturn(AdvancedEducationNotationTypeEnum::BY_TEACHER()->getValue());
+
+        $educationCurriculum->expects(self::once())->method('setEducationNotationConfig')->with(null);
+
+        $onParametersChange->onAdvancedEducationNotationTypeChange($parameters);
     }
 
     /**
@@ -284,19 +359,27 @@ class OnParametersChangeTest extends TestCase
      */
     public function testOnAdvancedEducationNotationTypeByEducationChange(): void
     {
-        $educationNotationConfig = new EducationNotationConfig();
-        $teacher = new Access();
-        $educationNotationConfig->addTeacher($teacher);
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onAdvancedEducationNotationTypeChange'])
+            ->getMock();
+
+        $teacher = $this->getMockBuilder(Access::class)->getMock();
+
+        $educationNotationConfig = $this->getMockBuilder(EducationNotationConfig::class)->getMock();
+        $educationNotationConfig->method('getTeachers')->willReturn(new ArrayCollection([$teacher]));
 
-        $organization = new Organization();
-        $organization->addEducationNotationConfig($educationNotationConfig);
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getEducationNotationConfigs')->willReturn(new ArrayCollection([$educationNotationConfig]));
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getOrganization')->willReturn($organization);
+        $parameters->method('getAdvancedEducationNotationType')->willReturn(AdvancedEducationNotationTypeEnum::BY_EDUCATION()->getValue());
 
-        $this->parameters->setAdvancedEducationNotationType(AdvancedEducationNotationTypeEnum::BY_EDUCATION()->getValue());
-        $this->parameters->setOrganization($organization);
+        $teacher->expects(self::once())->method('setEducationNotationConfig')->with(null);
 
-        $this->assertCount(1, $educationNotationConfig->getTeachers());
-        $this->onParametersChange->onAdvancedEducationNotationTypeChange($this->parameters);
-        $this->assertNull($educationNotationConfig->getTeachers()->first()->getEducationNotationConfig());
+        $onParametersChange->onAdvancedEducationNotationTypeChange($parameters);
     }
 
     /**
@@ -306,28 +389,38 @@ class OnParametersChangeTest extends TestCase
      */
     public function testOnMusicalDateChangeToPast(): void
     {
-        $this->parameters->setMusicalDate(new \DateTime('2022-09-01'));
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onMusicalDateChange'])
+            ->getMock();
 
-        $organization = new Organization();
-        $this->parameters->setOrganization($organization);
-        $organization->setParameters($this->parameters);
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+        $parameters->method('getOrganization')->willReturn($organization);
 
-        $this->organizationUtils->expects(self::once())->method('getActivityYearSwitchDate')->willReturn(2022);
+        $parameters->method('getMusicalDate')->willReturn(new \DateTime('2022-09-01'));
 
-        $course = new Course();
-        $course->setStartYear(2021);
-        $course->setEndYear(2022);
-        $course->setDatetimeStart(new \DateTime('2022-09-02'));
+        $startDate = new \DateTime('2022-09-02');
 
-        $this->courseRepositoryMock
-            ->method('getCoursesToFrom')
-            ->willReturn([$course])
-        ;
+        $this->organizationUtils
+            ->expects(self::once())
+            ->method('getActivityYearSwitchDate')
+            ->with($organization, $startDate)
+            ->willReturn(2022);
+
+        $course = $this->getMockBuilder(Course::class)->getMock();
+        $course->method('getStartYear')->willReturn(2021);
+        $course->method('getEndYear')->willReturn(2022);
+        $course->method('getDatetimeStart')->willReturn($startDate);
 
-        $this->onParametersChange->onMusicalDateChange($this->parameters, new \DateTime('2022-09-05'));
+        $this->courseRepository->method('getCoursesToFrom')->willReturn([$course]);
 
-        $this->assertEquals(2022, $course->getStartYear());
-        $this->assertEquals(2023, $course->getEndYear());
+        $course->expects(self::once())->method('setStartYear')->with(2022);
+        $course->expects(self::once())->method('setEndYear')->with(2023);
+
+        $onParametersChange->onMusicalDateChange($parameters, new \DateTime('2022-09-05'));
     }
 
     /**
@@ -338,27 +431,40 @@ class OnParametersChangeTest extends TestCase
      */
     public function testOnMusicalDateChangeToFuture(): void
     {
-        $this->parameters->setMusicalDate(new \DateTime('2022-09-05'));
+        $onParametersChange = $this
+            ->getMockBuilder(OnParametersChange::class)
+            ->setConstructorArgs([$this->courseRepository, $this->networkUtils, $this->organizationUtils, $this->messageBus])
+            ->setMethodsExcept(['onMusicalDateChange'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+        $parameters->method('getOrganization')->willReturn($organization);
 
-        $organization = new Organization();
-        $this->parameters->setOrganization($organization);
-        $organization->setParameters($this->parameters);
+        $parameters->method('getMusicalDate')->willReturn(new \DateTime('2022-09-05'));
 
-        $this->organizationUtils->expects(self::once())->method('getActivityYearSwitchDate')->willReturn(2021);
+        $startDate = new \DateTime('2022-09-02');
+
+        $this->organizationUtils
+            ->expects(self::once())
+            ->method('getActivityYearSwitchDate')
+            ->with($organization, $startDate)
+            ->willReturn(2021);
 
-        $course = new Course();
-        $course->setStartYear(2022);
-        $course->setEndYear(2023);
-        $course->setDatetimeStart(new \DateTime('2022-09-02'));
+        $course = $this->getMockBuilder(Course::class)->getMock();
+        $course->method('getStartYear')->willReturn(2022);
+        $course->method('getEndYear')->willReturn(2023);
+        $course->method('getDatetimeStart')->willReturn($startDate);
 
-        $this->courseRepositoryMock
+        $this->courseRepository
             ->method('getCoursesToFrom')
             ->willReturn([$course])
         ;
 
-        $this->onParametersChange->onMusicalDateChange($this->parameters, new \DateTime('2022-09-01'));
+        $course->expects(self::once())->method('setStartYear')->with(2021);
+        $course->expects(self::once())->method('setEndYear')->with(2022);
 
-        $this->assertEquals(2021, $course->getStartYear());
-        $this->assertEquals(2022, $course->getEndYear());
+        $onParametersChange->onMusicalDateChange($parameters, new \DateTime('2022-09-01'));
     }
 }

+ 36 - 40
tests/Service/OnChange/Organization/OnSubdomainChangeTest.php

@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection DuplicatedCode */
 
 namespace App\Test\Service\OnChange\Organization;
 
@@ -14,6 +14,7 @@ use App\Service\Organization\Utils as OrganizationUtils;
 use App\Service\Typo3\BindFileService;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\EntityManagerInterface;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\Messenger\Envelope;
 use Symfony\Component\Messenger\MessageBusInterface;
@@ -25,7 +26,6 @@ class OnSubdomainChangeTest extends TestCase
     private MailHub $mailHub;
     private BindFileService $bindFileService;
     private MessageBusInterface $messageBus;
-    private OnSubdomainChange $onSubdomainChange;
 
     public function setUp():void
     {
@@ -34,18 +34,19 @@ class OnSubdomainChangeTest extends TestCase
         $this->mailHub = $this->getMockBuilder(MailHub::class)->disableOriginalConstructor()->getMock();
         $this->bindFileService = $this->getMockBuilder(BindFileService::class)->disableOriginalConstructor()->getMock();
         $this->messageBus = $this->getMockBuilder(MessageBusInterface::class)->disableOriginalConstructor()->getMock();
+    }
 
-        $this->onSubdomainChange = new OnSubdomainChange(
-            $this->organizationUtils,
-            $this->accessUtils,
-            $this->mailHub,
-            $this->bindFileService,
-            $this->messageBus
-        );
+    private function makeOnSubdomainChangeMock(string $methodName): MockObject | OnSubdomainChange {
+        return $this->getMockBuilder(OnSubdomainChange::class)
+            ->setConstructorArgs([$this->organizationUtils, $this->accessUtils, $this->mailHub, $this->bindFileService, $this->messageBus])
+            ->setMethodsExcept([$methodName])
+            ->getMock();
     }
 
     public function testValidateIsOk(): void
     {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('validate');
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('isPostRequest')->willReturn(true);
 
@@ -55,22 +56,26 @@ class OnSubdomainChangeTest extends TestCase
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
         $subdomain->expects(self::once())->method('getOrganization')->willReturn($organization);
 
-        $this->onSubdomainChange->validate($subdomain, $context);
+        $onSubdomainChange->validate($subdomain, $context);
     }
 
     public function testValidateIsPutRequest(): void
     {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('validate');
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('isPostRequest')->willReturn(false);
 
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
         $subdomain->expects(self::never())->method('getOrganization');
 
-        $this->onSubdomainChange->validate($subdomain, $context);
+        $onSubdomainChange->validate($subdomain, $context);
     }
 
     public function testValidateMaxReached(): void
     {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('validate');
+
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
         $context->method('isPostRequest')->willReturn(true);
 
@@ -81,10 +86,13 @@ class OnSubdomainChangeTest extends TestCase
         $subdomain->expects(self::once())->method('getOrganization')->willReturn($organization);
 
         $this->expectException(\RuntimeException::class);
-        $this->onSubdomainChange->validate($subdomain, $context);
+        $onSubdomainChange->validate($subdomain, $context);
     }
 
-    public function testBeforeChangeActivated() {
+    public function testBeforeChangeActivated(): void
+    {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('beforeChange');
+
         // Le sous-domaine qu'on vient d'activer
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
         $subdomain->method('isActive')->willReturn(true);
@@ -108,28 +116,26 @@ class OnSubdomainChangeTest extends TestCase
         $context->method('isPutRequest')->willReturn(true);
         $context->method('isPostRequest')->willReturn(false);
 
-        $this->onSubdomainChange->beforeChange($subdomain, $context);
+        $onSubdomainChange->beforeChange($subdomain, $context);
     }
 
     public function testOnChangeNoChange(): void
     {
-        $onChange =  $this
-            ->getMockBuilder(OnSubdomainChange::class)
-            ->onlyMethods(['sendEmailAfterSubdomainChange'])
-            ->disableOriginalConstructor()
-            ->getMock();
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('onChange');
 
         $this->bindFileService->expects(self::never())->method('registerSubdomain');
         $this->messageBus->expects(self::never())->method('dispatch');
-        $onChange->expects(self::never())->method('sendEmailAfterSubdomainChange');
+        $onSubdomainChange->expects(self::never())->method('sendEmailAfterSubdomainChange');
 
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
         $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
 
-        $onChange->onChange($subdomain, $context);
+        $onSubdomainChange->onChange($subdomain, $context);
     }
 
     public function testOnChangeActivated(): void {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('onChange');
+
         $this->bindFileService->expects(self::never())->method('registerSubdomain');
         $this->messageBus
             ->expects(self::once())
@@ -137,14 +143,7 @@ class OnSubdomainChangeTest extends TestCase
             ->with(self::isInstanceOf(Typo3UpdateCommand::class))
             ->willReturn(new Envelope(new Typo3UpdateCommand(1)));
 
-        $onChange = $this
-            ->getMockBuilder(OnSubdomainChange::class)
-            ->onlyMethods(['sendEmailAfterSubdomainChange'])
-            ->setConstructorArgs(
-                [$this->organizationUtils, $this->accessUtils, $this->mailHub, $this->bindFileService, $this->messageBus]
-            )
-            ->getMock();
-        $onChange->expects(self::once())->method('sendEmailAfterSubdomainChange');
+        $onSubdomainChange->expects(self::once())->method('sendEmailAfterSubdomainChange');
 
         // Le sous-domaine qu'on vient d'activer
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
@@ -164,10 +163,12 @@ class OnSubdomainChangeTest extends TestCase
         $context->method('isPutRequest')->willReturn(true);
         $context->method('isPostRequest')->willReturn(false);
 
-        $onChange->onChange($subdomain, $context);
+        $onSubdomainChange->onChange($subdomain, $context);
     }
 
     public function testOnChangeCreated(): void {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('onChange');
+
         $this->bindFileService->expects(self::once())->method('registerSubdomain');
         $this->messageBus
             ->expects(self::once())
@@ -175,14 +176,7 @@ class OnSubdomainChangeTest extends TestCase
             ->with(self::isInstanceOf(Typo3UpdateCommand::class))
             ->willReturn(new Envelope(new Typo3UpdateCommand(1)));
 
-        $onChange = $this
-            ->getMockBuilder(OnSubdomainChange::class)
-            ->onlyMethods(['sendEmailAfterSubdomainChange'])
-            ->setConstructorArgs(
-                [$this->organizationUtils, $this->accessUtils, $this->mailHub, $this->bindFileService, $this->messageBus]
-            )
-            ->getMock();
-        $onChange->expects(self::once())->method('sendEmailAfterSubdomainChange');
+        $onSubdomainChange->expects(self::once())->method('sendEmailAfterSubdomainChange');
 
         // Le sous-domaine qu'on vient d'activer
         $subdomain = $this->getMockBuilder(Subdomain::class)->disableOriginalConstructor()->getMock();
@@ -198,10 +192,12 @@ class OnSubdomainChangeTest extends TestCase
         $context->method('isPutRequest')->willReturn(false);
         $context->method('isPostRequest')->willReturn(true);
 
-        $onChange->onChange($subdomain, $context);
+        $onSubdomainChange->onChange($subdomain, $context);
     }
 
     public function testSendEmailAfterSubdomainChange(): void {
+        $onSubdomainChange = $this->makeOnSubdomainChangeMock('sendEmailAfterSubdomainChange');
+
         $admin = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
 
         $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
@@ -232,6 +228,6 @@ class OnSubdomainChangeTest extends TestCase
                 ]
             );
 
-        $this->onSubdomainChange->sendEmailAfterSubdomainChange($subdomain);
+        $onSubdomainChange->sendEmailAfterSubdomainChange($subdomain);
     }
 }

+ 140 - 56
tests/Service/Organization/OrganizationProfileCreatorTest.php

@@ -1,85 +1,169 @@
-<?php
+<?php /** @noinspection DuplicatedCode */
+
 namespace App\Test\Service\Organization;
 
 use App\ApiResources\Profile\OrganizationProfile;
+use App\Entity\Network\Network;
+use App\Entity\Network\NetworkOrganization;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Parameters;
 use App\Entity\Organization\Settings;
-use App\Entity\Organization\Subdomain;
 use App\Enum\Organization\PrincipalTypeEnum;
 use App\Service\Network\Tree;
 use App\Service\Organization\OrganizationProfileCreator;
+use App\Service\Organization\Utils as OrganizationUtils;
 use App\Service\Security\Module;
+use Doctrine\Common\Collections\ArrayCollection;
 use PHPUnit\Framework\TestCase;
 
 class OrganizationProfileCreatorTest extends TestCase
 {
-    private Organization  $organization;
-    private Module $moduleMock;
-    private Tree $treeMock;
-    private OrganizationProfileCreator $organizationProfileCreator;
+    private Module $module;
+    private Tree $tree;
+    private OrganizationUtils $organizationUtils;
 
     public function setUp():void
     {
-        $this->organization = new Organization();
-
-        $this->moduleMock = $this->getMockBuilder(Module::class)->disableOriginalConstructor()->getMock();
-        $this->moduleMock
-            ->method('getOrganizationModules')
-            ->with($this->organization)
-            ->willReturn(["MODULE_A", "MODULE_B"]);
-
-        $this->treeMock = $this->getMockBuilder(Tree::class)->disableOriginalConstructor()->getMock();
-        $parent = new Organization();
-        $parent->setName('Parent');
-        $parent->setParameters(new Parameters());
-        $this->treeMock
-            ->method('findAllParentsAndSortByType')
-            ->with($this->organization)
-            ->willReturn([$parent, $parent]);
-
-        $organizationUtils = new \App\Service\Organization\Utils();
-
-        $this->organizationProfileCreator = new OrganizationProfileCreator($this->moduleMock,$this->treeMock, $organizationUtils);
-
-        $this->organization->setPrincipalType(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY());
-        $settings = new Settings();
-        $settings->setProduct('adminassos');
-        $parameters = new Parameters();
-        $parameters->setShowAdherentList(true);
-        $subdomain = new Subdomain();
-
-        $this->organization
-            ->setParameters($parameters)
-            ->setSettings($settings)
-            ->addSubdomain($subdomain)
-            ->setName('Foo')
-        ;
+        $this->module = $this->getMockBuilder(Module::class)->disableOriginalConstructor()->getMock();
+        $this->tree = $this->getMockBuilder(Tree::class)->disableOriginalConstructor()->getMock();
+        $this->organizationUtils = $this->getMockBuilder(OrganizationUtils::class)->disableOriginalConstructor()->getMock();
     }
 
     /**
      * @see OrganizationProfileCreator::createCompleteOrganizationProfile()
      */
-    public function testCreateCompleteOrganizationProfile(){
-        $organizationProfile = $this->organizationProfileCreator->createCompleteOrganizationProfile($this->organization);
-        $this->assertInstanceOf(OrganizationProfile::class, $organizationProfile);
-    }
+    public function testCreateCompleteOrganizationProfile(): void
+    {
+        $organizationProfileCreator = $this->getMockBuilder(OrganizationProfileCreator::class)
+            ->setConstructorArgs([$this->module, $this->tree, $this->organizationUtils])
+            ->setMethodsExcept(['createCompleteOrganizationProfile'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationProfile = $this->getMockBuilder(OrganizationProfile::class)->getMock();
+
+        $modules = ['1'];
+        $this->module->method('getOrganizationModules')->with($organization)->willReturn($modules);
+        $organizationProfile->expects(self::once())->method('setModules')->with($modules);
+
+        $product = "product";
+        $settings = $this->getMockBuilder(Settings::class)->getMock();
+        $settings->method('getProduct')->willReturn($product);
+        $organization->method('getSettings')->willReturn($settings);
+        $organizationProfile->expects(self::once())->method('setProduct')->with($product);
+
+        $parametersId = 101;
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getId')->willReturn($parametersId);
+        $organization->method('getParameters')->willReturn($parameters);
+        $organizationProfile->expects(self::once())->method('setParametersId')->with($parametersId);
+
+        $organization->method('getLegalStatus')->willReturn('foo');
+        $organizationProfile->expects(self::once())->method('setLegalStatus')->with('foo');
+
+        $organization->method('getNetworkOrganizationChildren')->willReturn(new ArrayCollection([1, 2, 3]));
+        $organizationProfile->expects(self::once())->method('setHasChildren')->with(true);
+
+        $parameters->method('getShowAdherentList')->willReturn(true);
+        $organization->method('getPrincipalType')->willReturn(PrincipalTypeEnum::LOCAL_FEDERATION()->getValue());
+        $organizationProfile->expects(self::once())->method('setShowAdherentList')->with(true);
+
+        $network1 = $this->getMockBuilder(Network::class)->getMock();
+        $network1->method('getName')->willReturn('Net 1');
+        $networkOrganization1 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization1->method('getNetwork')->willReturn($network1);
+
+        $network2 = $this->getMockBuilder(Network::class)->getMock();
+        $network2->method('getName')->willReturn('Net 2');
+        $networkOrganization2 = $this->getMockBuilder(NetworkOrganization::class)->getMock();
+        $networkOrganization2->method('getNetwork')->willReturn($network2);
+
+        $organization->method('getNetworkOrganizations')->willReturn(new ArrayCollection([$networkOrganization1, $networkOrganization2]));
+
+        $organizationProfile->expects(self::exactly(2))->method('addNetwork')->withConsecutive(['Net 1'], ['Net 2']);
+
+        $parent1 = $this->getMockBuilder(Organization::class)->getMock();
+        $parent2 = $this->getMockBuilder(Organization::class)->getMock();
+        $this->tree->method('findAllParentsAndSortByType')->willReturn([$parent1, $parent2]);
+
+        $parentProfile1 = $this->getMockBuilder(OrganizationProfile::class)->getMock();
+        $parentProfile2 = $this->getMockBuilder(OrganizationProfile::class)->getMock();
+
+        // Called 3 times, once for the organization, two for its parents
+        $organizationProfileCreator
+            ->expects(self::exactly(3))
+            ->method('createLightOrganizationProfile')
+            ->withConsecutive([$organization], [$parent1], [$parent2])
+            ->willReturnOnConsecutiveCalls($organizationProfile, $parentProfile1, $parentProfile2);
+
+        $organizationProfile
+            ->expects(self::exactly(2))
+            ->method('addParent')
+            ->withConsecutive([$parentProfile1], [$parentProfile2]);
+
+        $this->organizationUtils->method('getOrganizationCurrentActivityYear')->with($organization)->willReturn(2022);
+        $organizationProfile->expects(self::once())->method('setCurrentYear')->with();
 
-    public function testCreateOrganizationProfileWithoutAdherentListBecauseOfPrincipalType(){
-        $organizationProfile = $this->organizationProfileCreator->createCompleteOrganizationProfile($this->organization);
-        $this->assertFalse($organizationProfile->getShowAdherentList());
+        $returned = $organizationProfileCreator->createCompleteOrganizationProfile($organization);
+
+        $this->assertSame(
+            $organizationProfile,
+            $returned
+        );
     }
 
-    public function testCreateOrganizationProfileWithoutAdherentList(){
-        $this->organization->setPrincipalType(PrincipalTypeEnum::ARTISTIC_PRACTICE_ONLY());
-        $this->organization->getParameters()->setShowAdherentList(false);
-        $organizationProfile = $this->organizationProfileCreator->createCompleteOrganizationProfile($this->organization);
-        $this->assertFalse($organizationProfile->getShowAdherentList());
+    /**
+     * If the organization principal type is ARTISTIC_EDUCATION_ONLY, then showAdherentList should be set to false
+     */
+    public function testCreateOrganizationProfileWithoutAdherentListBecauseOfPrincipalType(): void
+    {
+        $organizationProfileCreator = $this->getMockBuilder(OrganizationProfileCreator::class)
+            ->setConstructorArgs([$this->module, $this->tree, $this->organizationUtils])
+            ->setMethodsExcept(['createCompleteOrganizationProfile'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationProfile = $this->getMockBuilder(OrganizationProfile::class)->getMock();
+        $organizationProfileCreator->method('createLightOrganizationProfile')->with($organization)->willReturn($organizationProfile);
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $parameters->method('getShowAdherentList')->willReturn(true);
+        $organization->method('getPrincipalType')->willReturn(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY()->getValue());
+        $organizationProfile->expects(self::once())->method('setShowAdherentList')->with(false);
+
+        $organization->method('getNetworkOrganizations')->willReturn(new ArrayCollection([]));
+        $this->tree->method('findAllParentsAndSortByType')->willReturn([]);
+
+        $organizationProfileCreator->createCompleteOrganizationProfile($organization);
+
     }
 
-    public function testCreateOrganizationProfileWithAdherentList(){
-        $this->organization->setPrincipalType(PrincipalTypeEnum::ARTISTIC_PRACTICE_ONLY());
-        $organizationProfile = $this->organizationProfileCreator->createCompleteOrganizationProfile($this->organization);
-        $this->assertTrue($organizationProfile->getShowAdherentList());
+    /**
+     * If the parameters::showAdherentList is false, then organizationProfile::showAdherentList should be set to false
+     */
+    public function testCreateOrganizationProfileWithoutAdherentList(): void
+    {
+        $organizationProfileCreator = $this->getMockBuilder(OrganizationProfileCreator::class)
+            ->setConstructorArgs([$this->module, $this->tree, $this->organizationUtils])
+            ->setMethodsExcept(['createCompleteOrganizationProfile'])
+            ->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationProfile = $this->getMockBuilder(OrganizationProfile::class)->getMock();
+        $organizationProfileCreator->method('createLightOrganizationProfile')->with($organization)->willReturn($organizationProfile);
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $parameters->method('getShowAdherentList')->willReturn(false);
+        $organization->method('getPrincipalType')->willReturn(PrincipalTypeEnum::LOCAL_FEDERATION()->getValue());
+        $organizationProfile->expects(self::once())->method('setShowAdherentList')->with(false);
+
+        $organization->method('getNetworkOrganizations')->willReturn(new ArrayCollection([]));
+        $this->tree->method('findAllParentsAndSortByType')->willReturn([]);
+
+        $organizationProfileCreator->createCompleteOrganizationProfile($organization);
     }
 }

+ 130 - 78
tests/Service/Organization/UtilsTest.php

@@ -1,121 +1,168 @@
-<?php
+<?php /** @noinspection PhpUnhandledExceptionInspection */
+
 namespace App\Test\Service\Organization;
 
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Parameters;
 use App\Entity\Organization\Settings;
+use App\Enum\Organization\OrganizationIdsEnum;
 use App\Enum\Organization\SettingsProductEnum;
-use App\Service\Organization\Utils;
 use App\Service\Organization\Utils as OrganizationUtils;
 use PHPUnit\Framework\TestCase;
 
-class UtilsTest extends TestCase
-{
-    private OrganizationUtils $organizationUtils;
-    private Organization $organization;
-    private Organization $federation;
-
-    public function setUp():void
-    {
-        $settings = new Settings();
-        $settings->setProduct(SettingsProductEnum::ARTIST_PREMIUM());
-        $this->organization = new Organization();
-        $this->organization->setSettings($settings);
-
-        $settings = new Settings();
-        $settings->setProduct(SettingsProductEnum::MANAGER());
-        $this->federation = new Organization();
-        $this->federation->setSettings($settings);
-
-        $this->organizationUtils = new OrganizationUtils();
+class TestableOrganizationUtils extends OrganizationUtils {
+    public function isOrganizationIdEqualTo(Organization $organization, OrganizationIdsEnum $organizationIdsEnum): bool {
+        return parent::isOrganizationIdEqualTo($organization, $organizationIdsEnum);
     }
+}
 
+class UtilsTest extends TestCase
+{
     /**
      * @see OrganizationUtils::isStructure()
      */
-    public function testIsStructureTest(){
-        $this->assertTrue($this->organizationUtils->isStructure($this->organization));
+    public function testIsStructure(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['isStructure'])->getMock();
+
+        $settings = $this->getMockBuilder(Settings::class)->getMock();
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getSettings')->willReturn($settings);
+
+        // Each cal to 'isStructure' provoke 2 calls on getProduct
+        $settings->method('getProduct')->willReturnOnConsecutiveCalls(
+            SettingsProductEnum::ARTIST()->getValue(),
+            SettingsProductEnum::ARTIST()->getValue(),
+            SettingsProductEnum::ARTIST_PREMIUM()->getValue(),
+            SettingsProductEnum::ARTIST_PREMIUM()->getValue(),
+            SettingsProductEnum::SCHOOL()->getValue(),
+            SettingsProductEnum::SCHOOL()->getValue(),
+            SettingsProductEnum::SCHOOL_PREMIUM()->getValue(),
+            SettingsProductEnum::SCHOOL_PREMIUM()->getValue(),
+            SettingsProductEnum::MANAGER()->getValue(),
+            SettingsProductEnum::MANAGER()->getValue(),
+            SettingsProductEnum::MANAGER_PREMIUM()->getValue(),
+            SettingsProductEnum::MANAGER_PREMIUM()->getValue(),
+        );
+
+        $this->assertTrue($organizationUtils->isStructure($organization));
+        $this->assertTrue($organizationUtils->isStructure($organization));
+        $this->assertTrue($organizationUtils->isStructure($organization));
+        $this->assertTrue($organizationUtils->isStructure($organization));
+        $this->assertFalse($organizationUtils->isStructure($organization));
+        $this->assertFalse($organizationUtils->isStructure($organization));
     }
 
     /**
      * @see OrganizationUtils::isStructure()
      */
-    public function testIsNotStructureTest(){
-        $this->assertFalse($this->organizationUtils->isStructure($this->federation));
+    public function testIsManager(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['isManager'])->getMock();
+
+        $settings = $this->getMockBuilder(Settings::class)->getMock();
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getSettings')->willReturn($settings);
+
+        $settings->method('getProduct')->willReturnOnConsecutiveCalls(
+            SettingsProductEnum::ARTIST()->getValue(),
+            SettingsProductEnum::ARTIST_PREMIUM()->getValue(),
+            SettingsProductEnum::SCHOOL()->getValue(),
+            SettingsProductEnum::SCHOOL_PREMIUM()->getValue(),
+            SettingsProductEnum::MANAGER()->getValue(),
+            SettingsProductEnum::MANAGER_PREMIUM()->getValue(),
+        );
+
+        $this->assertFalse($organizationUtils->isManager($organization));
+        $this->assertFalse($organizationUtils->isManager($organization));
+        $this->assertFalse($organizationUtils->isManager($organization));
+        $this->assertFalse($organizationUtils->isManager($organization));
+        $this->assertTrue($organizationUtils->isManager($organization));
+        $this->assertFalse($organizationUtils->isManager($organization));
     }
 
     /**
-     * @see OrganizationUtils::isManager()
+     * @see OrganizationUtils::is2iosOrganization()
      */
-    public function testIsManagerTest(){
-        $this->assertTrue($this->organizationUtils->isManager($this->federation));
-    }
+    public function testIsOrganizationIs2ios(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['is2iosOrganization'])->getMock();
 
-    /**
-     * @see OrganizationUtils::isManager()
-     */
-    public function testIsNotManagerTest(){
-        $this->assertFalse($this->organizationUtils->isManager($this->organization));
-    }
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
 
-    /**
-     * @see OrganizationUtils::isOrganizationIs2ios()
-     */
-    public function testIsOrganizationIs2ios(){
-        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock
-            ->method('getId')
-            ->willReturn(32366);
-        $this->assertTrue($this->organizationUtils->isOrganizationIs2ios($organizationMock));
+        $organizationUtils->expects(self::once())->method('isOrganizationIdEqualTo')->with($organization, OrganizationIdsEnum::_2IOS());
+
+        $organizationUtils->is2iosOrganization($organization);
     }
 
     /**
-     * @see OrganizationUtils::isOrganizationIs2ios()
+     * @see OrganizationUtils::isOrganizationCMF()
      */
-    public function testIsNotOrganizationIs2ios(){
-        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock
-            ->method('getId')
-            ->willReturn(1);
-        $this->assertFalse($this->organizationUtils->isOrganizationIs2ios($organizationMock));
+    public function testIsOrganizationIsCMF(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['isOrganizationCMF'])->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+
+        $organizationUtils->expects(self::once())->method('isOrganizationIdEqualTo')->with($organization, OrganizationIdsEnum::CMF());
+
+        $organizationUtils->isOrganizationCMF($organization);
     }
 
+
     /**
-     * @see OrganizationUtils::isOrganizationIsCMF()
+     * @see OrganizationUtils::is2iosOrganization()
      */
-    public function testIsOrganizationIsCMF(){
-        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
-        $organizationMock
-            ->method('getId')
-            ->willReturn(12097);
-        $this->assertTrue($this->organizationUtils->isOrganizationIsCMF($organizationMock));
+    public function testIsOrganizationIdEqualTo(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['isOrganizationIdEqualTo'])->getMock();
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getId')->willReturnOnConsecutiveCalls(123, OrganizationIdsEnum::_2IOS()->getValue());
+
+        $this->assertFalse($organizationUtils->isOrganizationIdEqualTo($organization, OrganizationIdsEnum::_2IOS()));
+        $this->assertTrue($organizationUtils->isOrganizationIdEqualTo($organization, OrganizationIdsEnum::_2IOS()));
     }
 
     /**
      * @see OrganizationUtils::getOrganizationCurrentActivityYear()
      */
-    public function testGetOrganizationCurrentActivityYear(){
-        $parameters = new Parameters();
-        $parameters->setMusicalDate(new \DateTime('2020-09-01'));
-        $this->organization->setParameters($parameters);
+    public function testGetOrganizationCurrentActivityYear(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['getOrganizationCurrentActivityYear'])->getMock();
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getMusicalDate')->willReturn(new \DateTime('2020-09-01'));
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
 
         $today = new \DateTime('now');
-        if($today->format('m') < 9)
-            $this->assertEquals( ($today->format('Y') - 1), $this->organizationUtils->getOrganizationCurrentActivityYear($this->organization));
-        else
-            $this->assertEquals($today->format('Y'), $this->organizationUtils->getOrganizationCurrentActivityYear($this->organization));
+        $expected = (int)$today->format('Y');
+        if ((int)$today->format('m') < 9) {
+            --$expected;
+        }
+
+        $this->assertEquals(
+            $expected,
+            $organizationUtils->getOrganizationCurrentActivityYear($organization)
+        );
     }
 
     /**
      * @see OrganizationUtils::getActivityPeriodsSwitchYear()
      */
-    public function testGetActivityPeriodsSwitchYear(){
-        $parameters = new Parameters();
-        $parameters->setMusicalDate(new \DateTime('2020-09-05'));
-        $this->organization->setParameters($parameters);
+    public function testGetActivityPeriodsSwitchYear(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['getActivityPeriodsSwitchYear'])->getMock();
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getMusicalDate')->willReturn(new \DateTime('2020-09-05'));
 
-        $organizationUtils = new \App\Service\Organization\Utils();
-        $periods = $organizationUtils->getActivityPeriodsSwitchYear($this->organization, 2022);
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
+
+        $periods = $organizationUtils->getActivityPeriodsSwitchYear($organization, 2022);
 
         $this->assertEquals('2022-09-05', $periods['dateStart']);
         $this->assertEquals('2023-09-04', $periods['dateEnd']);
@@ -124,12 +171,17 @@ class UtilsTest extends TestCase
     /**
      * @see OrganizationUtils::getActivityYearSwitchDate()
      */
-    public function testgetActivityYearSwitchDate(){
-        $parameters = new Parameters();
-        $parameters->setMusicalDate(new \DateTime('2020-09-05'));
-        $this->organization->setParameters($parameters);
+    public function testgetActivityYearSwitchDate(): void
+    {
+        $organizationUtils = $this->getMockBuilder(TestableOrganizationUtils::class)->setMethodsExcept(['getActivityYearSwitchDate'])->getMock();
+
+        $parameters = $this->getMockBuilder(Parameters::class)->getMock();
+        $parameters->method('getMusicalDate')->willReturn(new \DateTime('2020-09-05'));
+
+        $organization = $this->getMockBuilder(Organization::class)->getMock();
+        $organization->method('getParameters')->willReturn($parameters);
 
-        $this->assertEquals(2022, $this->organizationUtils->getActivityYearSwitchDate($this->organization, new \DateTime('2022-09-10')));
-        $this->assertEquals(2021, $this->organizationUtils->getActivityYearSwitchDate($this->organization, new \DateTime('2022-09-02')));
+        $this->assertEquals(2022, $organizationUtils->getActivityYearSwitchDate($organization, new \DateTime('2022-09-10')));
+        $this->assertEquals(2021, $organizationUtils->getActivityYearSwitchDate($organization, new \DateTime('2022-09-02')));
     }
 }

+ 34 - 21
tests/Service/Rest/ApiRequestServiceTest.php

@@ -19,10 +19,11 @@ class ApiRequestServiceTest extends TestCase
         $this->client = $this->getMockBuilder(HttpClientInterface::class)->disableOriginalConstructor()->getMock();
     }
 
-    public function testGetJsonContent() {
+    public function testGetJsonContent(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['getContent'])
+            ->setMethodsExcept(['getJsonContent'])
             ->getMock();
 
         $apiRequestService->expects(self::once())
@@ -35,10 +36,11 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals(['foo' => 'bar'], $data);
     }
 
-    public function testGetContent() {
+    public function testGetContent(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['get'])
+            ->setMethodsExcept(['getContent'])
             ->getMock();
 
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
@@ -54,10 +56,11 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals('{foo: bar}', $content);
     }
 
-    public function testGetContentWithError() {
+    public function testGetContentWithError(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['get'])
+            ->setMethodsExcept(['getContent'])
             ->getMock();
 
         $apiRequestService->expects(self::once())
@@ -68,10 +71,11 @@ class ApiRequestServiceTest extends TestCase
         $apiRequestService->getContent('path/to/data');
     }
 
-    public function testGet() {
+    public function testGet(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['request'])
+            ->setMethodsExcept(['get'])
             ->getMock();
 
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
@@ -86,10 +90,11 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals($response, $actualResponse);
     }
 
-    public function testPost() {
+    public function testPost(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['request'])
+            ->setMethodsExcept(['post'])
             ->getMock();
 
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
@@ -104,10 +109,11 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals($response, $actualResponse);
     }
 
-    public function testPut() {
+    public function testPut(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['request'])
+            ->setMethodsExcept(['put'])
             ->getMock();
 
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
@@ -122,10 +128,11 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals($response, $actualResponse);
     }
 
-    public function testDelete() {
+    public function testDelete(): void
+    {
         $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
             ->setConstructorArgs([$this->client])
-            ->onlyMethods(['request'])
+            ->setMethodsExcept(['delete'])
             ->getMock();
 
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
@@ -140,24 +147,30 @@ class ApiRequestServiceTest extends TestCase
         $this->assertEquals($response, $actualResponse);
     }
 
-    public function testRequest() {
-        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
+    public function testRequest(): void
+    {
+        $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['request'])
+            ->getMock();
 
+        $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $this->client->expects(self::once())->method('request')->with('GET', 'path/to/data?param=1', [])->willReturn($response);
 
-        $apiRequestService = new ApiRequestService($this->client);
-
         $actualResponse = $apiRequestService->request('GET', 'path/to/data', ['param' => 1]);
 
         $this->assertEquals($response, $actualResponse);
     }
 
-    public function testRequestWithError() {
+    public function testRequestWithError(): void
+    {
+        $apiRequestService = $this->getMockBuilder(ApiRequestService::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['request'])
+            ->getMock();
 
         $this->client->expects(self::once())->method('request')->willThrowException(new TransportException('error', 500));
 
-        $apiRequestService = new ApiRequestService($this->client);
-
         $this->expectException(HttpException::class);
         $apiRequestService->request('GET', 'path/to/data');
     }

+ 19 - 13
tests/Service/Rest/Operation/BaseRestOperationTest.php

@@ -20,7 +20,8 @@ class BaseRestOperationTest extends TestCase
             ->getMock();
     }
 
-    public function testGetters() {
+    public function testGetters(): void
+    {
         $operation = new TestableBaseRestOperation(
             'a label',
             'GET',
@@ -43,11 +44,12 @@ class BaseRestOperationTest extends TestCase
     /**
      * Test execution with a valid request
      */
-    public function testExecuteValid()
+    public function testExecuteValid(): void
     {
-        $operation = new TestableBaseRestOperation(
-            'Update entity 1', 'PUT', 'entity/1', [], [], ['json' => '{"a":1}']
-        );
+        $operation = $this->getMockBuilder(TestableBaseRestOperation::class)
+            ->setConstructorArgs(['Update entity 1', 'PUT', 'entity/1', [], [], ['json' => '{"a":1}']])
+            ->setMethodsExcept(['execute', 'getStatus', 'getErrorMessage'])
+            ->getMock();
 
         $responseOk = $this->getMockBuilder(ResponseInterface::class)->getMock();
         $responseOk->method('getStatusCode')->willReturn(200);
@@ -59,6 +61,7 @@ class BaseRestOperationTest extends TestCase
             ->willReturn($responseOk);
 
         $operation->execute($this->apiRequestService);
+
         $this->assertEquals(BaseRestOperation::STATUS_DONE, $operation->getStatus());
         $this->assertEquals("", $operation->getErrorMessage());
     }
@@ -66,11 +69,12 @@ class BaseRestOperationTest extends TestCase
     /**
      * Test execution with an invalid request (api returns an error 404 for example)
      */
-    public function testExecuteInvalid()
+    public function testExecuteInvalid(): void
     {
-        $operation = new TestableBaseRestOperation(
-            'Update entity 1', 'PUT', 'entity/2'
-        );
+        $operation = $this->getMockBuilder(TestableBaseRestOperation::class)
+            ->setConstructorArgs(['Update entity 1', 'PUT', 'entity/2'])
+            ->setMethodsExcept(['execute', 'getStatus', 'getErrorMessage'])
+            ->getMock();
 
         $responseError = $this->getMockBuilder(ResponseInterface::class)->getMock();
         $responseError->method('getStatusCode')->willReturn(404);
@@ -93,10 +97,12 @@ class BaseRestOperationTest extends TestCase
     /**
      * Test execution if the request throw an HTTP exception
      */
-    public function testExecutionError() {
-        $operation = new TestableBaseRestOperation(
-            'Update entity 1', 'PUT', 'entity/3'
-        );
+    public function testExecutionError(): void
+    {
+        $operation = $this->getMockBuilder(TestableBaseRestOperation::class)
+            ->setConstructorArgs(['Update entity 1', 'PUT', 'entity/3'])
+            ->setMethodsExcept(['execute', 'getStatus', 'getErrorMessage'])
+            ->getMock();
 
         $responseException = $this->getMockBuilder(ResponseInterface::class)->getMock();
         $responseException->method('getStatusCode')->willReturn(500);

+ 4 - 2
tests/Service/Rest/Operation/CreateOperationTest.php

@@ -5,7 +5,8 @@ use PHPUnit\Framework\TestCase;
 
 class CreateOperationTest extends TestCase
 {
-    public function testGetters() {
+    public function testGetters(): void
+    {
         $operation = new CreateOperation(
             'Create a dinosaur',
             'dinosaur',
@@ -20,7 +21,8 @@ class CreateOperationTest extends TestCase
         $this->assertEquals('POST dinosaur', (string)$operation);
     }
 
-    public function testGetChangeLog() {
+    public function testGetChangeLog(): void
+    {
         $operation = new CreateOperation(
             'Create a dinosaur',
             'dinosaur',

+ 24 - 10
tests/Service/Security/ModuleTest.php

@@ -8,10 +8,11 @@ use App\Service\Utils\Reflection;
 use Doctrine\Common\Collections\ArrayCollection;
 use PHPUnit\Framework\TestCase;
 use App\Service\Security\Module;
+use App\Service\Cotisation\Utils as CotisationUtils;
 
 class ModuleTest extends TestCase
 {
-    const OPENTALENT_CONFIG = __DIR__.'/../../../config/opentalent';
+    private const OPENTALENT_CONFIG = __DIR__.'/../../../config/opentalent';
 
     private Reflection $reflectionMock;
     private Parser $parser;
@@ -22,10 +23,11 @@ class ModuleTest extends TestCase
         $this->parser = new Parser();
     }
 
-    public function testGetOrganizationModules() {
+    public function testGetOrganizationModules(): void
+    {
         $module = $this->getMockBuilder(Module::class)
-            ->onlyMethods(['getModuleBySettings', 'getModulesByConditions', 'getModulesByProductConfiguration'])
-            ->disableOriginalConstructor()
+            ->setConstructorArgs([$this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG])
+            ->setMethodsExcept(['getOrganizationModules'])
             ->getMock();
 
         $module->expects(self::once())->method('getModuleBySettings')->willReturn(['Sms']);
@@ -48,7 +50,12 @@ class ModuleTest extends TestCase
     /**
      * @see Module::getModuleBySettings()
      */
-    public function testGetModuleBySettings(){
+    public function testGetModuleBySettings(): void
+    {
+        $module = $this->getMockBuilder(Module::class)
+            ->setConstructorArgs([$this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG])
+            ->setMethodsExcept(['getModuleBySettings'])
+            ->getMock();
 
         $settingsMock = $this->getMockBuilder(Settings::class)->getMock();
         $settingsMock
@@ -62,7 +69,6 @@ class ModuleTest extends TestCase
             ->method('getSettings')
             ->willReturn($settingsMock);
 
-        $module = new Module($this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG);
         $value = "Sms";
         // assert function to test whether 'value' is a value of array
         $this->assertContains($value, $module->getModuleBySettings($organizationMock)) ;
@@ -71,20 +77,24 @@ class ModuleTest extends TestCase
     /**
      * @see Module::getModulesByConditions()
      */
-    public function testGetModulesByConditions()
+    public function testGetModulesByConditions(): void
     {
+        $module = $this->getMockBuilder(Module::class)
+            ->setConstructorArgs([$this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG])
+            ->setMethodsExcept(['getModulesByConditions'])
+            ->getMock();
+
         $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
         $this->reflectionMock
             ->method('dynamicInvokeServiceWithArgsAndMethod')
             ->withConsecutive(
-                ['App\\Service\\Cotisation\\Utils', 'isLastParentAndCMF', array($organizationMock)]
+                [CotisationUtils::class, 'isLastParentAndCMF', array($organizationMock)]
             )
             ->willReturnOnConsecutiveCalls(
                 [true]
             )
         ;
 
-        $module = new Module($this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG);
         $value = "CotisationCall";
         // assert function to test whether 'value' is a value of array
         $this->assertContains($value, $module->getModulesByConditions($organizationMock)) ;
@@ -95,7 +105,11 @@ class ModuleTest extends TestCase
      */
     public function testGetModulesByProductConfiguration()
     {
-        $module = new Module($this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG);
+        $module = $this->getMockBuilder(Module::class)
+            ->setConstructorArgs([$this->reflectionMock, $this->parser, self::OPENTALENT_CONFIG])
+            ->setMethodsExcept(['getModulesByProductConfiguration'])
+            ->getMock();
+
         $value = "MessagesAdvanced";
         // assert function to test whether 'value' is a value of array
         $this->assertContains($value, $module->getModulesByProductConfiguration('artist-premium')) ;

+ 21 - 21
tests/Service/Security/SwitchUserTest.php

@@ -8,41 +8,41 @@ use PHPUnit\Framework\TestCase;
 
 class SwitchUserTest extends TestCase
 {
-    public function setUp():void
-    {
-    }
-
     /**
      * @see SwitchUser::isAllowedToSwitch()
      */
-    public function testIsAllowedToSwitch(){
-        $childrenMockMock = $this->getMockBuilder(Access::class)->getMock();
-
-        $children = new ArrayCollection();
-        $children->add($childrenMockMock);
+    public function testIsAllowedToSwitch(): void
+    {
+        $switchUser = $this->getMockBuilder(SwitchUser::class)
+            ->setMethodsExcept(['isAllowedToSwitch'])
+            ->getMock();
 
-        $userMockMock = $this->getMockBuilder(Access::class)->getMock();
-        $userMockMock
+        $children = $this->getMockBuilder(Access::class)->getMock();
+        $user = $this->getMockBuilder(Access::class)->getMock();
+        $user
             ->expects($this->once())
             ->method('getChildren')
-            ->willReturn($children);
+            ->willReturn(new ArrayCollection([$children]));
 
-        $switchUser = new SwitchUser();
-        $this->assertTrue($switchUser->isAllowedToSwitch($userMockMock, $childrenMockMock));
+        $this->assertTrue($switchUser->isAllowedToSwitch($user, $children));
     }
 
     /**
      * @see SwitchUser::isAllowedToSwitch()
      */
-    public function testIsNotAllowedToSwitch(){
-        $childrenMockMock = $this->getMockBuilder(Access::class)->getMock();
-        $userMockMock = $this->getMockBuilder(Access::class)->getMock();
-        $userMockMock
+    public function testIsNotAllowedToSwitch(): void
+    {
+        $switchUser = $this->getMockBuilder(SwitchUser::class)
+            ->setMethodsExcept(['isAllowedToSwitch'])
+            ->getMock();
+
+        $children = $this->getMockBuilder(Access::class)->getMock();
+        $user = $this->getMockBuilder(Access::class)->getMock();
+        $user
             ->expects($this->once())
             ->method('getChildren')
             ->willReturn(new ArrayCollection());
 
-        $switchUser = new SwitchUser();
-        $this->assertFalse($switchUser->isAllowedToSwitch($userMockMock, $childrenMockMock));
+        $this->assertFalse($switchUser->isAllowedToSwitch($user, $children));
     }
-}
+}

+ 7 - 2
tests/Service/ServiceIterator/CurrentAccessExtensionIteratorTest.php

@@ -7,7 +7,8 @@ use PHPUnit\Framework\TestCase;
 
 class CurrentAccessExtensionIteratorTest extends TestCase
 {
-    public function testAddWhere() {
+    public function testAddWhere(): void
+    {
         $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -26,7 +27,11 @@ class CurrentAccessExtensionIteratorTest extends TestCase
 
         $extensions = [$ext1, $ext2, $ext3];
 
-        $iterator = new CurrentAccessExtensionIterator($extensions);
+        $iterator = $this->getMockBuilder(CurrentAccessExtensionIterator::class)
+            ->setConstructorArgs([$extensions])
+            ->setMethodsExcept(['addWhere'])
+            ->getMock();
+
         $actualExt = $iterator->addWhere($queryBuilder, 'foo');
 
         $this->assertEquals(true, $actualExt);

+ 13 - 4
tests/Service/ServiceIterator/EncoderIteratorTest.php

@@ -6,7 +6,8 @@ use PHPUnit\Framework\TestCase;
 
 class EncoderIteratorTest extends TestCase
 {
-    public function testGetEncoderFor() {
+    public function testGetEncoderFor(): void
+    {
         $mocker = $this->getMockBuilder(EncoderInterface::class);
 
         $encoder1 = $mocker->getMock();
@@ -20,13 +21,18 @@ class EncoderIteratorTest extends TestCase
 
         $encoders = [$encoder1, $encoder2, $encoder3];
 
-        $iterator = new EncoderIterator($encoders);
+        $iterator = $this->getMockBuilder(EncoderIterator::class)
+            ->setConstructorArgs([$encoders])
+            ->setMethodsExcept(['getEncoderFor'])
+            ->getMock();
+
         $actualEncoder = $iterator->getEncoderFor('pdf');
 
         $this->assertEquals($encoder2, $actualEncoder);
     }
 
-    public function testGetEncoderForError() {
+    public function testGetEncoderForError(): void
+    {
         $mocker = $this->getMockBuilder(EncoderInterface::class);
 
         $encoder1 = $mocker->getMock();
@@ -37,7 +43,10 @@ class EncoderIteratorTest extends TestCase
 
         $encoders = [$encoder1, $encoder2];
 
-        $iterator = new EncoderIterator($encoders);
+        $iterator = $this->getMockBuilder(EncoderIterator::class)
+            ->setConstructorArgs([$encoders])
+            ->setMethodsExcept(['getEncoderFor'])
+            ->getMock();
 
         $this->expectException(Exception::class);
         $iterator->getEncoderFor('gif');

+ 13 - 4
tests/Service/ServiceIterator/ExporterIteratorTest.php

@@ -9,7 +9,8 @@ use PHPUnit\Framework\TestCase;
 
 class ExporterIteratorTest extends TestCase
 {
-    public function testGetExporterFor() {
+    public function testGetExporterFor(): void
+    {
         $exportRequest = $this->getMockBuilder(ExportRequest::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -27,13 +28,18 @@ class ExporterIteratorTest extends TestCase
 
         $exporters = [$exporter1, $exporter2, $exporter3];
 
-        $iterator = new ExporterIterator($exporters);
+        $iterator = $this->getMockBuilder(ExporterIterator::class)
+            ->setConstructorArgs([$exporters])
+            ->setMethodsExcept(['getExporterFor'])
+            ->getMock();
+
         $actualExporter = $iterator->getExporterFor($exportRequest);
 
         $this->assertEquals($exporter2, $actualExporter);
     }
 
-    public function testGetExporterForError() {
+    public function testGetExporterForError(): void
+    {
         $exportRequest = $this->getMockBuilder(ExportRequest::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -48,7 +54,10 @@ class ExporterIteratorTest extends TestCase
 
         $exporters = [$exporter1, $exporter2];
 
-        $iterator = new ExporterIterator($exporters);
+        $iterator = $this->getMockBuilder(ExporterIterator::class)
+            ->setConstructorArgs([$exporters])
+            ->setMethodsExcept(['getExporterFor'])
+            ->getMock();
 
         $this->expectException(Exception::class);
         $iterator->getExporterFor($exportRequest);

+ 29 - 7
tests/Service/ServiceIterator/OptionalsRolesIteratorTest.php

@@ -7,10 +7,9 @@ use PHPUnit\Framework\TestCase;
 
 class OptionalsRolesIteratorTest extends TestCase
 {
-    public function testAddWhere() {
-        $access = $this->getMockBuilder(Access::class)
-            ->disableOriginalConstructor()
-            ->getMock();
+    public function testAddWhere(): void
+    {
+        $access = $this->getMockBuilder(Access::class)->getMock();
 
         $mocker = $this->getMockBuilder(OptionalsRolesInterface::class);
 
@@ -30,14 +29,37 @@ class OptionalsRolesIteratorTest extends TestCase
 
         $roles = [$role1, $role2, $role3, $role4];
 
-        $iterator = new OptionalsRolesIterator($roles);
+        $iterator = $this->getMockBuilder(OptionalsRolesIterator::class)
+            ->setConstructorArgs([$roles])
+            ->setMethodsExcept(['getOptionalsRoles'])
+            ->getMock();
+
         $actualRoles = $iterator->getOptionalsRoles($access);
 
         $this->assertEquals(['ROLE2', 'ROLE4'], $actualRoles);
 
-        $roles = [$role1, $role3];
 
-        $iterator = new OptionalsRolesIterator($roles);
+    }
+
+    public function testAddWhereNotFound(): void
+    {
+        $access = $this->getMockBuilder(Access::class)->getMock();
+
+        $mocker = $this->getMockBuilder(OptionalsRolesInterface::class);
+
+        $role1 = $mocker->getMock();
+        $role1->method('support')->willReturn(false);
+
+        $role2 = $mocker->getMock();
+        $role2->method('support')->willReturn(false);
+
+        $roles = [$role1, $role2];
+
+        $iterator = $this->getMockBuilder(OptionalsRolesIterator::class)
+            ->setConstructorArgs([$roles])
+            ->setMethodsExcept(['getOptionalsRoles'])
+            ->getMock();
+
         $actualRoles = $iterator->getOptionalsRoles($access);
 
         $this->assertEquals([], $actualRoles);

+ 7 - 2
tests/Service/Storage/TemporaryFileStorageTest.php

@@ -8,7 +8,8 @@ use PHPUnit\Framework\TestCase;
 
 class TemporaryFileStorageTest extends TestCase
 {
-    public function testGetStorageBaseDir() {
+    public function testGetStorageBaseDir(): void
+    {
         $fileSystemMap = $this->getMockBuilder(FilesystemMap::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -23,7 +24,11 @@ class TemporaryFileStorageTest extends TestCase
         $fileSystem->method('getAdapter')->willReturn($adapter);
         $adapter->expects($this->once())->method('write')->willReturnSelf();
 
-        $storage = new TemporaryFileStorage($fileSystemMap);
+        $storage = $this->getMockBuilder(TemporaryFileStorage::class)
+            ->setConstructorArgs([$fileSystemMap])
+            ->setMethodsExcept(['write'])
+            ->getMock();
+
         $path = $storage->write('my_file.txt', 'some content');
 
         $this->assertMatchesRegularExpression(

+ 48 - 29
tests/Service/Typo3/Typo3ServiceTest.php

@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection PhpUnhandledExceptionInspection */
 
 namespace App\Test\Service\Typo3;
 
@@ -29,14 +29,18 @@ class Typo3ServiceTest extends TestCase
             ->with('GET', '/typo3/index.php?route=foo&param=bar')
             ->willReturn($response);
 
-        $typo3Service = new TestableTypo3Service($this->typo3Client);
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setConstructorArgs([$this->typo3Client])
+            ->setMethodsExcept(['sendCommand'])
+            ->getMock();
 
         $typo3Service->sendCommand('foo', ['param' => 'bar']);
     }
 
-    public function testCreateSite() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testCreateSite(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['createSite'])
             ->disableOriginalConstructor()
             ->getMock();
 
@@ -49,12 +53,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->createSite(1);
     }
 
-    public function testClearSiteCache() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testClearSiteCache(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['updateSite'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -64,12 +70,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->updateSite(1);
     }
 
-    public function testDeleteSite() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testDeleteSite(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['deleteSite'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -79,12 +87,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->deleteSite(1);
     }
 
-    public function testUndeleteSite() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testUndeleteSite(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['undeleteSite'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -94,12 +104,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->undeleteSite(1);
     }
 
-    public function testSetSiteDomain() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testSetSiteDomain(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['setSiteDomain'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -109,12 +121,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->setSiteDomain(1, 'new-domain', false);
     }
 
-    public function testSetSiteDomainWithRedirection() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testSetSiteDomainWithRedirection(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['setSiteDomain'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -124,12 +138,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->setSiteDomain(1, 'new-domain', true);
     }
 
-    public function testResetSitePerms() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testResetSitePerms(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['resetSitePerms'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -139,12 +155,14 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->resetSitePerms(1);
     }
 
-    public function testGetSiteStatus() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testGetSiteStatus(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['getSiteStatus'])
             ->disableOriginalConstructor()
             ->getMock();
 
+
         $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
         $typo3Service->expects(self::once())
             ->method('sendCommand')->
@@ -154,9 +172,10 @@ class Typo3ServiceTest extends TestCase
         $typo3Service->getSiteStatus(1);
     }
 
-    public function testAddRedirection() {
-        $typo3Service = $this->getMockBuilder(Typo3Service::class)
-            ->onlyMethods(['sendCommand'])
+    public function testAddRedirection(): void
+    {
+        $typo3Service = $this->getMockBuilder(TestableTypo3Service::class)
+            ->setMethodsExcept(['addRedirection'])
             ->disableOriginalConstructor()
             ->getMock();
 

+ 9 - 7
tests/Service/Utils/ArrayUtilsTest.php

@@ -9,10 +9,12 @@ class ArrayUtilsTest extends TestCase
 {
     public function testGetChanges(): void
     {
+        $arrayUtils = new ArrayUtils();
+
         // Non-recursive (default)
         $this->assertEquals(
             ['b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                 ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
             )
@@ -21,7 +23,7 @@ class ArrayUtilsTest extends TestCase
         // Recursive
         $this->assertEquals(
             ['b' => -2, 'c' => ['e' => ['f' => -5]], 'g' => 7],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                 ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
                 true
@@ -31,7 +33,7 @@ class ArrayUtilsTest extends TestCase
         // Recursive with unchanged sub array
         $this->assertEquals(
             ['b' => -2],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                 ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                 true
@@ -41,7 +43,7 @@ class ArrayUtilsTest extends TestCase
         // No changes
         $this->assertEquals(
             [],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                 ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
             )
@@ -50,7 +52,7 @@ class ArrayUtilsTest extends TestCase
         // Empty arrays
         $this->assertEquals(
             [],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 [],
                 [],
             )
@@ -59,7 +61,7 @@ class ArrayUtilsTest extends TestCase
         // First array is empty
         $this->assertEquals(
             ['a' => 1],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 [],
                 ['a' => 1],
             )
@@ -68,7 +70,7 @@ class ArrayUtilsTest extends TestCase
         // With callback
         $this->assertEquals(
             ['a' => 2],
-            ArrayUtils::getChanges(
+            $arrayUtils->getChanges(
                 ['a' => 1, 'b' => ''],
                 ['a' => 2, 'b' => null],
                 false,

+ 106 - 34
tests/Service/Utils/GpsCoordinateUtilsTest.php

@@ -7,14 +7,19 @@ use PHPUnit\Framework\TestCase;
 use Symfony\Component\HttpClient\MockHttpClient;
 use Symfony\Component\HttpClient\Response\MockResponse;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+use Symfony\Contracts\HttpClient\ResponseInterface;
 
 class GpsCoordinateUtilsTest extends TestCase
 {
+    private HttpClientInterface $client;
     private string $response;
     private string $responseReverse;
 
     public function setUp(): void
     {
+        $this->client = $this->getMockBuilder(HttpClientInterface::class)->disableOriginalConstructor()->getMock();
+
         $this->response = '[{"place_id":124047700,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":146744176,"boundingbox":["46.040309","46.0413942","6.584711","6.5864561"],"lat":"46.0405718","lon":"6.5857964","display_name":"Chemin des Rirets, La Frasse, Romme, Nancy-sur-Cluses, Bonneville, Haute-Savoie, Auvergne-Rhône-Alpes, France métropolitaine, 74300, France","place_rank":26,"category":"highway","type":"residential","importance":0.8099999999999999}]';
         $this->responseReverse = '{"place_id":124302276,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":146744171,"lat":"46.04082792421903","lon":"6.585562827387761","place_rank":26,"category":"highway","type":"unclassified","importance":0.09999999999999998,"addresstype":"road","name":"Chemin des Larrets","display_name":"Chemin des Larrets, La Frasse, Romme, Nancy-sur-Cluses, Bonneville, Haute-Savoie, Auvergne-Rhône-Alpes, France métropolitaine, 74300, France","address":{"road":"Chemin des Larrets","hamlet":"La Frasse","village":"Romme","municipality":"Bonneville","county":"Haute-Savoie","state":"Auvergne-Rhône-Alpes","country":"France","postcode":"74300","country_code":"fr"},"boundingbox":["46.0404896","46.040881","6.585013","6.5874704"]}';
     }
@@ -24,15 +29,26 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testSearchGpsCoordinates():void
     {
-        $responses = [new MockResponse($this->response, ['http_code' => 200])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['searchGpsCoordinates'])
+            ->getMock();
+
+        $response = $this->getMockBuilder(ResponseInterface::class)->getMock();
+        $response->method('getContent')->willReturn('{"data":1}');  // dummy response data
+
+        $this->client
+            ->expects(self::once())
+            ->method('request')
+            ->with(
+                'GET',
+                'search?addressdetails=1&format=json&limit=10&street=11 chemin des rirtes&postalcode=74300&city=nancy-sur-cluses'
+            )
+            ->willReturn($response);
 
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
         $content = $gpsCoordinateUtils->searchGpsCoordinates('11 chemin des rirtes', '74300', 'nancy-sur-cluses');
 
-        $this->assertIsArray($content);
-        $this->assertCount(1, $content);
-        $this->assertEquals("Chemin des Rirets, La Frasse, Romme, Nancy-sur-Cluses, Bonneville, Haute-Savoie, Auvergne-Rhône-Alpes, France métropolitaine, 74300, France", $content[0]['display_name']);
+        $this->assertEquals(['data' => 1], $content);
     }
 
     /**
@@ -40,10 +56,16 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testSearchGpsCoordinatesFailed():void
     {
-        $responses = [new MockResponse('...', ['http_code' => 404])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['searchGpsCoordinates'])
+            ->getMock();
+
+        $this->client
+            ->expects(self::once())
+            ->method('request')
+            ->willThrowException(new \Exception());
 
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
         $this->expectException(NotFoundHttpException::class);
         $gpsCoordinateUtils->searchGpsCoordinates('...', '74300', '...');
     }
@@ -53,15 +75,25 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testReverseGpsCoordinates():void
     {
-        $responses = [new MockResponse($this->responseReverse, ['http_code' => 200])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['reverseGpsCoordinates'])
+            ->getMock();
+
+        $response = $this->getMockBuilder(ResponseInterface::class)->getMock();
+        $response->method('getContent')->willReturn('{"data":1}');  // dummy response data
+
+        $this->client
+            ->expects(self::once())
+            ->method('request')
+            ->with(
+                'GET',
+                'reverse?addressdetails=1&format=json&lat=46.040851602664&lon=6.58558355'
+            )
+            ->willReturn($response);
 
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
         $content = $gpsCoordinateUtils->reverseGpsCoordinates(46.04085160266434, 6.585583549999978);
-
-        $this->assertIsArray($content);
-        $this->assertArrayHasKey('place_id', $content);
-        $this->assertEquals("Chemin des Larrets, La Frasse, Romme, Nancy-sur-Cluses, Bonneville, Haute-Savoie, Auvergne-Rhône-Alpes, France métropolitaine, 74300, France", $content['display_name']);
+        $this->assertEquals(['data' => 1], $content);
     }
 
     /**
@@ -69,10 +101,16 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testReverseGpsCoordinatesFailed():void
     {
-        $responses = [new MockResponse('...', ['http_code' => 404])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['reverseGpsCoordinates'])
+            ->getMock();
+
+        $this->client
+            ->expects(self::once())
+            ->method('request')
+            ->willThrowException(new \Exception());
 
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
         $this->expectException(NotFoundHttpException::class);
         $gpsCoordinateUtils->reverseGpsCoordinates(0000, 0000);
     }
@@ -82,11 +120,37 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testCreateGpsCoordinate():void
     {
-        $responses = [new MockResponse('...', ['http_code' => 200])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
-
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
-        $this->assertInstanceOf(GpsCoordinate::class, $gpsCoordinateUtils->createGpsCoordinate(json_decode($this->responseReverse, true)));
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['createGpsCoordinate'])
+            ->getMock();
+
+        $gpsApiResponse = [
+            'address' => ['foo'],
+            'lat' => 123.4,
+            'lon' => 456.7,
+        ];
+
+        $gpsCoordinateUtils
+            ->expects(self::once())
+            ->method('transformAddress')
+            ->with(['foo'])
+            ->willReturn(
+                [
+                    'city' => 'bar',
+                    'cp' => '12345',
+                    'streetAddress' => '1 rue lambda',
+                    'streetAddressSecond' => 'cedex 1'
+                ]
+            );
+
+        $gpsCoordinate = $gpsCoordinateUtils->createGpsCoordinate($gpsApiResponse);
+
+        $this->assertEquals(123.4, $gpsCoordinate->getLatitude());
+        $this->assertEquals(456.7, $gpsCoordinate->getLongitude());
+        $this->assertEquals('bar', $gpsCoordinate->getCity());
+        $this->assertEquals('1 rue lambda', $gpsCoordinate->getStreetAddress());
+        $this->assertEquals('cedex 1', $gpsCoordinate->getStreetAddressSecond());
     }
 
     /**
@@ -94,17 +158,25 @@ class GpsCoordinateUtilsTest extends TestCase
      */
     public function testTransformAddress():void
     {
-        $responses = [new MockResponse('...', ['http_code' => 200])];
-        $client = new MockHttpClient($responses, 'https://nominatim.openstreetmap.org/');
+        $gpsCoordinateUtils = $this->getMockBuilder(GpsCoordinateUtils::class)
+            ->setConstructorArgs([$this->client])
+            ->setMethodsExcept(['transformAddress'])
+            ->getMock();
+
+        $arrayAddress = [
+            'road' => 'foo',
+            'hamlet' => 'bar',
+            'town' => 'alpha',
+            'postcode' => '12345'
+        ];
+
+        $addressTransformed = $gpsCoordinateUtils->transformAddress($arrayAddress);
 
-        $gpsCoordinateUtils = new GpsCoordinateUtils($client);
-        $arrayAddress = json_decode($this->responseReverse, true);
-        $addressTransformed = $gpsCoordinateUtils->transformAddress($arrayAddress['address']);
         $this->assertEquals([
-              "streetAddress" => "Chemin des Larrets",
-              "streetAddressSecond" => "La Frasse",
-              "city" => "Romme",
-              "cp" => "74300"
+              "streetAddress" => "foo",
+              "streetAddressSecond" => "bar",
+              "city" => "alpha",
+              "cp" => "12345"
             ], $addressTransformed);
     }
-}
+}