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 deleteTypo3Website(int $organizationId): void { parent::deleteTypo3Website($organizationId); } public function switchDolibarrSocietyToProspect(Organization $organization): void { parent::switchDolibarrSocietyToProspect($organization); } public function getFutureOrphanPersons(Organization $organization): array { return parent::getFutureOrphanPersons($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(); $this->fileManager = $this->getMockBuilder(FileManager::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, $this->fileManager ]) ->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(): void { $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 testMakePostalAddressNonExistingCountry(): 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(): void { $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('get') ->with('/_internal/request/adminassos/create/organization/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('get') ->with('/_internal/request/adminassos/create/organization/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'); $person1 = $this->getMockBuilder(Person::class)->getMock(); $person1->method('getId')->willReturn(1); $person2 = $this->getMockBuilder(Person::class)->getMock(); $person2->method('getId')->willReturn(2); $person3 = $this->getMockBuilder(Person::class)->getMock(); $person3->method('getId')->willReturn(3); $organizationFactory ->method('getFutureOrphanPersons') ->with($organization) ->willReturn([$person1, $person2, $person3]); $this->entityManager->expects(self::exactly(5))->method('remove')->withConsecutive( [$parameters], [$organization], [$person1], [$person2], [$person3], ); $organizationFactory->expects(self::once())->method('deleteTypo3Website')->with(123); $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->with($organization); $this->fileManager->expects(self::once())->method('deleteOrganizationFiles')->with(123); $this->fileManager ->expects(self::exactly(3)) ->method('deletePersonFiles') ->withConsecutive([1], [2], [3]); $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); $person1 = $this->getMockBuilder(Person::class)->getMock(); $person1->method('getId')->willReturn(1); $person2 = $this->getMockBuilder(Person::class)->getMock(); $person2->method('getId')->willReturn(2); $person3 = $this->getMockBuilder(Person::class)->getMock(); $person3->method('getId')->willReturn(3); $organizationFactory ->method('getFutureOrphanPersons') ->with($organization) ->willReturn([$person1, $person2, $person3]); $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'); $this->entityManager->method('remove')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::never())->method('deleteTypo3Website'); $organizationFactory->expects(self::never())->method('switchDolibarrSocietyToProspect'); $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); $person1 = $this->getMockBuilder(Person::class)->getMock(); $person1->method('getId')->willReturn(1); $person2 = $this->getMockBuilder(Person::class)->getMock(); $person2->method('getId')->willReturn(2); $person3 = $this->getMockBuilder(Person::class)->getMock(); $person3->method('getId')->willReturn(3); $organizationFactory ->method('getFutureOrphanPersons') ->with($organization) ->willReturn([$person1, $person2, $person3]); $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'); $this->entityManager->expects(self::exactly(5))->method('remove')->withConsecutive( [$parameters], [$organization], [$person1], [$person2], [$person3], ); $organizationFactory->expects(self::once())->method('deleteTypo3Website')->willThrowException(new \Exception('some error')); $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->willThrowException(new \Exception('some error')); $organizationDeletionRequest ->expects(self::once()) ->method('setStatus') ->with(OrganizationDeletionRequest::STATUS_OK_WITH_ERRORS); $this->fileManager ->expects(self::once()) ->method('deleteOrganizationFiles') ->with(123) ->willThrowException(new \Exception('some error')); ; $this->fileManager ->expects(self::exactly(3)) ->method('deletePersonFiles') ->withConsecutive([1], [2], [3]) ->willThrowException(new \Exception('some error')); $this->logger ->expects(self::exactly(6)) ->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 organization's files, please proceed manually."], ["An error happened while deleting the person's files, please proceed manually (id=1)."], ["An error happened while deleting the person's files, please proceed manually (id=2)."], ["An error happened while deleting the person's files, please proceed manually (id=3)."], ); $result = $organizationFactory->delete($organizationDeletionRequest); $this->assertEquals( $organizationDeletionRequest, $result ); } 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); } }