phoneNumberUtil = $phoneNumberUtil; } public function interruptIfOrganizationExists(OrganizationCreationRequest $organizationCreationRequest): void { parent::interruptIfOrganizationExists($organizationCreationRequest); } public function validateSubdomain(string $subdomainValue): void { parent::validateSubdomain($subdomainValue); } public function makeOrganizationWithRelations( OrganizationCreationRequest $organizationCreationRequest, ): Organization { return parent::makeOrganizationWithRelations($organizationCreationRequest); } public function makeOrganization(OrganizationCreationRequest $organizationCreationRequest): Organization { return parent::makeOrganization($organizationCreationRequest); } public function makeParameters(OrganizationCreationRequest $organizationCreationRequest): Parameters { return parent::makeParameters($organizationCreationRequest); } public function makeSettings(OrganizationCreationRequest $organizationCreationRequest): Settings { return parent::makeSettings($organizationCreationRequest); } public function makePostalAddress(OrganizationCreationRequest $organizationCreationRequest): OrganizationAddressPostal { return parent::makePostalAddress($organizationCreationRequest); } public function makeContactPoint(OrganizationCreationRequest $organizationCreationRequest): ContactPoint { return parent::makeContactPoint($organizationCreationRequest); } public function makeNetworkOrganization(OrganizationCreationRequest $organizationCreationRequest): NetworkOrganization { return parent::makeNetworkOrganization($organizationCreationRequest); } public function makeAdminAccess(OrganizationCreationRequest $organizationCreationRequest): Access { return parent::makeAdminAccess($organizationCreationRequest); } public function makeCycles(): array { return parent::makeCycles(); } public function makeAccess(int|OrganizationMemberCreationRequest $creationRequestData, FunctionEnum $function, \DateTime $creationDate, ?int $authorId): Access { return parent::makeAccess($creationRequestData, $function, $creationDate, $authorId); } public function makePersonPostalAddress(OrganizationMemberCreationRequest $organizationMemberCreationRequest, \DateTime $creationDate, ?int $authorId): PersonAddressPostal { return parent::makePersonPostalAddress($organizationMemberCreationRequest, $creationDate, $authorId); } public function makePersonContactPoint(OrganizationMemberCreationRequest $organizationMemberCreationRequest, \DateTime $creationDate, ?int $authorId): ContactPoint { return parent::makePersonContactPoint($organizationMemberCreationRequest, $creationDate, $authorId); } public function makeSubdomain(OrganizationCreationRequest $organizationCreationRequest): Subdomain { return parent::makeSubdomain($organizationCreationRequest); } public function createTypo3Website(Organization $organization): ?int { return parent::createTypo3Website($organization); } public function updateAdminassosDb(Organization $organization): void { parent::updateAdminassosDb($organization); } public function normalizeIdentificationField(string $value): string { return parent::normalizeIdentificationField($value); } public function deleteOrganizationAccesses(Organization $organization): void { parent::deleteOrganizationAccesses($organization); } public function deleteTypo3Website(Organization $organization): void { parent::deleteTypo3Website($organization); } public function switchDolibarrSocietyToProspect(Organization $organization): void { parent::switchDolibarrSocietyToProspect($organization); } public function deleteOrganizationFiles(Organization $organization): void { parent::deleteOrganizationFiles($organization); } public function deleteDirectoriesV1(Organization $organization): void { parent::deleteDirectoriesV1($organization); } public function deleteDirectories59(Organization $organization): void { parent::deleteDirectories59($organization); } } class OrganizationFactoryTest extends TestCase { private readonly MockObject|SubdomainService $subdomainService; private readonly MockObject|OrganizationRepository $organizationRepository; private readonly MockObject|CountryRepository $countryRepository; private readonly MockObject|OrganizationUtils $organizationUtils; private readonly MockObject|Typo3Service $typo3Service; private readonly MockObject|DolibarrApiService $dolibarrApiService; private readonly MockObject|EntityManagerInterface $entityManager; private readonly MockObject|PersonRepository $personRepository; private readonly MockObject|BindFileService $bindFileService; private readonly MockObject|LoggerInterface $logger; private readonly MockObject|OrganizationIdentificationRepository $organizationIdentificationRepository; private readonly MockObject|ApiLegacyRequestService $apiLegacyRequestService; private readonly MockObject|PhoneNumberUtil $phoneNumberUtil; private readonly MockObject|FunctionTypeRepository $functionTypeRepository; public function setUp(): void { $this->subdomainService = $this->getMockBuilder(SubdomainService::class)->disableOriginalConstructor()->getMock(); $this->organizationRepository = $this->getMockBuilder(OrganizationRepository::class)->disableOriginalConstructor()->getMock(); $this->countryRepository = $this->getMockBuilder(CountryRepository::class)->disableOriginalConstructor()->getMock(); $this->organizationUtils = $this->getMockBuilder(OrganizationUtils::class)->disableOriginalConstructor()->getMock(); $this->typo3Service = $this->getMockBuilder(Typo3Service::class)->disableOriginalConstructor()->getMock(); $this->dolibarrApiService = $this->getMockBuilder(DolibarrApiService::class)->disableOriginalConstructor()->getMock(); $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock(); $this->personRepository = $this->getMockBuilder(PersonRepository::class)->disableOriginalConstructor()->getMock(); $this->bindFileService = $this->getMockBuilder(BindFileService::class)->disableOriginalConstructor()->getMock(); $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock(); $this->organizationIdentificationRepository = $this->getMockBuilder(OrganizationIdentificationRepository::class)->disableOriginalConstructor()->getMock(); $this->apiLegacyRequestService = $this->getMockBuilder(ApiLegacyRequestService::class)->disableOriginalConstructor()->getMock(); $this->phoneNumberUtil = $this->getMockBuilder(PhoneNumberUtil::class)->disableOriginalConstructor()->getMock(); $this->functionTypeRepository = $this->getMockBuilder(FunctionTypeRepository::class)->disableOriginalConstructor()->getMock(); } public function tearDown(): void { DatesUtils::clearFakeDatetime(); } private function getOrganizationFactoryMockFor(string $methodName): TestableOrganizationFactory|MockObject { $organizationFactory = $this ->getMockBuilder(TestableOrganizationFactory::class) ->setConstructorArgs( [ $this->subdomainService, $this->organizationRepository, $this->countryRepository, $this->organizationUtils, $this->typo3Service, $this->dolibarrApiService, $this->entityManager, $this->personRepository, $this->bindFileService, $this->organizationIdentificationRepository, $this->apiLegacyRequestService, $this->functionTypeRepository, ]) ->setMethodsExcept(['setLoggerInterface', 'setPhoneNumberUtil', $methodName]) ->getMock(); $organizationFactory->setLoggerInterface($this->logger); $organizationFactory->setPhoneNumberUtil($this->phoneNumberUtil); return $organizationFactory; } public function testCreate(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('create'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain'); $organizationCreationRequest->method('isClient')->willReturn(false); $organizationCreationRequest->method('getCreateWebsite')->willReturn(true); $this->entityManager->expects(self::once())->method('beginTransaction'); $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists'); $organizationFactory->expects(self::once())->method('validateSubdomain')->with('subdomain'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeOrganizationWithRelations') ->with($organizationCreationRequest) ->willReturn($organization); $this->entityManager->expects(self::once())->method('persist')->with($organization); $this->entityManager->expects(self::once())->method('flush'); $this->entityManager->expects(self::once())->method('commit'); $this->dolibarrApiService ->expects(self::once()) ->method('createSociety') ->with($organization, false) ->willReturn(456); $this->bindFileService ->expects(self::once()) ->method('registerSubdomain') ->with('subdomain'); $organizationFactory ->expects(self::once()) ->method('createTypo3Website') ->with($organization) ->willReturn(789); $this->logger ->method('info') ->withConsecutive( ["Start the creation of a new organization named 'foo'"], ["Subdomain is valid and available : 'subdomain'"], ['Organization created with all its relations'], ['Organization persisted in the DB'], ['New dolibarr structure created (uid : 456)'], ['Subdomain registered'], ['Typo3 website created (root uid: 789)'], ['Adminassos db updated'] ); $organizationCreationRequest ->expects(self::once()) ->method('setStatus') ->with(OrganizationCreationRequest::STATUS_OK); $result = $organizationFactory->create($organizationCreationRequest); $this->assertEquals( $organization, $result ); } public function testCreateWithRollback(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('create'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain'); $organizationCreationRequest->method('isClient')->willReturn(false); $organizationCreationRequest->method('getCreateWebsite')->willReturn(true); $this->entityManager->expects(self::once())->method('beginTransaction'); $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists'); $organizationFactory->expects(self::once())->method('validateSubdomain')->with('subdomain'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeOrganizationWithRelations') ->with($organizationCreationRequest) ->willReturn($organization); $this->entityManager->expects(self::once())->method('persist')->with($organization); $this->entityManager->expects(self::once())->method('flush')->willThrowException(new \RuntimeException('some error')); $this->entityManager->expects(self::once())->method('rollback'); $this->dolibarrApiService ->expects(self::never()) ->method('createSociety'); $this->bindFileService ->expects(self::never()) ->method('registerSubdomain'); $organizationFactory ->expects(self::never()) ->method('createTypo3Website'); $this->logger ->method('info') ->withConsecutive( ["Start the creation of a new organization named 'foo'"], ["Subdomain is valid and available : 'subdomain'"], ['Organization created with all its relations'] ); $this->logger ->method('critical') ->with( $this->matchesRegularExpression('/^An error happened, operation cancelled\nRuntimeException: some error.*/') ); $this->expectException(\RuntimeException::class); $result = $organizationFactory->create($organizationCreationRequest); } public function testCreateWithExistingOrganization(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('create'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $this->entityManager->expects(self::once())->method('beginTransaction'); $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists')->willThrowException(new \RuntimeException('An organization named foo already exists')); $organizationFactory->expects(self::never())->method('validateSubdomain'); $organizationFactory ->expects(self::never()) ->method('makeOrganizationWithRelations'); $this->entityManager->expects(self::never())->method('persist'); $this->entityManager->expects(self::never())->method('flush'); $this->entityManager->expects(self::once())->method('rollback'); $this->dolibarrApiService ->expects(self::never()) ->method('createSociety'); $this->bindFileService ->expects(self::never()) ->method('registerSubdomain'); $organizationFactory ->expects(self::never()) ->method('createTypo3Website'); $this->logger ->method('info') ->withConsecutive( ["Start the creation of a new organization named 'foo'"], ); $this->logger ->method('critical') ->with( $this->matchesRegularExpression("/^An error happened, operation cancelled\nRuntimeException: An organization named foo already exists.*/") ); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('An organization named foo already exists'); $result = $organizationFactory->create($organizationCreationRequest); } public function testCreateNoWebsiteAndIsClient(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('create'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain'); $organizationCreationRequest->method('isClient')->willReturn(true); $organizationCreationRequest->method('getCreateWebsite')->willReturn(false); $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeOrganizationWithRelations') ->with($organizationCreationRequest) ->willReturn($organization); $this->dolibarrApiService ->method('createSociety') ->with($organization, true) ->willReturn(456); $organizationFactory ->expects(self::never()) ->method('createTypo3Website'); $this->logger ->expects(self::once()) ->method('warning') ->with('Typo3 website creation was not required'); $result = $organizationFactory->create($organizationCreationRequest); $this->assertEquals( $organization, $result ); } public function testCreateWithErrors(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('create'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain'); $organizationCreationRequest->method('isClient')->willReturn(true); $organizationCreationRequest->method('getCreateWebsite')->willReturn(true); $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeOrganizationWithRelations') ->with($organizationCreationRequest) ->willReturn($organization); $this->dolibarrApiService ->method('createSociety') ->with($organization, true) ->willThrowException(new \RuntimeException('An error happened')); $this->bindFileService ->method('registerSubdomain') ->with('subdomain') ->willThrowException(new \RuntimeException('An error happened')); $organizationFactory ->method('createTypo3Website') ->with($organization) ->willThrowException(new \RuntimeException('An error happened')); $organizationFactory ->method('updateAdminassosDb') ->with($organization) ->willThrowException(new \RuntimeException('An error happened')); $this->logger ->expects(self::exactly(4)) ->method('critical') ->willReturnOnConsecutiveCalls([ 'An error happened while creating the dolibarr society, please proceed manually.', 'An error happened while updating the bind file, please proceed manually.', 'An error happened while creating the typo3 website, please proceed manually.', 'An error happened while updating the adminassos db, please proceed manually.', ]); $this->logger ->expects(self::once()) ->method('warning') ->with('-- Operation ended with errors, check the logs for more information --'); $organizationCreationRequest ->expects(self::once()) ->method('setStatus') ->with(OrganizationCreationRequest::STATUS_OK_WITH_ERRORS); $result = $organizationFactory->create($organizationCreationRequest); $this->assertEquals( $organization, $result ); } public function testInterruptIfOrganizationExistsNotExisting(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn(''); $organizationCreationRequest->method('getWaldecNumber')->willReturn(''); $organizationCreationRequest->method('getIdentifier')->willReturn(''); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $this->organizationIdentificationRepository ->expects(self::exactly(2)) ->method('findOneBy') ->willReturn(null); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsNotExistingNonExistingWithIdentifiers(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $this->organizationIdentificationRepository ->expects(self::exactly(5)) ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, null], [['waldecNumber' => 'W123456'], null, null], [['identifier' => 'FR000000000000'], null, null], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null], ]); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsExistingWithSiret(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organization = $this->getMockBuilder(Organization::class)->getMock(); $this->organizationIdentificationRepository ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, $organization], [['waldecNumber' => 'W123456'], null, null], [['identifier' => 'FR000000000000'], null, null], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null], ]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage("This siret number is already registered : '123456'"); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsExistingWithWaldec(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organization = $this->getMockBuilder(Organization::class)->getMock(); $this->organizationIdentificationRepository ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, null], [['waldecNumber' => 'W123456'], null, $organization], [['identifier' => 'FR000000000000'], null, null], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null], ]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage("This RNA identifier (waldec number) is already registered : 'W123456'"); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsExistingWithCMFIdentifier(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organization = $this->getMockBuilder(Organization::class)->getMock(); $this->organizationIdentificationRepository ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, null], [['waldecNumber' => 'W123456'], null, null], [['identifier' => 'FR000000000000'], null, $organization], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null], ]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage("This CMF identifier is already registered : 'FR000000000000'"); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsExistingWithSameNameAndCity(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organization = $this->getMockBuilder(Organization::class)->getMock(); $this->organizationIdentificationRepository ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, null], [['waldecNumber' => 'W123456'], null, null], [['identifier' => 'FR000000000000'], null, null], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, $organization], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null], ]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage("An organization named 'foo' already exists in Paris"); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testInterruptIfOrganizationExistsExistingWithSameAddress(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('foo'); $organizationCreationRequest->method('getSiretNumber')->willReturn('123456'); $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456'); $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000'); $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3'); $organizationCreationRequest->method('getCity')->willReturn('Paris'); $organizationCreationRequest->method('getPostalCode')->willReturn('75000'); $organizationFactory ->method('normalizeIdentificationField') ->willReturnMap([ ['foo', 'foo'], ['part1 part2 part3', 'part1 part2 part3'], ]); $organization = $this->getMockBuilder(Organization::class)->getMock(); $this->organizationIdentificationRepository ->method('findOneBy') ->willReturnMap([ [['siretNumber' => '123456'], null, null], [['waldecNumber' => 'W123456'], null, null], [['identifier' => 'FR000000000000'], null, null], [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null], [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, $organization], ]); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('An organization already exists at this address.'); $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest); } public function testValidateSubdomain(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain'); $this->subdomainService->expects(self::once())->method('isValidSubdomain')->willReturn(true); $this->subdomainService->expects(self::once())->method('isReservedSubdomain')->willReturn(false); $this->subdomainService->expects(self::once())->method('isRegistered')->willReturn(false); $organizationFactory->validateSubdomain('foo'); } public function testValidateSubdomainIsNotValid(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain'); $this->subdomainService->method('isValidSubdomain')->willReturn(false); $this->subdomainService->method('isReservedSubdomain')->willReturn(false); $this->subdomainService->method('isRegistered')->willReturn(false); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Not a valid subdomain : foo'); $organizationFactory->validateSubdomain('foo'); } public function testValidateSubdomainIsReserved(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain'); $this->subdomainService->method('isValidSubdomain')->willReturn(true); $this->subdomainService->method('isReservedSubdomain')->willReturn(true); $this->subdomainService->method('isRegistered')->willReturn(false); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('This subdomain is not available : foo'); $organizationFactory->validateSubdomain('foo'); } public function testValidateSubdomainIsRegistered(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain'); $this->subdomainService->method('isValidSubdomain')->willReturn(true); $this->subdomainService->method('isReservedSubdomain')->willReturn(false); $this->subdomainService->method('isRegistered')->willReturn(true); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('This subdomain is already registered : foo'); $organizationFactory->validateSubdomain('foo'); } public function testMakeOrganizationWithRelations(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganizationWithRelations'); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getCreationDate')->willReturn($creationDate); $organizationCreationRequest->method('getAuthorId')->willReturn(1); $organization = $this->getMockBuilder(Organization::class)->getMock(); // Création de l'organisation $organizationFactory ->expects(self::once()) ->method('makeOrganization') ->with($organizationCreationRequest) ->willReturn($organization); // Création des Parameters $parameters = $this->getMockBuilder(Parameters::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeParameters') ->with($organizationCreationRequest) ->willReturn($parameters); $organization->expects(self::once())->method('setParameters')->with($parameters); // Création des Settings $settings = $this->getMockBuilder(Settings::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeSettings') ->with($organizationCreationRequest) ->willReturn($settings); $organization->expects(self::once())->method('setSettings')->with($settings); // Création de l'adresse postale $organizationAddressPostal = $this->getMockBuilder(OrganizationAddressPostal::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makePostalAddress') ->with($organizationCreationRequest) ->willReturn($organizationAddressPostal); $organization->expects(self::once())->method('addOrganizationAddressPostal')->with($organizationAddressPostal); // Création du point de contact $contactPoint = $this->getMockBuilder(ContactPoint::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeContactPoint') ->with($organizationCreationRequest) ->willReturn($contactPoint); $organization->expects(self::once())->method('addContactPoint')->with($contactPoint); // Rattachement au réseau $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeNetworkOrganization') ->with($organizationCreationRequest) ->willReturn($networkOrganization); $organization->expects(self::once())->method('addNetworkOrganization')->with($networkOrganization); // Créé l'admin $adminAccess = $this->getMockBuilder(Access::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeAdminAccess') ->with($organizationCreationRequest) ->willReturn($adminAccess); // Le `$organization->expects(...)->method('addAccess')` est implémenté plus loin, // après la création du président et du directeur. // Création des cycles $cycle1 = $this->getMockBuilder(Cycle::class)->getMock(); $cycle2 = $this->getMockBuilder(Cycle::class)->getMock(); $cycle3 = $this->getMockBuilder(Cycle::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeCycles') ->willReturn([$cycle1, $cycle2, $cycle3]); $organization->expects(self::exactly(3))->method('addCycle')->withConsecutive([$cycle1], [$cycle2], [$cycle3]); // Création du président et du directeur $organizationMemberCreationRequest1 = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationCreationRequest->method('getPresident')->willReturn($organizationMemberCreationRequest1); $organizationMemberCreationRequest2 = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationCreationRequest->method('getDirector')->willReturn($organizationMemberCreationRequest2); $access1 = $this->getMockBuilder(Access::class)->getMock(); $access2 = $this->getMockBuilder(Access::class)->getMock(); $organizationFactory ->expects(self::exactly(2)) ->method('makeAccess') ->willReturnMap([ [$organizationMemberCreationRequest1, FunctionEnum::PRESIDENT, $creationDate, 1, $access1], [$organizationMemberCreationRequest2, FunctionEnum::DIRECTOR, $creationDate, 1, $access2], ]); $organization ->expects(self::exactly(3)) ->method('addAccess') ->withConsecutive([$adminAccess], [$access1], [$access2]); // Création du sous-domaine $subdomain = $this->getMockBuilder(Subdomain::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makeSubdomain') ->with($organizationCreationRequest) ->willReturn($subdomain); $organization->expects(self::once())->method('addSubdomain')->with($subdomain); // Enregistrement du sous domaine dans Parameters (retrocompatibilité v1) $organization->method('getParameters')->willReturn($parameters); $organizationCreationRequest->method('getSubdomain')->willReturn('foo'); $parameters->expects(self::once())->method('setSubDomain')->with('foo'); $parameters->expects(self::once())->method('setOtherWebsite')->with('https://foo.opentalent.fr'); $result = $organizationFactory->makeOrganizationWithRelations($organizationCreationRequest); $this->assertEquals( $result, $organization ); } public function testMakeOrganizationWithRelationsNoPresidentNoDirector(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganizationWithRelations'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organization = $this->getMockBuilder(Organization::class)->getMock(); // Création de l'organisation $organizationFactory ->expects(self::once()) ->method('makeOrganization') ->with($organizationCreationRequest) ->willReturn($organization); $organizationCreationRequest->method('getPresident')->willReturn(null); $organizationCreationRequest->method('getDirector')->willReturn(null); // Un seul appel, pour l'adminAccess $organization ->expects(self::once()) ->method('addAccess'); $organizationFactory->makeOrganizationWithRelations($organizationCreationRequest); } public function testMakeOrganization() { $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganization'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getName')->willReturn('My Organization'); $organizationCreationRequest->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901); $organizationCreationRequest->method('getPrincipalType')->willReturn(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY); $organization = $organizationFactory->makeOrganization($organizationCreationRequest); $this->assertEquals( 'My Organization', $organization->getName() ); $this->assertEquals( LegalEnum::ASSOCIATION_LAW_1901, $organization->getLegalStatus() ); $this->assertEquals( PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY, $organization->getPrincipalType() ); } public function testMakeParameters(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeParameters'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $parameters = $organizationFactory->makeParameters($organizationCreationRequest); $this->assertInstanceOf(Parameters::class, $parameters); } public function testMakeSettings(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeSettings'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getProduct')->willReturn(SettingsProductEnum::ARTIST_PREMIUM); $settings = $organizationFactory->makeSettings($organizationCreationRequest); $this->assertEquals( SettingsProductEnum::ARTIST_PREMIUM, $settings->getProduct() ); } public function testMakePostalAddress(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePostalAddress'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getStreetAddress1')->willReturn('address1'); $organizationCreationRequest->method('getStreetAddress2')->willReturn('address2'); $organizationCreationRequest->method('getStreetAddress3')->willReturn('address3'); $organizationCreationRequest->method('getPostalCode')->willReturn('00000'); $organizationCreationRequest->method('getCity')->willReturn('city'); $organizationCreationRequest->method('getCountryId')->willReturn(1); $country = $this->getMockBuilder(Country::class)->getMock(); $this->countryRepository->expects(self::once())->method('find')->with(1)->willReturn($country); $organizationAddressPostal = $organizationFactory->makePostalAddress($organizationCreationRequest); $this->assertEquals( AddressPostalOrganizationTypeEnum::ADDRESS_HEAD_OFFICE, $organizationAddressPostal->getType() ); $addressPostal = $organizationAddressPostal->getAddressPostal(); $this->assertEquals( 'address1', $addressPostal->getStreetAddress() ); $this->assertEquals( 'address2', $addressPostal->getStreetAddressSecond() ); $this->assertEquals( 'address3', $addressPostal->getStreetAddressThird() ); $this->assertEquals( '00000', $addressPostal->getPostalCode() ); $this->assertEquals( 'city', $addressPostal->getAddressCity() ); $this->assertEquals( $country, $addressPostal->getAddressCountry() ); } public function testMakePostalAddressUnexistingCountry(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePostalAddress'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getCountryId')->willReturn(1); $this->countryRepository->expects(self::once())->method('find')->with(1)->willReturn(null); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('No country found for id 1'); $organizationFactory->makePostalAddress($organizationCreationRequest); } public function testMakeContactPoint(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeContactPoint'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getPhoneNumber')->willReturn('+33102030405'); $organizationCreationRequest->method('getEmail')->willReturn('contact@domain.net'); $this->phoneNumberUtil ->method('isPossibleNumber') ->with('+33102030405') ->willReturn(true); $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock(); $this->phoneNumberUtil ->expects(self::once()) ->method('parse') ->with('+33102030405') ->willReturn($phoneNumber); $contactPoint = $organizationFactory->makeContactPoint($organizationCreationRequest); $this->assertEquals( 'contact@domain.net', $contactPoint->getEmail() ); $this->assertEquals( $phoneNumber, $contactPoint->getTelphone() ); } public function testMakeContactPointInvalidPhoneNumber(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeContactPoint'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getPhoneNumber')->willReturn('invalid'); $organizationCreationRequest->method('getEmail')->willReturn('contact@domain.net'); $this->phoneNumberUtil ->method('isPossibleNumber') ->with('invalid') ->willReturn(false); $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock(); $this->phoneNumberUtil ->expects(self::never()) ->method('parse'); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Phone number is invalid or missing'); $organizationFactory->makeContactPoint($organizationCreationRequest); } public function testMakeNetworkOrganization(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); DatesUtils::setFakeDatetime('2024-01-01'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $parent = $this->getMockBuilder(Organization::class)->getMock(); $settings = $this->getMockBuilder(Settings::class)->getMock(); $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER); $parent->method('getSettings')->willReturn($settings); $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent); $network = $this->getMockBuilder(Network::class)->getMock(); $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock(); $networkOrganization->method('getNetwork')->willReturn($network); $this->organizationUtils ->expects(self::once()) ->method('getActiveNetworkOrganization') ->with($parent) ->willReturn($networkOrganization); $networkOrganization = $organizationFactory->makeNetworkOrganization($organizationCreationRequest); $this->assertEquals( $parent, $networkOrganization->getParent() ); $this->assertEquals( $network, $networkOrganization->getNetwork() ); $this->assertEquals( '2024-01-01', $networkOrganization->getStartDate()->format('Y-m-d') ); } public function testMakeNetworkOrganizationMissingParent(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('No parent organization found for id 123'); $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn(null); $organizationFactory->makeNetworkOrganization($organizationCreationRequest); } public function testMakeNetworkOrganizationParentIsNotManager(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); DatesUtils::setFakeDatetime('2024-01-01'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $parent = $this->getMockBuilder(Organization::class)->getMock(); $settings = $this->getMockBuilder(Settings::class)->getMock(); $settings->method('getProduct')->willReturn(SettingsProductEnum::SCHOOL); $parent->method('getSettings')->willReturn($settings); $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage("Parent organization must have the product 'manager' (actual product: 'school')"); $organizationFactory->makeNetworkOrganization($organizationCreationRequest); } public function testMakeNetworkOrganizationMissingNetwork(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $parent = $this->getMockBuilder(Organization::class)->getMock(); $settings = $this->getMockBuilder(Settings::class)->getMock(); $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER); $parent->method('getSettings')->willReturn($settings); $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('No network found for parent 123'); $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent); $organizationFactory->makeNetworkOrganization($organizationCreationRequest); } public function testMakeNetworkOrganizationIsCMFInvalidIdentifier(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $organizationCreationRequest->method('getIdentifier')->willReturn('invalid'); $parent = $this->getMockBuilder(Organization::class)->getMock(); $settings = $this->getMockBuilder(Settings::class)->getMock(); $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER); $parent->method('getSettings')->willReturn($settings); $this->organizationRepository->method('find')->with(123)->willReturn($parent); $network = $this->getMockBuilder(Network::class)->getMock(); $network->method('getId')->willReturn(NetworkEnum::CMF->value); $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock(); $networkOrganization->method('getNetwork')->willReturn($network); $this->organizationUtils ->method('getActiveNetworkOrganization') ->with($parent) ->willReturn($networkOrganization); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('CMF identifier is missing or invalid.'); $organizationFactory->makeNetworkOrganization($organizationCreationRequest); } public function testMakeNetworkOrganizationIsNotCMFInvalidIdentifier(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getParentId')->willReturn(123); $organizationCreationRequest->method('getIdentifier')->willReturn('invalid'); $parent = $this->getMockBuilder(Organization::class)->getMock(); $settings = $this->getMockBuilder(Settings::class)->getMock(); $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER); $parent->method('getSettings')->willReturn($settings); $this->organizationRepository->method('find')->with(123)->willReturn($parent); $network = $this->getMockBuilder(Network::class)->getMock(); $network->method('getId')->willReturn(NetworkEnum::OUTOFNET->value); $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock(); $networkOrganization->method('getNetwork')->willReturn($network); $this->organizationUtils ->method('getActiveNetworkOrganization') ->with($parent) ->willReturn($networkOrganization); $result = $organizationFactory->makeNetworkOrganization($organizationCreationRequest); $this->assertEquals( $network, $result->getNetwork() ); } public function testMakeAdminAccess(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeAdminAccess'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getSubdomain')->willReturn('foo'); $adminAccess = $organizationFactory->makeAdminAccess($organizationCreationRequest); $this->assertTrue( $adminAccess->getAdminAccess() ); $this->assertEquals( 'adminfoo', $adminAccess->getPerson()->getUsername() ); $this->assertEquals( 32, strlen($adminAccess->getPerson()->getPassword()) ); } public function testMakeCycles(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeCycles'); $cycles = $organizationFactory->makeCycles(); $cyclesExpectedData = [ ['Cycle initiation', 10, CycleEnum::INITIATION_CYCLE], ['Cycle 1', 20, CycleEnum::CYCLE_1], ['Cycle 2', 30, CycleEnum::CYCLE_2], ['Cycle 3', 40, CycleEnum::CYCLE_3], ['Cycle 4', 50, CycleEnum::CYCLE_4], ['Hors cycle', 60, CycleEnum::OUT_CYCLE], ]; $i = 0; foreach ($cycles as $cycle) { $this->assertEquals( $cyclesExpectedData[$i][0], $cycle->getLabel() ); $this->assertEquals( $cyclesExpectedData[$i][1], $cycle->getOrder() ); $this->assertEquals( $cyclesExpectedData[$i][2], $cycle->getCycleEnum() ); $this->assertFalse( $cycle->getIsSystem() ); ++$i; } } public function testMakeAccessNewPerson(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getUsername')->willReturn('bob'); $organizationMemberCreationRequest->method('getName')->willReturn('Bob'); $organizationMemberCreationRequest->method('getGivenName')->willReturn('bOBBy'); $organizationMemberCreationRequest->method('getGender')->willReturn(GenderEnum::MISTER); $this->personRepository ->method('findOneBy') ->with(['username' => 'bob'], null) ->willReturn(null); $personAddressPostal = $this->getMockBuilder(PersonAddressPostal::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makePersonPostalAddress') ->with($organizationMemberCreationRequest) ->willReturn($personAddressPostal); $contactPoint = $this->getMockBuilder(ContactPoint::class)->getMock(); $organizationFactory ->expects(self::once()) ->method('makePersonContactPoint') ->with($organizationMemberCreationRequest) ->willReturn($contactPoint); $functionType = $this->getMockBuilder(FunctionType::class)->getMock(); $this->functionTypeRepository ->expects(self::once()) ->method('findOneBy') ->with(['mission' => FunctionEnum::ACCOUNTANT]) ->willReturn($functionType); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $access = $organizationFactory->makeAccess( $organizationMemberCreationRequest, FunctionEnum::ACCOUNTANT, $creationDate, 1 ); $this->assertInstanceOf(Access::class, $access); $this->assertEquals( 'bob', $access->getPerson()->getUsername() ); $this->assertTrue( strlen($access->getPerson()->getPassword()) === 32 ); $this->assertEquals( 'Bob', $access->getPerson()->getName() ); $this->assertEquals( 'Bobby', $access->getPerson()->getGivenName() ); $this->assertEquals( [$personAddressPostal], $access->getPerson()->getPersonAddressPostal()->toArray() ); $this->assertEquals( [$contactPoint], $access->getPerson()->getContactPoints()->toArray() ); $this->assertEquals( $functionType, $access->getOrganizationFunction()->first()->getFunctionType() ); $this->assertEquals( $creationDate, $access->getOrganizationFunction()->first()->getStartDate() ); } public function testMakeAccessNewPersonUsernameAlreadyInUse(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getUsername')->willReturn('bob'); $organizationMemberCreationRequest->method('getName')->willReturn('Bob'); $organizationMemberCreationRequest->method('getGivenName')->willReturn('bOBBy'); $organizationMemberCreationRequest->method('getGender')->willReturn(GenderEnum::MISTER); $person = $this->getMockBuilder(Person::class)->getMock(); $this->personRepository ->method('findOneBy') ->with(['username' => 'bob'], null) ->willReturn($person); $organizationFactory ->expects(self::never()) ->method('makePersonPostalAddress'); $organizationFactory ->expects(self::never()) ->method('makePersonContactPoint'); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Username already in use : bob'); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $organizationFactory->makeAccess( $organizationMemberCreationRequest, FunctionEnum::ADHERENT, $creationDate, 1 ); } public function testMakeAccessExistingPerson(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess'); $person = $this->getMockBuilder(Person::class)->getMock(); $this->personRepository ->expects(self::once()) ->method('find') ->with(123) ->willReturn($person); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $functionType = $this->getMockBuilder(FunctionType::class)->getMock(); $this->functionTypeRepository ->expects(self::once()) ->method('findOneBy') ->with(['mission' => FunctionEnum::ACCOUNTANT]) ->willReturn($functionType); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $access = $organizationFactory->makeAccess( 123, FunctionEnum::ACCOUNTANT, $creationDate, 1 ); $this->assertInstanceOf(Access::class, $access); $this->assertEquals( $person, $access->getPerson() ); $this->assertEquals( $functionType, $access->getOrganizationFunction()->first()->getFunctionType() ); $this->assertEquals( $creationDate, $access->getOrganizationFunction()->first()->getStartDate() ); } public function testMakeAccessPostalAddress() { $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonPostalAddress'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getStreetAddress1')->willReturn('Aaa'); $organizationMemberCreationRequest->method('getStreetAddress2')->willReturn('Bbb'); $organizationMemberCreationRequest->method('getStreetAddress3')->willReturn(null); $organizationMemberCreationRequest->method('getPostalCode')->willReturn('00000'); $organizationMemberCreationRequest->method('getCity')->willReturn('city'); $organizationMemberCreationRequest->method('getCountryId')->willReturn(123); $country = $this->getMockBuilder(Country::class)->getMock(); $this->countryRepository ->expects(self::once()) ->method('find') ->with(123) ->willReturn($country); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $personPostalAddress = $organizationFactory->makePersonPostalAddress( $organizationMemberCreationRequest, $creationDate, 1 ); $this->assertEquals( AddressPostalPersonTypeEnum::ADDRESS_PRINCIPAL, $personPostalAddress->getType() ); $postalAddress = $personPostalAddress->getAddressPostal(); $this->assertEquals('Aaa', $postalAddress->getStreetAddress()); $this->assertEquals('Bbb', $postalAddress->getStreetAddressSecond()); $this->assertEquals(null, $postalAddress->getStreetAddressThird()); $this->assertEquals('00000', $postalAddress->getPostalCode()); $this->assertEquals('city', $postalAddress->getAddressCity()); $this->assertEquals($country, $postalAddress->getAddressCountry()); } public function testMakeAccessContactPoint(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405'); $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com'); $organizationMemberCreationRequest->method('getMobile')->willReturn('+33607080910'); $this->phoneNumberUtil ->expects(self::exactly(2)) ->method('isPossibleNumber') ->willReturnMap([ ['+33102030405', null, true], ['+33607080910', null, true], ]); $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock(); $mobilePhoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock(); $this->phoneNumberUtil ->expects(self::exactly(2)) ->method('parse') ->willReturnMap([ ['+33102030405', null, null, false, $phoneNumber], ['+33607080910', null, null, false, $mobilePhoneNumber], ]); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $contactPoint = $organizationFactory->makePersonContactPoint( $organizationMemberCreationRequest, $creationDate, 1 ); $this->assertEquals( ContactPointTypeEnum::PRINCIPAL, $contactPoint->getContactType() ); $this->assertEquals( 'email@domain.com', $contactPoint->getEmail() ); $this->assertEquals( $phoneNumber, $contactPoint->getTelphone() ); $this->assertEquals( $mobilePhoneNumber, $contactPoint->getMobilPhone() ); } public function testMakeAccessContactPointInvalidPhone(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getUsername')->willReturn('bob'); $organizationMemberCreationRequest->method('getPhone')->willReturn('invalid'); $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com'); $organizationMemberCreationRequest->method('getMobile')->willReturn('+33607080910'); $this->phoneNumberUtil ->expects(self::once()) ->method('isPossibleNumber') ->with('invalid') ->willReturn(false); $this->phoneNumberUtil ->expects(self::never()) ->method('parse'); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Phone number is invalid or missing (person: bob)'); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $organizationFactory->makePersonContactPoint( $organizationMemberCreationRequest, $creationDate, 1 ); } public function testMakeAccessContactPointInvalidMobilePhone(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getUsername')->willReturn('bob'); $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405'); $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com'); $organizationMemberCreationRequest->method('getMobile')->willReturn('invalid'); $this->phoneNumberUtil ->expects(self::exactly(2)) ->method('isPossibleNumber') ->willReturnMap([ ['+33102030405', null, true], ['invalid', null, false], ]); $this->phoneNumberUtil ->expects(self::never()) ->method('parse'); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Mobile phone number is invalid (person: bob)'); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $organizationFactory->makePersonContactPoint( $organizationMemberCreationRequest, $creationDate, 1 ); } public function testMakePersonContactPointNoMobile(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint'); $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock(); $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405'); $organizationMemberCreationRequest->method('getMobile')->willReturn(null); $this->phoneNumberUtil ->expects(self::once()) ->method('isPossibleNumber') ->with('+33102030405') ->willReturn(true); $creationDate = $this->getMockBuilder(\DateTime::class)->getMock(); $contactPoint = $organizationFactory->makePersonContactPoint( $organizationMemberCreationRequest, $creationDate, 1 ); $this->assertEquals( null, $contactPoint->getMobilPhone() ); } public function testMakeSubdomain(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('makeSubdomain'); $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock(); $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain'); $subdomain = $organizationFactory->makeSubdomain($organizationCreationRequest); $this->assertEquals( 'subdomain', $subdomain->getSubdomain() ); $this->assertTrue( $subdomain->isActive() ); } public function testCreateTypo3Website(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock(); $response->method('getStatusCode')->willReturn(Response::HTTP_OK); $response->method('getContent')->willReturn('{"root_uid": 456}'); $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response); $organization->expects(self::once())->method('setCmsId')->with(456); $this->entityManager->expects(self::once())->method('persist')->with($organization); $this->entityManager->expects(self::once())->method('flush'); $result = $organizationFactory->createTypo3Website($organization); $this->assertEquals( 456, $result ); } public function testCreateTypo3WebsiteWithError(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock(); $response->method('getStatusCode')->willReturn(Response::HTTP_FORBIDDEN); $response->method('getContent')->willReturn(''); $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response); $this->logger ->expects(self::once()) ->method('critical') ->with('/!\ A critical error happened while creating the Typo3 website'); $result = $organizationFactory->createTypo3Website($organization); $this->assertNull($result); } public function testCreateTypo3WebsiteWithInvalidResponse(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock(); $response->method('getStatusCode')->willReturn(Response::HTTP_OK); $response->method('getContent')->willReturn('Login page'); $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response); $this->logger ->expects(self::once()) ->method('critical') ->with('/!\ A critical error happened while creating the Typo3 website'); $result = $organizationFactory->createTypo3Website($organization); $this->assertNull($result); } public function testUpdateAdminassosDb(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('updateAdminassosDb'); $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock(); $response->method('getStatusCode')->willReturn(Response::HTTP_OK); $this->apiLegacyRequestService ->expects(self::once()) ->method('post') ->with('/_internal/secure/organization/creation-event', ['organizationId' => 123]) ->willReturn($response); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $organizationFactory->updateAdminassosDb($organization); } public function testUpdateAdminassosDbError(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('updateAdminassosDb'); $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock(); $response->method('getStatusCode')->willReturn(Response::HTTP_BAD_REQUEST); $response->method('getContent')->willReturn('some error'); $this->apiLegacyRequestService ->expects(self::once()) ->method('post') ->with('/_internal/secure/organization/creation-event', ['organizationId' => 123]) ->willReturn($response); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('An error happened while updating the adminassos database: some error'); $organizationFactory->updateAdminassosDb($organization); } public function testNormalizeIdentificationField(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('normalizeIdentificationField'); $this->assertEquals( 'c+est+une+phrase+normalisee+', $organizationFactory->normalizeIdentificationField("C'est une phrase normalisée.") ); } public function testDelete(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('delete'); $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock(); $organizationDeletionRequest->method('getOrganizationId')->willReturn(123); $parameters = $this->getMockBuilder(Parameters::class)->getMock(); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $organization->method('getParameters')->willReturn($parameters); $this->organizationRepository ->expects(self::once()) ->method('find') ->with(123) ->willReturn($organization); $this->entityManager->expects(self::once())->method('beginTransaction'); $this->entityManager->expects(self::once())->method('flush'); $this->entityManager->expects(self::once())->method('commit'); $this->entityManager->expects(self::never())->method('rollback'); $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization); $this->entityManager->expects(self::exactly(2))->method('remove')->withConsecutive( [$parameters], [$organization] ); $organizationFactory->expects(self::once())->method('deleteTypo3Website')->with($organization); $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->with($organization); $organizationFactory->expects(self::once())->method('deleteOrganizationFiles')->with($organization); $organizationFactory->expects(self::once())->method('deleteDirectoriesV1')->with($organization); $organizationFactory->expects(self::once())->method('deleteDirectories59')->with($organization); $organizationDeletionRequest ->expects(self::once()) ->method('setStatus') ->with(OrganizationDeletionRequest::STATUS_OK); $result = $organizationFactory->delete($organizationDeletionRequest); $this->assertEquals( $organizationDeletionRequest, $result ); } public function testDeleteWithRollback(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('delete'); $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock(); $organizationDeletionRequest->method('getOrganizationId')->willReturn(123); $parameters = $this->getMockBuilder(Parameters::class)->getMock(); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getParameters')->willReturn($parameters); $this->organizationRepository ->expects(self::once()) ->method('find') ->with(123) ->willReturn($organization); $this->entityManager->expects(self::once())->method('beginTransaction'); $this->entityManager->expects(self::never())->method('flush'); $this->entityManager->expects(self::never())->method('commit'); $this->entityManager->expects(self::once())->method('rollback'); $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization); $this->entityManager->method('remove')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::never())->method('deleteTypo3Website'); $organizationFactory->expects(self::never())->method('switchDolibarrSocietyToProspect'); $organizationFactory->expects(self::never())->method('deleteOrganizationFiles'); $organizationFactory->expects(self::never())->method('deleteDirectoriesV1'); $organizationFactory->expects(self::never())->method('deleteDirectories59'); $organizationDeletionRequest ->expects(self::never()) ->method('setStatus'); $this->logger ->expects(self::once()) ->method('critical') ->with($this->callback(function ($arg) { return is_string($arg) && str_contains($arg, 'An error happened, operation cancelled') && str_contains($arg, 'some error'); })); $this->expectException(\Exception::class); $organizationFactory->delete($organizationDeletionRequest); } public function testDeleteWithNonBlockingErrors(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('delete'); $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock(); $organizationDeletionRequest->method('getOrganizationId')->willReturn(123); $parameters = $this->getMockBuilder(Parameters::class)->getMock(); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $organization->method('getParameters')->willReturn($parameters); $this->organizationRepository ->expects(self::once()) ->method('find') ->with(123) ->willReturn($organization); $this->entityManager->expects(self::once())->method('beginTransaction'); $this->entityManager->expects(self::once())->method('flush'); $this->entityManager->expects(self::once())->method('commit'); $this->entityManager->expects(self::never())->method('rollback'); $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization); $this->entityManager->expects(self::exactly(2))->method('remove')->withConsecutive( [$parameters], [$organization] ); $organizationFactory->expects(self::once())->method('deleteTypo3Website')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::once())->method('deleteOrganizationFiles')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::once())->method('deleteDirectoriesV1')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::once())->method('deleteDirectories59')->willThrowException(new \Exception('some error')); $organizationDeletionRequest ->expects(self::once()) ->method('setStatus') ->with(OrganizationDeletionRequest::STATUS_OK_WITH_ERRORS); $this->logger ->expects(self::exactly(5)) ->method('critical') ->withConsecutive( ['An error happened while deleting the Typo3 website, please proceed manually.'], ['An error happened while updating the Dolibarr society, please proceed manually.'], ['An error happened while deleting the local directories, please proceed manually.'], ['An error happened while deleting the V1 directories, please proceed manually.'], ['An error happened while deleting the 5.9 directories, please proceed manually.'], ); $result = $organizationFactory->delete($organizationDeletionRequest); $this->assertEquals( $organizationDeletionRequest, $result ); } public function testDeleteOrganizationAccesses(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('deleteOrganizationAccesses'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $access1 = $this->getMockBuilder(Access::class)->getMock(); $access2 = $this->getMockBuilder(Access::class)->getMock(); $access_other = $this->getMockBuilder(Access::class)->getMock(); $person1 = $this->getMockBuilder(Person::class)->getMock(); $person1->method('getAccesses')->willReturn(new ArrayCollection([$access1])); $access1->method('getPerson')->willReturn($person1); $person2 = $this->getMockBuilder(Person::class)->getMock(); $person2->method('getAccesses')->willReturn(new ArrayCollection([$access2, $access_other])); $access2->method('getPerson')->willReturn($person2); $organization->method('getAccesses')->willReturn(new ArrayCollection([$access1, $access2])); $this->entityManager ->expects(self::exactly(3)) ->method('remove') ->withConsecutive( [$person1], [$access1], [$access2], ); $organizationFactory->deleteOrganizationAccesses($organization); } public function testSwitchDolibarrSocietyToProspect(): void { $organizationFactory = $this->getOrganizationFactoryMockFor('switchDolibarrSocietyToProspect'); $organization = $this->getMockBuilder(Organization::class)->getMock(); $organization->method('getId')->willReturn(123); $this->dolibarrApiService ->expects(self::once()) ->method('switchSocietyToProspect') ->with(123); $organizationFactory->switchDolibarrSocietyToProspect($organization); } }