OrganizationFactoryTest.php 89 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Tests\Unit\Service\Organization;
  4. use App\ApiResources\Organization\OrganizationCreationRequest;
  5. use App\ApiResources\Organization\OrganizationDeletionRequest;
  6. use App\ApiResources\Organization\OrganizationMemberCreationRequest;
  7. use App\Entity\Access\Access;
  8. use App\Entity\Access\FunctionType;
  9. use App\Entity\Core\ContactPoint;
  10. use App\Entity\Core\Country;
  11. use App\Entity\Education\Cycle;
  12. use App\Entity\Network\Network;
  13. use App\Entity\Network\NetworkOrganization;
  14. use App\Entity\Organization\Organization;
  15. use App\Entity\Organization\OrganizationAddressPostal;
  16. use App\Entity\Organization\Parameters;
  17. use App\Entity\Organization\Settings;
  18. use App\Entity\Organization\Subdomain;
  19. use App\Entity\Person\Person;
  20. use App\Entity\Person\PersonAddressPostal;
  21. use App\Enum\Access\FunctionEnum;
  22. use App\Enum\Core\ContactPointTypeEnum;
  23. use App\Enum\Education\CycleEnum;
  24. use App\Enum\Network\NetworkEnum;
  25. use App\Enum\Organization\AddressPostalOrganizationTypeEnum;
  26. use App\Enum\Organization\LegalEnum;
  27. use App\Enum\Organization\PrincipalTypeEnum;
  28. use App\Enum\Organization\SettingsProductEnum;
  29. use App\Enum\Person\AddressPostalPersonTypeEnum;
  30. use App\Enum\Person\GenderEnum;
  31. use App\Repository\Access\FunctionTypeRepository;
  32. use App\Repository\Core\CountryRepository;
  33. use App\Repository\Organization\OrganizationIdentificationRepository;
  34. use App\Repository\Organization\OrganizationRepository;
  35. use App\Repository\Person\PersonRepository;
  36. use App\Service\ApiLegacy\ApiLegacyRequestService;
  37. use App\Service\Dolibarr\DolibarrApiService;
  38. use App\Service\Organization\OrganizationFactory;
  39. use App\Service\Organization\Utils as OrganizationUtils;
  40. use App\Service\Typo3\BindFileService;
  41. use App\Service\Typo3\SubdomainService;
  42. use App\Service\Typo3\Typo3Service;
  43. use App\Service\Utils\DatesUtils;
  44. use Doctrine\Common\Collections\ArrayCollection;
  45. use Doctrine\ORM\EntityManagerInterface;
  46. use libphonenumber\PhoneNumber;
  47. use libphonenumber\PhoneNumberUtil;
  48. use PHPUnit\Framework\MockObject\MockObject;
  49. use PHPUnit\Framework\TestCase;
  50. use Psr\Log\LoggerInterface;
  51. use Symfony\Component\HttpFoundation\Response;
  52. use Symfony\Contracts\HttpClient\ResponseInterface;
  53. class TestableOrganizationFactory extends OrganizationFactory
  54. {
  55. public function setPhoneNumberUtil(PhoneNumberUtil $phoneNumberUtil): void
  56. {
  57. $this->phoneNumberUtil = $phoneNumberUtil;
  58. }
  59. public function interruptIfOrganizationExists(OrganizationCreationRequest $organizationCreationRequest): void
  60. {
  61. parent::interruptIfOrganizationExists($organizationCreationRequest);
  62. }
  63. public function validateSubdomain(string $subdomainValue): void
  64. {
  65. parent::validateSubdomain($subdomainValue);
  66. }
  67. public function makeOrganizationWithRelations(
  68. OrganizationCreationRequest $organizationCreationRequest,
  69. ): Organization {
  70. return parent::makeOrganizationWithRelations($organizationCreationRequest);
  71. }
  72. public function makeOrganization(OrganizationCreationRequest $organizationCreationRequest): Organization
  73. {
  74. return parent::makeOrganization($organizationCreationRequest);
  75. }
  76. public function makeParameters(OrganizationCreationRequest $organizationCreationRequest): Parameters
  77. {
  78. return parent::makeParameters($organizationCreationRequest);
  79. }
  80. public function makeSettings(OrganizationCreationRequest $organizationCreationRequest): Settings
  81. {
  82. return parent::makeSettings($organizationCreationRequest);
  83. }
  84. public function makePostalAddress(OrganizationCreationRequest $organizationCreationRequest): OrganizationAddressPostal
  85. {
  86. return parent::makePostalAddress($organizationCreationRequest);
  87. }
  88. public function makeContactPoint(OrganizationCreationRequest $organizationCreationRequest): ContactPoint
  89. {
  90. return parent::makeContactPoint($organizationCreationRequest);
  91. }
  92. public function makeNetworkOrganization(OrganizationCreationRequest $organizationCreationRequest): NetworkOrganization
  93. {
  94. return parent::makeNetworkOrganization($organizationCreationRequest);
  95. }
  96. public function makeAdminAccess(OrganizationCreationRequest $organizationCreationRequest): Access
  97. {
  98. return parent::makeAdminAccess($organizationCreationRequest);
  99. }
  100. public function makeCycles(): array
  101. {
  102. return parent::makeCycles();
  103. }
  104. public function makeAccess(int|OrganizationMemberCreationRequest $creationRequestData, FunctionEnum $function, \DateTime $creationDate, ?int $authorId): Access
  105. {
  106. return parent::makeAccess($creationRequestData, $function, $creationDate, $authorId);
  107. }
  108. public function makePersonPostalAddress(OrganizationMemberCreationRequest $organizationMemberCreationRequest, \DateTime $creationDate, ?int $authorId): PersonAddressPostal
  109. {
  110. return parent::makePersonPostalAddress($organizationMemberCreationRequest, $creationDate, $authorId);
  111. }
  112. public function makePersonContactPoint(OrganizationMemberCreationRequest $organizationMemberCreationRequest, \DateTime $creationDate, ?int $authorId): ContactPoint
  113. {
  114. return parent::makePersonContactPoint($organizationMemberCreationRequest, $creationDate, $authorId);
  115. }
  116. public function makeSubdomain(OrganizationCreationRequest $organizationCreationRequest): Subdomain
  117. {
  118. return parent::makeSubdomain($organizationCreationRequest);
  119. }
  120. public function createTypo3Website(Organization $organization): ?int
  121. {
  122. return parent::createTypo3Website($organization);
  123. }
  124. public function updateAdminassosDb(Organization $organization): void
  125. {
  126. parent::updateAdminassosDb($organization);
  127. }
  128. public function normalizeIdentificationField(string $value): string
  129. {
  130. return parent::normalizeIdentificationField($value);
  131. }
  132. public function deleteOrganizationAccesses(Organization $organization): void
  133. {
  134. parent::deleteOrganizationAccesses($organization);
  135. }
  136. public function deleteTypo3Website(Organization $organization): void
  137. {
  138. parent::deleteTypo3Website($organization);
  139. }
  140. public function switchDolibarrSocietyToProspect(Organization $organization): void
  141. {
  142. parent::switchDolibarrSocietyToProspect($organization);
  143. }
  144. public function deleteOrganizationFiles(Organization $organization): void
  145. {
  146. parent::deleteOrganizationFiles($organization);
  147. }
  148. public function deleteDirectoriesV1(Organization $organization): void
  149. {
  150. parent::deleteDirectoriesV1($organization);
  151. }
  152. public function deleteDirectories59(Organization $organization): void
  153. {
  154. parent::deleteDirectories59($organization);
  155. }
  156. }
  157. class OrganizationFactoryTest extends TestCase
  158. {
  159. private readonly MockObject|SubdomainService $subdomainService;
  160. private readonly MockObject|OrganizationRepository $organizationRepository;
  161. private readonly MockObject|CountryRepository $countryRepository;
  162. private readonly MockObject|OrganizationUtils $organizationUtils;
  163. private readonly MockObject|Typo3Service $typo3Service;
  164. private readonly MockObject|DolibarrApiService $dolibarrApiService;
  165. private readonly MockObject|EntityManagerInterface $entityManager;
  166. private readonly MockObject|PersonRepository $personRepository;
  167. private readonly MockObject|BindFileService $bindFileService;
  168. private readonly MockObject|LoggerInterface $logger;
  169. private readonly MockObject|OrganizationIdentificationRepository $organizationIdentificationRepository;
  170. private readonly MockObject|ApiLegacyRequestService $apiLegacyRequestService;
  171. private readonly MockObject|PhoneNumberUtil $phoneNumberUtil;
  172. private readonly MockObject|FunctionTypeRepository $functionTypeRepository;
  173. public function setUp(): void
  174. {
  175. $this->subdomainService = $this->getMockBuilder(SubdomainService::class)->disableOriginalConstructor()->getMock();
  176. $this->organizationRepository = $this->getMockBuilder(OrganizationRepository::class)->disableOriginalConstructor()->getMock();
  177. $this->countryRepository = $this->getMockBuilder(CountryRepository::class)->disableOriginalConstructor()->getMock();
  178. $this->organizationUtils = $this->getMockBuilder(OrganizationUtils::class)->disableOriginalConstructor()->getMock();
  179. $this->typo3Service = $this->getMockBuilder(Typo3Service::class)->disableOriginalConstructor()->getMock();
  180. $this->dolibarrApiService = $this->getMockBuilder(DolibarrApiService::class)->disableOriginalConstructor()->getMock();
  181. $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
  182. $this->personRepository = $this->getMockBuilder(PersonRepository::class)->disableOriginalConstructor()->getMock();
  183. $this->bindFileService = $this->getMockBuilder(BindFileService::class)->disableOriginalConstructor()->getMock();
  184. $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
  185. $this->organizationIdentificationRepository = $this->getMockBuilder(OrganizationIdentificationRepository::class)->disableOriginalConstructor()->getMock();
  186. $this->apiLegacyRequestService = $this->getMockBuilder(ApiLegacyRequestService::class)->disableOriginalConstructor()->getMock();
  187. $this->phoneNumberUtil = $this->getMockBuilder(PhoneNumberUtil::class)->disableOriginalConstructor()->getMock();
  188. $this->functionTypeRepository = $this->getMockBuilder(FunctionTypeRepository::class)->disableOriginalConstructor()->getMock();
  189. }
  190. public function tearDown(): void
  191. {
  192. DatesUtils::clearFakeDatetime();
  193. }
  194. private function getOrganizationFactoryMockFor(string $methodName): TestableOrganizationFactory|MockObject
  195. {
  196. $organizationFactory = $this
  197. ->getMockBuilder(TestableOrganizationFactory::class)
  198. ->setConstructorArgs(
  199. [
  200. $this->subdomainService,
  201. $this->organizationRepository,
  202. $this->countryRepository,
  203. $this->organizationUtils,
  204. $this->typo3Service,
  205. $this->dolibarrApiService,
  206. $this->entityManager,
  207. $this->personRepository,
  208. $this->bindFileService,
  209. $this->organizationIdentificationRepository,
  210. $this->apiLegacyRequestService,
  211. $this->functionTypeRepository,
  212. ])
  213. ->setMethodsExcept(['setLoggerInterface', 'setPhoneNumberUtil', $methodName])
  214. ->getMock();
  215. $organizationFactory->setLoggerInterface($this->logger);
  216. $organizationFactory->setPhoneNumberUtil($this->phoneNumberUtil);
  217. return $organizationFactory;
  218. }
  219. public function testCreate(): void
  220. {
  221. $organizationFactory = $this->getOrganizationFactoryMockFor('create');
  222. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  223. $organizationCreationRequest->method('getName')->willReturn('foo');
  224. $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain');
  225. $organizationCreationRequest->method('isClient')->willReturn(false);
  226. $organizationCreationRequest->method('getCreateWebsite')->willReturn(true);
  227. $this->entityManager->expects(self::once())->method('beginTransaction');
  228. $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists');
  229. $organizationFactory->expects(self::once())->method('validateSubdomain')->with('subdomain');
  230. $organization = $this->getMockBuilder(Organization::class)->getMock();
  231. $organizationFactory
  232. ->expects(self::once())
  233. ->method('makeOrganizationWithRelations')
  234. ->with($organizationCreationRequest)
  235. ->willReturn($organization);
  236. $this->entityManager->expects(self::once())->method('persist')->with($organization);
  237. $this->entityManager->expects(self::once())->method('flush');
  238. $this->entityManager->expects(self::once())->method('commit');
  239. $this->dolibarrApiService
  240. ->expects(self::once())
  241. ->method('createSociety')
  242. ->with($organization, false)
  243. ->willReturn(456);
  244. $this->bindFileService
  245. ->expects(self::once())
  246. ->method('registerSubdomain')
  247. ->with('subdomain');
  248. $organizationFactory
  249. ->expects(self::once())
  250. ->method('createTypo3Website')
  251. ->with($organization)
  252. ->willReturn(789);
  253. $this->logger
  254. ->method('info')
  255. ->withConsecutive(
  256. ["Start the creation of a new organization named 'foo'"],
  257. ["Subdomain is valid and available : 'subdomain'"],
  258. ['Organization created with all its relations'],
  259. ['Organization persisted in the DB'],
  260. ['New dolibarr structure created (uid : 456)'],
  261. ['Subdomain registered'],
  262. ['Typo3 website created (root uid: 789)'],
  263. ['Adminassos db updated']
  264. );
  265. $organizationCreationRequest
  266. ->expects(self::once())
  267. ->method('setStatus')
  268. ->with(OrganizationCreationRequest::STATUS_OK);
  269. $result = $organizationFactory->create($organizationCreationRequest);
  270. $this->assertEquals(
  271. $organization,
  272. $result
  273. );
  274. }
  275. public function testCreateWithRollback(): void
  276. {
  277. $organizationFactory = $this->getOrganizationFactoryMockFor('create');
  278. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  279. $organizationCreationRequest->method('getName')->willReturn('foo');
  280. $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain');
  281. $organizationCreationRequest->method('isClient')->willReturn(false);
  282. $organizationCreationRequest->method('getCreateWebsite')->willReturn(true);
  283. $this->entityManager->expects(self::once())->method('beginTransaction');
  284. $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists');
  285. $organizationFactory->expects(self::once())->method('validateSubdomain')->with('subdomain');
  286. $organization = $this->getMockBuilder(Organization::class)->getMock();
  287. $organizationFactory
  288. ->expects(self::once())
  289. ->method('makeOrganizationWithRelations')
  290. ->with($organizationCreationRequest)
  291. ->willReturn($organization);
  292. $this->entityManager->expects(self::once())->method('persist')->with($organization);
  293. $this->entityManager->expects(self::once())->method('flush')->willThrowException(new \RuntimeException('some error'));
  294. $this->entityManager->expects(self::once())->method('rollback');
  295. $this->dolibarrApiService
  296. ->expects(self::never())
  297. ->method('createSociety');
  298. $this->bindFileService
  299. ->expects(self::never())
  300. ->method('registerSubdomain');
  301. $organizationFactory
  302. ->expects(self::never())
  303. ->method('createTypo3Website');
  304. $this->logger
  305. ->method('info')
  306. ->withConsecutive(
  307. ["Start the creation of a new organization named 'foo'"],
  308. ["Subdomain is valid and available : 'subdomain'"],
  309. ['Organization created with all its relations']
  310. );
  311. $this->logger
  312. ->method('critical')
  313. ->with(
  314. $this->matchesRegularExpression('/^An error happened, operation cancelled\nRuntimeException: some error.*/')
  315. );
  316. $this->expectException(\RuntimeException::class);
  317. $result = $organizationFactory->create($organizationCreationRequest);
  318. }
  319. public function testCreateWithExistingOrganization(): void
  320. {
  321. $organizationFactory = $this->getOrganizationFactoryMockFor('create');
  322. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  323. $organizationCreationRequest->method('getName')->willReturn('foo');
  324. $this->entityManager->expects(self::once())->method('beginTransaction');
  325. $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists')->willThrowException(new \RuntimeException('An organization named foo already exists'));
  326. $organizationFactory->expects(self::never())->method('validateSubdomain');
  327. $organizationFactory
  328. ->expects(self::never())
  329. ->method('makeOrganizationWithRelations');
  330. $this->entityManager->expects(self::never())->method('persist');
  331. $this->entityManager->expects(self::never())->method('flush');
  332. $this->entityManager->expects(self::once())->method('rollback');
  333. $this->dolibarrApiService
  334. ->expects(self::never())
  335. ->method('createSociety');
  336. $this->bindFileService
  337. ->expects(self::never())
  338. ->method('registerSubdomain');
  339. $organizationFactory
  340. ->expects(self::never())
  341. ->method('createTypo3Website');
  342. $this->logger
  343. ->method('info')
  344. ->withConsecutive(
  345. ["Start the creation of a new organization named 'foo'"],
  346. );
  347. $this->logger
  348. ->method('critical')
  349. ->with(
  350. $this->matchesRegularExpression("/^An error happened, operation cancelled\nRuntimeException: An organization named foo already exists.*/")
  351. );
  352. $this->expectException(\RuntimeException::class);
  353. $this->expectExceptionMessage('An organization named foo already exists');
  354. $result = $organizationFactory->create($organizationCreationRequest);
  355. }
  356. public function testCreateNoWebsiteAndIsClient(): void
  357. {
  358. $organizationFactory = $this->getOrganizationFactoryMockFor('create');
  359. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  360. $organizationCreationRequest->method('getName')->willReturn('foo');
  361. $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain');
  362. $organizationCreationRequest->method('isClient')->willReturn(true);
  363. $organizationCreationRequest->method('getCreateWebsite')->willReturn(false);
  364. $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists');
  365. $organization = $this->getMockBuilder(Organization::class)->getMock();
  366. $organizationFactory
  367. ->expects(self::once())
  368. ->method('makeOrganizationWithRelations')
  369. ->with($organizationCreationRequest)
  370. ->willReturn($organization);
  371. $this->dolibarrApiService
  372. ->method('createSociety')
  373. ->with($organization, true)
  374. ->willReturn(456);
  375. $organizationFactory
  376. ->expects(self::never())
  377. ->method('createTypo3Website');
  378. $this->logger
  379. ->expects(self::once())
  380. ->method('warning')
  381. ->with('Typo3 website creation was not required');
  382. $result = $organizationFactory->create($organizationCreationRequest);
  383. $this->assertEquals(
  384. $organization,
  385. $result
  386. );
  387. }
  388. public function testCreateWithErrors(): void
  389. {
  390. $organizationFactory = $this->getOrganizationFactoryMockFor('create');
  391. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  392. $organizationCreationRequest->method('getName')->willReturn('foo');
  393. $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain');
  394. $organizationCreationRequest->method('isClient')->willReturn(true);
  395. $organizationCreationRequest->method('getCreateWebsite')->willReturn(true);
  396. $organizationFactory->expects(self::once())->method('interruptIfOrganizationExists');
  397. $organization = $this->getMockBuilder(Organization::class)->getMock();
  398. $organizationFactory
  399. ->expects(self::once())
  400. ->method('makeOrganizationWithRelations')
  401. ->with($organizationCreationRequest)
  402. ->willReturn($organization);
  403. $this->dolibarrApiService
  404. ->method('createSociety')
  405. ->with($organization, true)
  406. ->willThrowException(new \RuntimeException('An error happened'));
  407. $this->bindFileService
  408. ->method('registerSubdomain')
  409. ->with('subdomain')
  410. ->willThrowException(new \RuntimeException('An error happened'));
  411. $organizationFactory
  412. ->method('createTypo3Website')
  413. ->with($organization)
  414. ->willThrowException(new \RuntimeException('An error happened'));
  415. $organizationFactory
  416. ->method('updateAdminassosDb')
  417. ->with($organization)
  418. ->willThrowException(new \RuntimeException('An error happened'));
  419. $this->logger
  420. ->expects(self::exactly(4))
  421. ->method('critical')
  422. ->willReturnOnConsecutiveCalls([
  423. 'An error happened while creating the dolibarr society, please proceed manually.',
  424. 'An error happened while updating the bind file, please proceed manually.',
  425. 'An error happened while creating the typo3 website, please proceed manually.',
  426. 'An error happened while updating the adminassos db, please proceed manually.',
  427. ]);
  428. $this->logger
  429. ->expects(self::once())
  430. ->method('warning')
  431. ->with('-- Operation ended with errors, check the logs for more information --');
  432. $organizationCreationRequest
  433. ->expects(self::once())
  434. ->method('setStatus')
  435. ->with(OrganizationCreationRequest::STATUS_OK_WITH_ERRORS);
  436. $result = $organizationFactory->create($organizationCreationRequest);
  437. $this->assertEquals(
  438. $organization,
  439. $result
  440. );
  441. }
  442. public function testInterruptIfOrganizationExistsNotExisting(): void
  443. {
  444. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  445. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  446. $organizationCreationRequest->method('getName')->willReturn('foo');
  447. $organizationCreationRequest->method('getSiretNumber')->willReturn('');
  448. $organizationCreationRequest->method('getWaldecNumber')->willReturn('');
  449. $organizationCreationRequest->method('getIdentifier')->willReturn('');
  450. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  451. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  452. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  453. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  454. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  455. $this->organizationIdentificationRepository
  456. ->expects(self::exactly(2))
  457. ->method('findOneBy')
  458. ->willReturn(null);
  459. $organizationFactory
  460. ->method('normalizeIdentificationField')
  461. ->willReturnMap([
  462. ['foo', 'foo'],
  463. ['part1 part2 part3', 'part1 part2 part3'],
  464. ]);
  465. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  466. }
  467. public function testInterruptIfOrganizationExistsNotExistingNonExistingWithIdentifiers(): void
  468. {
  469. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  470. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  471. $organizationCreationRequest->method('getName')->willReturn('foo');
  472. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  473. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  474. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  475. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  476. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  477. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  478. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  479. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  480. $organizationFactory
  481. ->method('normalizeIdentificationField')
  482. ->willReturnMap([
  483. ['foo', 'foo'],
  484. ['part1 part2 part3', 'part1 part2 part3'],
  485. ]);
  486. $this->organizationIdentificationRepository
  487. ->expects(self::exactly(5))
  488. ->method('findOneBy')
  489. ->willReturnMap([
  490. [['siretNumber' => '123456'], null, null],
  491. [['waldecNumber' => 'W123456'], null, null],
  492. [['identifier' => 'FR000000000000'], null, null],
  493. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null],
  494. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null],
  495. ]);
  496. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  497. }
  498. public function testInterruptIfOrganizationExistsExistingWithSiret(): void
  499. {
  500. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  501. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  502. $organizationCreationRequest->method('getName')->willReturn('foo');
  503. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  504. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  505. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  506. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  507. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  508. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  509. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  510. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  511. $organizationFactory
  512. ->method('normalizeIdentificationField')
  513. ->willReturnMap([
  514. ['foo', 'foo'],
  515. ['part1 part2 part3', 'part1 part2 part3'],
  516. ]);
  517. $organization = $this->getMockBuilder(Organization::class)->getMock();
  518. $this->organizationIdentificationRepository
  519. ->method('findOneBy')
  520. ->willReturnMap([
  521. [['siretNumber' => '123456'], null, $organization],
  522. [['waldecNumber' => 'W123456'], null, null],
  523. [['identifier' => 'FR000000000000'], null, null],
  524. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null],
  525. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null],
  526. ]);
  527. $this->expectException(\RuntimeException::class);
  528. $this->expectExceptionMessage("This siret number is already registered : '123456'");
  529. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  530. }
  531. public function testInterruptIfOrganizationExistsExistingWithWaldec(): void
  532. {
  533. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  534. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  535. $organizationCreationRequest->method('getName')->willReturn('foo');
  536. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  537. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  538. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  539. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  540. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  541. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  542. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  543. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  544. $organizationFactory
  545. ->method('normalizeIdentificationField')
  546. ->willReturnMap([
  547. ['foo', 'foo'],
  548. ['part1 part2 part3', 'part1 part2 part3'],
  549. ]);
  550. $organization = $this->getMockBuilder(Organization::class)->getMock();
  551. $this->organizationIdentificationRepository
  552. ->method('findOneBy')
  553. ->willReturnMap([
  554. [['siretNumber' => '123456'], null, null],
  555. [['waldecNumber' => 'W123456'], null, $organization],
  556. [['identifier' => 'FR000000000000'], null, null],
  557. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null],
  558. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null],
  559. ]);
  560. $this->expectException(\RuntimeException::class);
  561. $this->expectExceptionMessage("This RNA identifier (waldec number) is already registered : 'W123456'");
  562. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  563. }
  564. public function testInterruptIfOrganizationExistsExistingWithCMFIdentifier(): void
  565. {
  566. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  567. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  568. $organizationCreationRequest->method('getName')->willReturn('foo');
  569. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  570. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  571. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  572. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  573. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  574. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  575. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  576. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  577. $organizationFactory
  578. ->method('normalizeIdentificationField')
  579. ->willReturnMap([
  580. ['foo', 'foo'],
  581. ['part1 part2 part3', 'part1 part2 part3'],
  582. ]);
  583. $organization = $this->getMockBuilder(Organization::class)->getMock();
  584. $this->organizationIdentificationRepository
  585. ->method('findOneBy')
  586. ->willReturnMap([
  587. [['siretNumber' => '123456'], null, null],
  588. [['waldecNumber' => 'W123456'], null, null],
  589. [['identifier' => 'FR000000000000'], null, $organization],
  590. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null],
  591. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null],
  592. ]);
  593. $this->expectException(\RuntimeException::class);
  594. $this->expectExceptionMessage("This CMF identifier is already registered : 'FR000000000000'");
  595. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  596. }
  597. public function testInterruptIfOrganizationExistsExistingWithSameNameAndCity(): void
  598. {
  599. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  600. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  601. $organizationCreationRequest->method('getName')->willReturn('foo');
  602. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  603. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  604. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  605. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  606. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  607. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  608. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  609. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  610. $organizationFactory
  611. ->method('normalizeIdentificationField')
  612. ->willReturnMap([
  613. ['foo', 'foo'],
  614. ['part1 part2 part3', 'part1 part2 part3'],
  615. ]);
  616. $organization = $this->getMockBuilder(Organization::class)->getMock();
  617. $this->organizationIdentificationRepository
  618. ->method('findOneBy')
  619. ->willReturnMap([
  620. [['siretNumber' => '123456'], null, null],
  621. [['waldecNumber' => 'W123456'], null, null],
  622. [['identifier' => 'FR000000000000'], null, null],
  623. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, $organization],
  624. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, null],
  625. ]);
  626. $this->expectException(\RuntimeException::class);
  627. $this->expectExceptionMessage("An organization named 'foo' already exists in Paris");
  628. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  629. }
  630. public function testInterruptIfOrganizationExistsExistingWithSameAddress(): void
  631. {
  632. $organizationFactory = $this->getOrganizationFactoryMockFor('interruptIfOrganizationExists');
  633. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  634. $organizationCreationRequest->method('getName')->willReturn('foo');
  635. $organizationCreationRequest->method('getSiretNumber')->willReturn('123456');
  636. $organizationCreationRequest->method('getWaldecNumber')->willReturn('W123456');
  637. $organizationCreationRequest->method('getIdentifier')->willReturn('FR000000000000');
  638. $organizationCreationRequest->method('getStreetAddress1')->willReturn('part1');
  639. $organizationCreationRequest->method('getStreetAddress2')->willReturn('part2');
  640. $organizationCreationRequest->method('getStreetAddress3')->willReturn('part3');
  641. $organizationCreationRequest->method('getCity')->willReturn('Paris');
  642. $organizationCreationRequest->method('getPostalCode')->willReturn('75000');
  643. $organizationFactory
  644. ->method('normalizeIdentificationField')
  645. ->willReturnMap([
  646. ['foo', 'foo'],
  647. ['part1 part2 part3', 'part1 part2 part3'],
  648. ]);
  649. $organization = $this->getMockBuilder(Organization::class)->getMock();
  650. $this->organizationIdentificationRepository
  651. ->method('findOneBy')
  652. ->willReturnMap([
  653. [['siretNumber' => '123456'], null, null],
  654. [['waldecNumber' => 'W123456'], null, null],
  655. [['identifier' => 'FR000000000000'], null, null],
  656. [['normalizedName' => 'foo', 'addressCity' => 'Paris'], null, null],
  657. [['normalizedAddress' => 'part1 part2 part3', 'addressCity' => 'Paris', 'postalCode' => '75000'], null, $organization],
  658. ]);
  659. $this->expectException(\RuntimeException::class);
  660. $this->expectExceptionMessage('An organization already exists at this address.');
  661. $organizationFactory->interruptIfOrganizationExists($organizationCreationRequest);
  662. }
  663. public function testValidateSubdomain(): void
  664. {
  665. $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain');
  666. $this->subdomainService->expects(self::once())->method('isValidSubdomain')->willReturn(true);
  667. $this->subdomainService->expects(self::once())->method('isReservedSubdomain')->willReturn(false);
  668. $this->subdomainService->expects(self::once())->method('isRegistered')->willReturn(false);
  669. $organizationFactory->validateSubdomain('foo');
  670. }
  671. public function testValidateSubdomainIsNotValid(): void
  672. {
  673. $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain');
  674. $this->subdomainService->method('isValidSubdomain')->willReturn(false);
  675. $this->subdomainService->method('isReservedSubdomain')->willReturn(false);
  676. $this->subdomainService->method('isRegistered')->willReturn(false);
  677. $this->expectException(\RuntimeException::class);
  678. $this->expectExceptionMessage('Not a valid subdomain : foo');
  679. $organizationFactory->validateSubdomain('foo');
  680. }
  681. public function testValidateSubdomainIsReserved(): void
  682. {
  683. $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain');
  684. $this->subdomainService->method('isValidSubdomain')->willReturn(true);
  685. $this->subdomainService->method('isReservedSubdomain')->willReturn(true);
  686. $this->subdomainService->method('isRegistered')->willReturn(false);
  687. $this->expectException(\RuntimeException::class);
  688. $this->expectExceptionMessage('This subdomain is not available : foo');
  689. $organizationFactory->validateSubdomain('foo');
  690. }
  691. public function testValidateSubdomainIsRegistered(): void
  692. {
  693. $organizationFactory = $this->getOrganizationFactoryMockFor('validateSubdomain');
  694. $this->subdomainService->method('isValidSubdomain')->willReturn(true);
  695. $this->subdomainService->method('isReservedSubdomain')->willReturn(false);
  696. $this->subdomainService->method('isRegistered')->willReturn(true);
  697. $this->expectException(\RuntimeException::class);
  698. $this->expectExceptionMessage('This subdomain is already registered : foo');
  699. $organizationFactory->validateSubdomain('foo');
  700. }
  701. public function testMakeOrganizationWithRelations(): void
  702. {
  703. $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganizationWithRelations');
  704. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  705. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  706. $organizationCreationRequest->method('getCreationDate')->willReturn($creationDate);
  707. $organizationCreationRequest->method('getAuthorId')->willReturn(1);
  708. $organization = $this->getMockBuilder(Organization::class)->getMock();
  709. // Création de l'organisation
  710. $organizationFactory
  711. ->expects(self::once())
  712. ->method('makeOrganization')
  713. ->with($organizationCreationRequest)
  714. ->willReturn($organization);
  715. // Création des Parameters
  716. $parameters = $this->getMockBuilder(Parameters::class)->getMock();
  717. $organizationFactory
  718. ->expects(self::once())
  719. ->method('makeParameters')
  720. ->with($organizationCreationRequest)
  721. ->willReturn($parameters);
  722. $organization->expects(self::once())->method('setParameters')->with($parameters);
  723. // Création des Settings
  724. $settings = $this->getMockBuilder(Settings::class)->getMock();
  725. $organizationFactory
  726. ->expects(self::once())
  727. ->method('makeSettings')
  728. ->with($organizationCreationRequest)
  729. ->willReturn($settings);
  730. $organization->expects(self::once())->method('setSettings')->with($settings);
  731. // Création de l'adresse postale
  732. $organizationAddressPostal = $this->getMockBuilder(OrganizationAddressPostal::class)->getMock();
  733. $organizationFactory
  734. ->expects(self::once())
  735. ->method('makePostalAddress')
  736. ->with($organizationCreationRequest)
  737. ->willReturn($organizationAddressPostal);
  738. $organization->expects(self::once())->method('addOrganizationAddressPostal')->with($organizationAddressPostal);
  739. // Création du point de contact
  740. $contactPoint = $this->getMockBuilder(ContactPoint::class)->getMock();
  741. $organizationFactory
  742. ->expects(self::once())
  743. ->method('makeContactPoint')
  744. ->with($organizationCreationRequest)
  745. ->willReturn($contactPoint);
  746. $organization->expects(self::once())->method('addContactPoint')->with($contactPoint);
  747. // Rattachement au réseau
  748. $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
  749. $organizationFactory
  750. ->expects(self::once())
  751. ->method('makeNetworkOrganization')
  752. ->with($organizationCreationRequest)
  753. ->willReturn($networkOrganization);
  754. $organization->expects(self::once())->method('addNetworkOrganization')->with($networkOrganization);
  755. // Créé l'admin
  756. $adminAccess = $this->getMockBuilder(Access::class)->getMock();
  757. $organizationFactory
  758. ->expects(self::once())
  759. ->method('makeAdminAccess')
  760. ->with($organizationCreationRequest)
  761. ->willReturn($adminAccess);
  762. // Le `$organization->expects(...)->method('addAccess')` est implémenté plus loin,
  763. // après la création du président et du directeur.
  764. // Création des cycles
  765. $cycle1 = $this->getMockBuilder(Cycle::class)->getMock();
  766. $cycle2 = $this->getMockBuilder(Cycle::class)->getMock();
  767. $cycle3 = $this->getMockBuilder(Cycle::class)->getMock();
  768. $organizationFactory
  769. ->expects(self::once())
  770. ->method('makeCycles')
  771. ->willReturn([$cycle1, $cycle2, $cycle3]);
  772. $organization->expects(self::exactly(3))->method('addCycle')->withConsecutive([$cycle1], [$cycle2], [$cycle3]);
  773. // Création du président et du directeur
  774. $organizationMemberCreationRequest1 = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  775. $organizationCreationRequest->method('getPresident')->willReturn($organizationMemberCreationRequest1);
  776. $organizationMemberCreationRequest2 = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  777. $organizationCreationRequest->method('getDirector')->willReturn($organizationMemberCreationRequest2);
  778. $access1 = $this->getMockBuilder(Access::class)->getMock();
  779. $access2 = $this->getMockBuilder(Access::class)->getMock();
  780. $organizationFactory
  781. ->expects(self::exactly(2))
  782. ->method('makeAccess')
  783. ->willReturnMap([
  784. [$organizationMemberCreationRequest1, FunctionEnum::PRESIDENT, $creationDate, 1, $access1],
  785. [$organizationMemberCreationRequest2, FunctionEnum::DIRECTOR, $creationDate, 1, $access2],
  786. ]);
  787. $organization
  788. ->expects(self::exactly(3))
  789. ->method('addAccess')
  790. ->withConsecutive([$adminAccess], [$access1], [$access2]);
  791. // Création du sous-domaine
  792. $subdomain = $this->getMockBuilder(Subdomain::class)->getMock();
  793. $organizationFactory
  794. ->expects(self::once())
  795. ->method('makeSubdomain')
  796. ->with($organizationCreationRequest)
  797. ->willReturn($subdomain);
  798. $organization->expects(self::once())->method('addSubdomain')->with($subdomain);
  799. // Enregistrement du sous domaine dans Parameters (retrocompatibilité v1)
  800. $organization->method('getParameters')->willReturn($parameters);
  801. $organizationCreationRequest->method('getSubdomain')->willReturn('foo');
  802. $parameters->expects(self::once())->method('setSubDomain')->with('foo');
  803. $parameters->expects(self::once())->method('setOtherWebsite')->with('https://foo.opentalent.fr');
  804. $result = $organizationFactory->makeOrganizationWithRelations($organizationCreationRequest);
  805. $this->assertEquals(
  806. $result,
  807. $organization
  808. );
  809. }
  810. public function testMakeOrganizationWithRelationsNoPresidentNoDirector(): void
  811. {
  812. $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganizationWithRelations');
  813. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  814. $organization = $this->getMockBuilder(Organization::class)->getMock();
  815. // Création de l'organisation
  816. $organizationFactory
  817. ->expects(self::once())
  818. ->method('makeOrganization')
  819. ->with($organizationCreationRequest)
  820. ->willReturn($organization);
  821. $organizationCreationRequest->method('getPresident')->willReturn(null);
  822. $organizationCreationRequest->method('getDirector')->willReturn(null);
  823. // Un seul appel, pour l'adminAccess
  824. $organization
  825. ->expects(self::once())
  826. ->method('addAccess');
  827. $organizationFactory->makeOrganizationWithRelations($organizationCreationRequest);
  828. }
  829. public function testMakeOrganization()
  830. {
  831. $organizationFactory = $this->getOrganizationFactoryMockFor('makeOrganization');
  832. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  833. $organizationCreationRequest->method('getName')->willReturn('My Organization');
  834. $organizationCreationRequest->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901);
  835. $organizationCreationRequest->method('getPrincipalType')->willReturn(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY);
  836. $organization = $organizationFactory->makeOrganization($organizationCreationRequest);
  837. $this->assertEquals(
  838. 'My Organization',
  839. $organization->getName()
  840. );
  841. $this->assertEquals(
  842. LegalEnum::ASSOCIATION_LAW_1901,
  843. $organization->getLegalStatus()
  844. );
  845. $this->assertEquals(
  846. PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY,
  847. $organization->getPrincipalType()
  848. );
  849. }
  850. public function testMakeParameters(): void
  851. {
  852. $organizationFactory = $this->getOrganizationFactoryMockFor('makeParameters');
  853. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  854. $parameters = $organizationFactory->makeParameters($organizationCreationRequest);
  855. $this->assertInstanceOf(Parameters::class, $parameters);
  856. }
  857. public function testMakeSettings(): void
  858. {
  859. $organizationFactory = $this->getOrganizationFactoryMockFor('makeSettings');
  860. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  861. $organizationCreationRequest->method('getProduct')->willReturn(SettingsProductEnum::ARTIST_PREMIUM);
  862. $settings = $organizationFactory->makeSettings($organizationCreationRequest);
  863. $this->assertEquals(
  864. SettingsProductEnum::ARTIST_PREMIUM,
  865. $settings->getProduct()
  866. );
  867. }
  868. public function testMakePostalAddress(): void
  869. {
  870. $organizationFactory = $this->getOrganizationFactoryMockFor('makePostalAddress');
  871. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  872. $organizationCreationRequest->method('getStreetAddress1')->willReturn('address1');
  873. $organizationCreationRequest->method('getStreetAddress2')->willReturn('address2');
  874. $organizationCreationRequest->method('getStreetAddress3')->willReturn('address3');
  875. $organizationCreationRequest->method('getPostalCode')->willReturn('00000');
  876. $organizationCreationRequest->method('getCity')->willReturn('city');
  877. $organizationCreationRequest->method('getCountryId')->willReturn(1);
  878. $country = $this->getMockBuilder(Country::class)->getMock();
  879. $this->countryRepository->expects(self::once())->method('find')->with(1)->willReturn($country);
  880. $organizationAddressPostal = $organizationFactory->makePostalAddress($organizationCreationRequest);
  881. $this->assertEquals(
  882. AddressPostalOrganizationTypeEnum::ADDRESS_HEAD_OFFICE,
  883. $organizationAddressPostal->getType()
  884. );
  885. $addressPostal = $organizationAddressPostal->getAddressPostal();
  886. $this->assertEquals(
  887. 'address1',
  888. $addressPostal->getStreetAddress()
  889. );
  890. $this->assertEquals(
  891. 'address2',
  892. $addressPostal->getStreetAddressSecond()
  893. );
  894. $this->assertEquals(
  895. 'address3',
  896. $addressPostal->getStreetAddressThird()
  897. );
  898. $this->assertEquals(
  899. '00000',
  900. $addressPostal->getPostalCode()
  901. );
  902. $this->assertEquals(
  903. 'city',
  904. $addressPostal->getAddressCity()
  905. );
  906. $this->assertEquals(
  907. $country,
  908. $addressPostal->getAddressCountry()
  909. );
  910. }
  911. public function testMakePostalAddressUnexistingCountry(): void
  912. {
  913. $organizationFactory = $this->getOrganizationFactoryMockFor('makePostalAddress');
  914. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  915. $organizationCreationRequest->method('getCountryId')->willReturn(1);
  916. $this->countryRepository->expects(self::once())->method('find')->with(1)->willReturn(null);
  917. $this->expectException(\RuntimeException::class);
  918. $this->expectExceptionMessage('No country found for id 1');
  919. $organizationFactory->makePostalAddress($organizationCreationRequest);
  920. }
  921. public function testMakeContactPoint(): void
  922. {
  923. $organizationFactory = $this->getOrganizationFactoryMockFor('makeContactPoint');
  924. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  925. $organizationCreationRequest->method('getPhoneNumber')->willReturn('+33102030405');
  926. $organizationCreationRequest->method('getEmail')->willReturn('contact@domain.net');
  927. $this->phoneNumberUtil
  928. ->method('isPossibleNumber')
  929. ->with('+33102030405')
  930. ->willReturn(true);
  931. $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock();
  932. $this->phoneNumberUtil
  933. ->expects(self::once())
  934. ->method('parse')
  935. ->with('+33102030405')
  936. ->willReturn($phoneNumber);
  937. $contactPoint = $organizationFactory->makeContactPoint($organizationCreationRequest);
  938. $this->assertEquals(
  939. 'contact@domain.net',
  940. $contactPoint->getEmail()
  941. );
  942. $this->assertEquals(
  943. $phoneNumber,
  944. $contactPoint->getTelphone()
  945. );
  946. }
  947. public function testMakeContactPointInvalidPhoneNumber(): void
  948. {
  949. $organizationFactory = $this->getOrganizationFactoryMockFor('makeContactPoint');
  950. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  951. $organizationCreationRequest->method('getPhoneNumber')->willReturn('invalid');
  952. $organizationCreationRequest->method('getEmail')->willReturn('contact@domain.net');
  953. $this->phoneNumberUtil
  954. ->method('isPossibleNumber')
  955. ->with('invalid')
  956. ->willReturn(false);
  957. $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock();
  958. $this->phoneNumberUtil
  959. ->expects(self::never())
  960. ->method('parse');
  961. $this->expectException(\RuntimeException::class);
  962. $this->expectExceptionMessage('Phone number is invalid or missing');
  963. $organizationFactory->makeContactPoint($organizationCreationRequest);
  964. }
  965. public function testMakeNetworkOrganization(): void
  966. {
  967. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  968. DatesUtils::setFakeDatetime('2024-01-01');
  969. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  970. $organizationCreationRequest->method('getParentId')->willReturn(123);
  971. $parent = $this->getMockBuilder(Organization::class)->getMock();
  972. $settings = $this->getMockBuilder(Settings::class)->getMock();
  973. $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER);
  974. $parent->method('getSettings')->willReturn($settings);
  975. $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent);
  976. $network = $this->getMockBuilder(Network::class)->getMock();
  977. $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
  978. $networkOrganization->method('getNetwork')->willReturn($network);
  979. $this->organizationUtils
  980. ->expects(self::once())
  981. ->method('getActiveNetworkOrganization')
  982. ->with($parent)
  983. ->willReturn($networkOrganization);
  984. $networkOrganization = $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  985. $this->assertEquals(
  986. $parent,
  987. $networkOrganization->getParent()
  988. );
  989. $this->assertEquals(
  990. $network,
  991. $networkOrganization->getNetwork()
  992. );
  993. $this->assertEquals(
  994. '2024-01-01',
  995. $networkOrganization->getStartDate()->format('Y-m-d')
  996. );
  997. }
  998. public function testMakeNetworkOrganizationMissingParent(): void
  999. {
  1000. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  1001. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1002. $organizationCreationRequest->method('getParentId')->willReturn(123);
  1003. $this->expectException(\RuntimeException::class);
  1004. $this->expectExceptionMessage('No parent organization found for id 123');
  1005. $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn(null);
  1006. $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  1007. }
  1008. public function testMakeNetworkOrganizationParentIsNotManager(): void
  1009. {
  1010. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  1011. DatesUtils::setFakeDatetime('2024-01-01');
  1012. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1013. $organizationCreationRequest->method('getParentId')->willReturn(123);
  1014. $parent = $this->getMockBuilder(Organization::class)->getMock();
  1015. $settings = $this->getMockBuilder(Settings::class)->getMock();
  1016. $settings->method('getProduct')->willReturn(SettingsProductEnum::SCHOOL);
  1017. $parent->method('getSettings')->willReturn($settings);
  1018. $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent);
  1019. $this->expectException(\RuntimeException::class);
  1020. $this->expectExceptionMessage("Parent organization must have the product 'manager' (actual product: 'school')");
  1021. $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  1022. }
  1023. public function testMakeNetworkOrganizationMissingNetwork(): void
  1024. {
  1025. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  1026. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1027. $organizationCreationRequest->method('getParentId')->willReturn(123);
  1028. $parent = $this->getMockBuilder(Organization::class)->getMock();
  1029. $settings = $this->getMockBuilder(Settings::class)->getMock();
  1030. $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER);
  1031. $parent->method('getSettings')->willReturn($settings);
  1032. $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent);
  1033. $this->expectException(\RuntimeException::class);
  1034. $this->expectExceptionMessage('No network found for parent 123');
  1035. $this->organizationRepository->expects(self::once())->method('find')->with(123)->willReturn($parent);
  1036. $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  1037. }
  1038. public function testMakeNetworkOrganizationIsCMFInvalidIdentifier(): void
  1039. {
  1040. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  1041. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1042. $organizationCreationRequest->method('getParentId')->willReturn(123);
  1043. $organizationCreationRequest->method('getIdentifier')->willReturn('invalid');
  1044. $parent = $this->getMockBuilder(Organization::class)->getMock();
  1045. $settings = $this->getMockBuilder(Settings::class)->getMock();
  1046. $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER);
  1047. $parent->method('getSettings')->willReturn($settings);
  1048. $this->organizationRepository->method('find')->with(123)->willReturn($parent);
  1049. $network = $this->getMockBuilder(Network::class)->getMock();
  1050. $network->method('getId')->willReturn(NetworkEnum::CMF->value);
  1051. $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
  1052. $networkOrganization->method('getNetwork')->willReturn($network);
  1053. $this->organizationUtils
  1054. ->method('getActiveNetworkOrganization')
  1055. ->with($parent)
  1056. ->willReturn($networkOrganization);
  1057. $this->expectException(\RuntimeException::class);
  1058. $this->expectExceptionMessage('CMF identifier is missing or invalid.');
  1059. $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  1060. }
  1061. public function testMakeNetworkOrganizationIsNotCMFInvalidIdentifier(): void
  1062. {
  1063. $organizationFactory = $this->getOrganizationFactoryMockFor('makeNetworkOrganization');
  1064. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1065. $organizationCreationRequest->method('getParentId')->willReturn(123);
  1066. $organizationCreationRequest->method('getIdentifier')->willReturn('invalid');
  1067. $parent = $this->getMockBuilder(Organization::class)->getMock();
  1068. $settings = $this->getMockBuilder(Settings::class)->getMock();
  1069. $settings->method('getProduct')->willReturn(SettingsProductEnum::MANAGER);
  1070. $parent->method('getSettings')->willReturn($settings);
  1071. $this->organizationRepository->method('find')->with(123)->willReturn($parent);
  1072. $network = $this->getMockBuilder(Network::class)->getMock();
  1073. $network->method('getId')->willReturn(NetworkEnum::OUTOFNET->value);
  1074. $networkOrganization = $this->getMockBuilder(NetworkOrganization::class)->getMock();
  1075. $networkOrganization->method('getNetwork')->willReturn($network);
  1076. $this->organizationUtils
  1077. ->method('getActiveNetworkOrganization')
  1078. ->with($parent)
  1079. ->willReturn($networkOrganization);
  1080. $result = $organizationFactory->makeNetworkOrganization($organizationCreationRequest);
  1081. $this->assertEquals(
  1082. $network,
  1083. $result->getNetwork()
  1084. );
  1085. }
  1086. public function testMakeAdminAccess(): void
  1087. {
  1088. $organizationFactory = $this->getOrganizationFactoryMockFor('makeAdminAccess');
  1089. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1090. $organizationCreationRequest->method('getSubdomain')->willReturn('foo');
  1091. $adminAccess = $organizationFactory->makeAdminAccess($organizationCreationRequest);
  1092. $this->assertTrue(
  1093. $adminAccess->getAdminAccess()
  1094. );
  1095. $this->assertEquals(
  1096. 'adminfoo',
  1097. $adminAccess->getPerson()->getUsername()
  1098. );
  1099. $this->assertEquals(
  1100. 32,
  1101. strlen($adminAccess->getPerson()->getPassword())
  1102. );
  1103. }
  1104. public function testMakeCycles(): void
  1105. {
  1106. $organizationFactory = $this->getOrganizationFactoryMockFor('makeCycles');
  1107. $cycles = $organizationFactory->makeCycles();
  1108. $cyclesExpectedData = [
  1109. ['Cycle initiation', 10, CycleEnum::INITIATION_CYCLE],
  1110. ['Cycle 1', 20, CycleEnum::CYCLE_1],
  1111. ['Cycle 2', 30, CycleEnum::CYCLE_2],
  1112. ['Cycle 3', 40, CycleEnum::CYCLE_3],
  1113. ['Cycle 4', 50, CycleEnum::CYCLE_4],
  1114. ['Hors cycle', 60, CycleEnum::OUT_CYCLE],
  1115. ];
  1116. $i = 0;
  1117. foreach ($cycles as $cycle) {
  1118. $this->assertEquals(
  1119. $cyclesExpectedData[$i][0],
  1120. $cycle->getLabel()
  1121. );
  1122. $this->assertEquals(
  1123. $cyclesExpectedData[$i][1],
  1124. $cycle->getOrder()
  1125. );
  1126. $this->assertEquals(
  1127. $cyclesExpectedData[$i][2],
  1128. $cycle->getCycleEnum()
  1129. );
  1130. $this->assertFalse(
  1131. $cycle->getIsSystem()
  1132. );
  1133. ++$i;
  1134. }
  1135. }
  1136. public function testMakeAccessNewPerson(): void
  1137. {
  1138. $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess');
  1139. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1140. $organizationMemberCreationRequest->method('getUsername')->willReturn('bob');
  1141. $organizationMemberCreationRequest->method('getName')->willReturn('Bob');
  1142. $organizationMemberCreationRequest->method('getGivenName')->willReturn('bOBBy');
  1143. $organizationMemberCreationRequest->method('getGender')->willReturn(GenderEnum::MISTER);
  1144. $this->personRepository
  1145. ->method('findOneBy')
  1146. ->with(['username' => 'bob'], null)
  1147. ->willReturn(null);
  1148. $personAddressPostal = $this->getMockBuilder(PersonAddressPostal::class)->getMock();
  1149. $organizationFactory
  1150. ->expects(self::once())
  1151. ->method('makePersonPostalAddress')
  1152. ->with($organizationMemberCreationRequest)
  1153. ->willReturn($personAddressPostal);
  1154. $contactPoint = $this->getMockBuilder(ContactPoint::class)->getMock();
  1155. $organizationFactory
  1156. ->expects(self::once())
  1157. ->method('makePersonContactPoint')
  1158. ->with($organizationMemberCreationRequest)
  1159. ->willReturn($contactPoint);
  1160. $functionType = $this->getMockBuilder(FunctionType::class)->getMock();
  1161. $this->functionTypeRepository
  1162. ->expects(self::once())
  1163. ->method('findOneBy')
  1164. ->with(['mission' => FunctionEnum::ACCOUNTANT])
  1165. ->willReturn($functionType);
  1166. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1167. $access = $organizationFactory->makeAccess(
  1168. $organizationMemberCreationRequest,
  1169. FunctionEnum::ACCOUNTANT,
  1170. $creationDate,
  1171. 1
  1172. );
  1173. $this->assertInstanceOf(Access::class, $access);
  1174. $this->assertEquals(
  1175. 'bob',
  1176. $access->getPerson()->getUsername()
  1177. );
  1178. $this->assertTrue(
  1179. strlen($access->getPerson()->getPassword()) === 32
  1180. );
  1181. $this->assertEquals(
  1182. 'Bob',
  1183. $access->getPerson()->getName()
  1184. );
  1185. $this->assertEquals(
  1186. 'Bobby',
  1187. $access->getPerson()->getGivenName()
  1188. );
  1189. $this->assertEquals(
  1190. [$personAddressPostal],
  1191. $access->getPerson()->getPersonAddressPostal()->toArray()
  1192. );
  1193. $this->assertEquals(
  1194. [$contactPoint],
  1195. $access->getPerson()->getContactPoints()->toArray()
  1196. );
  1197. $this->assertEquals(
  1198. $functionType,
  1199. $access->getOrganizationFunction()->first()->getFunctionType()
  1200. );
  1201. $this->assertEquals(
  1202. $creationDate,
  1203. $access->getOrganizationFunction()->first()->getStartDate()
  1204. );
  1205. }
  1206. public function testMakeAccessNewPersonUsernameAlreadyInUse(): void
  1207. {
  1208. $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess');
  1209. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1210. $organizationMemberCreationRequest->method('getUsername')->willReturn('bob');
  1211. $organizationMemberCreationRequest->method('getName')->willReturn('Bob');
  1212. $organizationMemberCreationRequest->method('getGivenName')->willReturn('bOBBy');
  1213. $organizationMemberCreationRequest->method('getGender')->willReturn(GenderEnum::MISTER);
  1214. $person = $this->getMockBuilder(Person::class)->getMock();
  1215. $this->personRepository
  1216. ->method('findOneBy')
  1217. ->with(['username' => 'bob'], null)
  1218. ->willReturn($person);
  1219. $organizationFactory
  1220. ->expects(self::never())
  1221. ->method('makePersonPostalAddress');
  1222. $organizationFactory
  1223. ->expects(self::never())
  1224. ->method('makePersonContactPoint');
  1225. $this->expectException(\RuntimeException::class);
  1226. $this->expectExceptionMessage('Username already in use : bob');
  1227. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1228. $organizationFactory->makeAccess(
  1229. $organizationMemberCreationRequest,
  1230. FunctionEnum::ADHERENT,
  1231. $creationDate,
  1232. 1
  1233. );
  1234. }
  1235. public function testMakeAccessExistingPerson(): void
  1236. {
  1237. $organizationFactory = $this->getOrganizationFactoryMockFor('makeAccess');
  1238. $person = $this->getMockBuilder(Person::class)->getMock();
  1239. $this->personRepository
  1240. ->expects(self::once())
  1241. ->method('find')
  1242. ->with(123)
  1243. ->willReturn($person);
  1244. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1245. $functionType = $this->getMockBuilder(FunctionType::class)->getMock();
  1246. $this->functionTypeRepository
  1247. ->expects(self::once())
  1248. ->method('findOneBy')
  1249. ->with(['mission' => FunctionEnum::ACCOUNTANT])
  1250. ->willReturn($functionType);
  1251. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1252. $access = $organizationFactory->makeAccess(
  1253. 123,
  1254. FunctionEnum::ACCOUNTANT,
  1255. $creationDate,
  1256. 1
  1257. );
  1258. $this->assertInstanceOf(Access::class, $access);
  1259. $this->assertEquals(
  1260. $person,
  1261. $access->getPerson()
  1262. );
  1263. $this->assertEquals(
  1264. $functionType,
  1265. $access->getOrganizationFunction()->first()->getFunctionType()
  1266. );
  1267. $this->assertEquals(
  1268. $creationDate,
  1269. $access->getOrganizationFunction()->first()->getStartDate()
  1270. );
  1271. }
  1272. public function testMakeAccessPostalAddress()
  1273. {
  1274. $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonPostalAddress');
  1275. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1276. $organizationMemberCreationRequest->method('getStreetAddress1')->willReturn('Aaa');
  1277. $organizationMemberCreationRequest->method('getStreetAddress2')->willReturn('Bbb');
  1278. $organizationMemberCreationRequest->method('getStreetAddress3')->willReturn(null);
  1279. $organizationMemberCreationRequest->method('getPostalCode')->willReturn('00000');
  1280. $organizationMemberCreationRequest->method('getCity')->willReturn('city');
  1281. $organizationMemberCreationRequest->method('getCountryId')->willReturn(123);
  1282. $country = $this->getMockBuilder(Country::class)->getMock();
  1283. $this->countryRepository
  1284. ->expects(self::once())
  1285. ->method('find')
  1286. ->with(123)
  1287. ->willReturn($country);
  1288. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1289. $personPostalAddress = $organizationFactory->makePersonPostalAddress(
  1290. $organizationMemberCreationRequest,
  1291. $creationDate,
  1292. 1
  1293. );
  1294. $this->assertEquals(
  1295. AddressPostalPersonTypeEnum::ADDRESS_PRINCIPAL,
  1296. $personPostalAddress->getType()
  1297. );
  1298. $postalAddress = $personPostalAddress->getAddressPostal();
  1299. $this->assertEquals('Aaa', $postalAddress->getStreetAddress());
  1300. $this->assertEquals('Bbb', $postalAddress->getStreetAddressSecond());
  1301. $this->assertEquals(null, $postalAddress->getStreetAddressThird());
  1302. $this->assertEquals('00000', $postalAddress->getPostalCode());
  1303. $this->assertEquals('city', $postalAddress->getAddressCity());
  1304. $this->assertEquals($country, $postalAddress->getAddressCountry());
  1305. }
  1306. public function testMakeAccessContactPoint(): void
  1307. {
  1308. $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint');
  1309. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1310. $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405');
  1311. $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com');
  1312. $organizationMemberCreationRequest->method('getMobile')->willReturn('+33607080910');
  1313. $this->phoneNumberUtil
  1314. ->expects(self::exactly(2))
  1315. ->method('isPossibleNumber')
  1316. ->willReturnMap([
  1317. ['+33102030405', null, true],
  1318. ['+33607080910', null, true],
  1319. ]);
  1320. $phoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock();
  1321. $mobilePhoneNumber = $this->getMockBuilder(PhoneNumber::class)->getMock();
  1322. $this->phoneNumberUtil
  1323. ->expects(self::exactly(2))
  1324. ->method('parse')
  1325. ->willReturnMap([
  1326. ['+33102030405', null, null, false, $phoneNumber],
  1327. ['+33607080910', null, null, false, $mobilePhoneNumber],
  1328. ]);
  1329. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1330. $contactPoint = $organizationFactory->makePersonContactPoint(
  1331. $organizationMemberCreationRequest,
  1332. $creationDate,
  1333. 1
  1334. );
  1335. $this->assertEquals(
  1336. ContactPointTypeEnum::PRINCIPAL,
  1337. $contactPoint->getContactType()
  1338. );
  1339. $this->assertEquals(
  1340. 'email@domain.com',
  1341. $contactPoint->getEmail()
  1342. );
  1343. $this->assertEquals(
  1344. $phoneNumber,
  1345. $contactPoint->getTelphone()
  1346. );
  1347. $this->assertEquals(
  1348. $mobilePhoneNumber,
  1349. $contactPoint->getMobilPhone()
  1350. );
  1351. }
  1352. public function testMakeAccessContactPointInvalidPhone(): void
  1353. {
  1354. $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint');
  1355. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1356. $organizationMemberCreationRequest->method('getUsername')->willReturn('bob');
  1357. $organizationMemberCreationRequest->method('getPhone')->willReturn('invalid');
  1358. $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com');
  1359. $organizationMemberCreationRequest->method('getMobile')->willReturn('+33607080910');
  1360. $this->phoneNumberUtil
  1361. ->expects(self::once())
  1362. ->method('isPossibleNumber')
  1363. ->with('invalid')
  1364. ->willReturn(false);
  1365. $this->phoneNumberUtil
  1366. ->expects(self::never())
  1367. ->method('parse');
  1368. $this->expectException(\RuntimeException::class);
  1369. $this->expectExceptionMessage('Phone number is invalid or missing (person: bob)');
  1370. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1371. $organizationFactory->makePersonContactPoint(
  1372. $organizationMemberCreationRequest,
  1373. $creationDate,
  1374. 1
  1375. );
  1376. }
  1377. public function testMakeAccessContactPointInvalidMobilePhone(): void
  1378. {
  1379. $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint');
  1380. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1381. $organizationMemberCreationRequest->method('getUsername')->willReturn('bob');
  1382. $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405');
  1383. $organizationMemberCreationRequest->method('getEmail')->willReturn('email@domain.com');
  1384. $organizationMemberCreationRequest->method('getMobile')->willReturn('invalid');
  1385. $this->phoneNumberUtil
  1386. ->expects(self::exactly(2))
  1387. ->method('isPossibleNumber')
  1388. ->willReturnMap([
  1389. ['+33102030405', null, true],
  1390. ['invalid', null, false],
  1391. ]);
  1392. $this->phoneNumberUtil
  1393. ->expects(self::never())
  1394. ->method('parse');
  1395. $this->expectException(\RuntimeException::class);
  1396. $this->expectExceptionMessage('Mobile phone number is invalid (person: bob)');
  1397. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1398. $organizationFactory->makePersonContactPoint(
  1399. $organizationMemberCreationRequest,
  1400. $creationDate,
  1401. 1
  1402. );
  1403. }
  1404. public function testMakePersonContactPointNoMobile(): void
  1405. {
  1406. $organizationFactory = $this->getOrganizationFactoryMockFor('makePersonContactPoint');
  1407. $organizationMemberCreationRequest = $this->getMockBuilder(OrganizationMemberCreationRequest::class)->getMock();
  1408. $organizationMemberCreationRequest->method('getPhone')->willReturn('+33102030405');
  1409. $organizationMemberCreationRequest->method('getMobile')->willReturn(null);
  1410. $this->phoneNumberUtil
  1411. ->expects(self::once())
  1412. ->method('isPossibleNumber')
  1413. ->with('+33102030405')
  1414. ->willReturn(true);
  1415. $creationDate = $this->getMockBuilder(\DateTime::class)->getMock();
  1416. $contactPoint = $organizationFactory->makePersonContactPoint(
  1417. $organizationMemberCreationRequest,
  1418. $creationDate,
  1419. 1
  1420. );
  1421. $this->assertEquals(
  1422. null,
  1423. $contactPoint->getMobilPhone()
  1424. );
  1425. }
  1426. public function testMakeSubdomain(): void
  1427. {
  1428. $organizationFactory = $this->getOrganizationFactoryMockFor('makeSubdomain');
  1429. $organizationCreationRequest = $this->getMockBuilder(OrganizationCreationRequest::class)->getMock();
  1430. $organizationCreationRequest->method('getSubdomain')->willReturn('subdomain');
  1431. $subdomain = $organizationFactory->makeSubdomain($organizationCreationRequest);
  1432. $this->assertEquals(
  1433. 'subdomain',
  1434. $subdomain->getSubdomain()
  1435. );
  1436. $this->assertTrue(
  1437. $subdomain->isActive()
  1438. );
  1439. }
  1440. public function testCreateTypo3Website(): void
  1441. {
  1442. $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website');
  1443. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1444. $organization->method('getId')->willReturn(123);
  1445. $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
  1446. $response->method('getStatusCode')->willReturn(Response::HTTP_OK);
  1447. $response->method('getContent')->willReturn('{"root_uid": 456}');
  1448. $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response);
  1449. $organization->expects(self::once())->method('setCmsId')->with(456);
  1450. $this->entityManager->expects(self::once())->method('persist')->with($organization);
  1451. $this->entityManager->expects(self::once())->method('flush');
  1452. $result = $organizationFactory->createTypo3Website($organization);
  1453. $this->assertEquals(
  1454. 456,
  1455. $result
  1456. );
  1457. }
  1458. public function testCreateTypo3WebsiteWithError(): void
  1459. {
  1460. $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website');
  1461. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1462. $organization->method('getId')->willReturn(123);
  1463. $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
  1464. $response->method('getStatusCode')->willReturn(Response::HTTP_FORBIDDEN);
  1465. $response->method('getContent')->willReturn('');
  1466. $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response);
  1467. $this->logger
  1468. ->expects(self::once())
  1469. ->method('critical')
  1470. ->with('/!\ A critical error happened while creating the Typo3 website');
  1471. $result = $organizationFactory->createTypo3Website($organization);
  1472. $this->assertNull($result);
  1473. }
  1474. public function testCreateTypo3WebsiteWithInvalidResponse(): void
  1475. {
  1476. $organizationFactory = $this->getOrganizationFactoryMockFor('createTypo3Website');
  1477. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1478. $organization->method('getId')->willReturn(123);
  1479. $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
  1480. $response->method('getStatusCode')->willReturn(Response::HTTP_OK);
  1481. $response->method('getContent')->willReturn('<html lang="fr">Login page</html>');
  1482. $this->typo3Service->expects(self::once())->method('createSite')->with(123)->willReturn($response);
  1483. $this->logger
  1484. ->expects(self::once())
  1485. ->method('critical')
  1486. ->with('/!\ A critical error happened while creating the Typo3 website');
  1487. $result = $organizationFactory->createTypo3Website($organization);
  1488. $this->assertNull($result);
  1489. }
  1490. public function testUpdateAdminassosDb(): void
  1491. {
  1492. $organizationFactory = $this->getOrganizationFactoryMockFor('updateAdminassosDb');
  1493. $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
  1494. $response->method('getStatusCode')->willReturn(Response::HTTP_OK);
  1495. $this->apiLegacyRequestService
  1496. ->expects(self::once())
  1497. ->method('post')
  1498. ->with('/_internal/secure/organization/creation-event', ['organizationId' => 123])
  1499. ->willReturn($response);
  1500. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1501. $organization->method('getId')->willReturn(123);
  1502. $organizationFactory->updateAdminassosDb($organization);
  1503. }
  1504. public function testUpdateAdminassosDbError(): void
  1505. {
  1506. $organizationFactory = $this->getOrganizationFactoryMockFor('updateAdminassosDb');
  1507. $response = $this->getMockBuilder(ResponseInterface::class)->disableOriginalConstructor()->getMock();
  1508. $response->method('getStatusCode')->willReturn(Response::HTTP_BAD_REQUEST);
  1509. $response->method('getContent')->willReturn('some error');
  1510. $this->apiLegacyRequestService
  1511. ->expects(self::once())
  1512. ->method('post')
  1513. ->with('/_internal/secure/organization/creation-event', ['organizationId' => 123])
  1514. ->willReturn($response);
  1515. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1516. $organization->method('getId')->willReturn(123);
  1517. $this->expectException(\RuntimeException::class);
  1518. $this->expectExceptionMessage('An error happened while updating the adminassos database: some error');
  1519. $organizationFactory->updateAdminassosDb($organization);
  1520. }
  1521. public function testNormalizeIdentificationField(): void
  1522. {
  1523. $organizationFactory = $this->getOrganizationFactoryMockFor('normalizeIdentificationField');
  1524. $this->assertEquals(
  1525. 'c+est+une+phrase+normalisee+',
  1526. $organizationFactory->normalizeIdentificationField("C'est une phrase normalisée.")
  1527. );
  1528. }
  1529. public function testDelete(): void
  1530. {
  1531. $organizationFactory = $this->getOrganizationFactoryMockFor('delete');
  1532. $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock();
  1533. $organizationDeletionRequest->method('getOrganizationId')->willReturn(123);
  1534. $parameters = $this->getMockBuilder(Parameters::class)->getMock();
  1535. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1536. $organization->method('getId')->willReturn(123);
  1537. $organization->method('getParameters')->willReturn($parameters);
  1538. $this->organizationRepository
  1539. ->expects(self::once())
  1540. ->method('find')
  1541. ->with(123)
  1542. ->willReturn($organization);
  1543. $this->entityManager->expects(self::once())->method('beginTransaction');
  1544. $this->entityManager->expects(self::once())->method('flush');
  1545. $this->entityManager->expects(self::once())->method('commit');
  1546. $this->entityManager->expects(self::never())->method('rollback');
  1547. $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization);
  1548. $this->entityManager->expects(self::exactly(2))->method('remove')->withConsecutive(
  1549. [$parameters],
  1550. [$organization]
  1551. );
  1552. $organizationFactory->expects(self::once())->method('deleteTypo3Website')->with($organization);
  1553. $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->with($organization);
  1554. $organizationFactory->expects(self::once())->method('deleteOrganizationFiles')->with($organization);
  1555. $organizationFactory->expects(self::once())->method('deleteDirectoriesV1')->with($organization);
  1556. $organizationFactory->expects(self::once())->method('deleteDirectories59')->with($organization);
  1557. $organizationDeletionRequest
  1558. ->expects(self::once())
  1559. ->method('setStatus')
  1560. ->with(OrganizationDeletionRequest::STATUS_OK);
  1561. $result = $organizationFactory->delete($organizationDeletionRequest);
  1562. $this->assertEquals(
  1563. $organizationDeletionRequest,
  1564. $result
  1565. );
  1566. }
  1567. public function testDeleteWithRollback(): void
  1568. {
  1569. $organizationFactory = $this->getOrganizationFactoryMockFor('delete');
  1570. $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock();
  1571. $organizationDeletionRequest->method('getOrganizationId')->willReturn(123);
  1572. $parameters = $this->getMockBuilder(Parameters::class)->getMock();
  1573. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1574. $organization->method('getParameters')->willReturn($parameters);
  1575. $this->organizationRepository
  1576. ->expects(self::once())
  1577. ->method('find')
  1578. ->with(123)
  1579. ->willReturn($organization);
  1580. $this->entityManager->expects(self::once())->method('beginTransaction');
  1581. $this->entityManager->expects(self::never())->method('flush');
  1582. $this->entityManager->expects(self::never())->method('commit');
  1583. $this->entityManager->expects(self::once())->method('rollback');
  1584. $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization);
  1585. $this->entityManager->method('remove')->willThrowException(new \Exception('some error'));
  1586. $organizationFactory->expects(self::never())->method('deleteTypo3Website');
  1587. $organizationFactory->expects(self::never())->method('switchDolibarrSocietyToProspect');
  1588. $organizationFactory->expects(self::never())->method('deleteOrganizationFiles');
  1589. $organizationFactory->expects(self::never())->method('deleteDirectoriesV1');
  1590. $organizationFactory->expects(self::never())->method('deleteDirectories59');
  1591. $organizationDeletionRequest
  1592. ->expects(self::never())
  1593. ->method('setStatus');
  1594. $this->logger
  1595. ->expects(self::once())
  1596. ->method('critical')
  1597. ->with($this->callback(function ($arg) {
  1598. return is_string($arg) && str_contains($arg, 'An error happened, operation cancelled') && str_contains($arg, 'some error');
  1599. }));
  1600. $this->expectException(\Exception::class);
  1601. $organizationFactory->delete($organizationDeletionRequest);
  1602. }
  1603. public function testDeleteWithNonBlockingErrors(): void
  1604. {
  1605. $organizationFactory = $this->getOrganizationFactoryMockFor('delete');
  1606. $organizationDeletionRequest = $this->getMockBuilder(OrganizationDeletionRequest::class)->getMock();
  1607. $organizationDeletionRequest->method('getOrganizationId')->willReturn(123);
  1608. $parameters = $this->getMockBuilder(Parameters::class)->getMock();
  1609. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1610. $organization->method('getId')->willReturn(123);
  1611. $organization->method('getParameters')->willReturn($parameters);
  1612. $this->organizationRepository
  1613. ->expects(self::once())
  1614. ->method('find')
  1615. ->with(123)
  1616. ->willReturn($organization);
  1617. $this->entityManager->expects(self::once())->method('beginTransaction');
  1618. $this->entityManager->expects(self::once())->method('flush');
  1619. $this->entityManager->expects(self::once())->method('commit');
  1620. $this->entityManager->expects(self::never())->method('rollback');
  1621. $organizationFactory->expects(self::once())->method('deleteOrganizationAccesses')->with($organization);
  1622. $this->entityManager->expects(self::exactly(2))->method('remove')->withConsecutive(
  1623. [$parameters],
  1624. [$organization]
  1625. );
  1626. $organizationFactory->expects(self::once())->method('deleteTypo3Website')->willThrowException(new \Exception('some error'));
  1627. $organizationFactory->expects(self::once())->method('switchDolibarrSocietyToProspect')->willThrowException(new \Exception('some error'));
  1628. $organizationFactory->expects(self::once())->method('deleteOrganizationFiles')->willThrowException(new \Exception('some error'));
  1629. $organizationFactory->expects(self::once())->method('deleteDirectoriesV1')->willThrowException(new \Exception('some error'));
  1630. $organizationFactory->expects(self::once())->method('deleteDirectories59')->willThrowException(new \Exception('some error'));
  1631. $organizationDeletionRequest
  1632. ->expects(self::once())
  1633. ->method('setStatus')
  1634. ->with(OrganizationDeletionRequest::STATUS_OK_WITH_ERRORS);
  1635. $this->logger
  1636. ->expects(self::exactly(5))
  1637. ->method('critical')
  1638. ->withConsecutive(
  1639. ['An error happened while deleting the Typo3 website, please proceed manually.'],
  1640. ['An error happened while updating the Dolibarr society, please proceed manually.'],
  1641. ['An error happened while deleting the local directories, please proceed manually.'],
  1642. ['An error happened while deleting the V1 directories, please proceed manually.'],
  1643. ['An error happened while deleting the 5.9 directories, please proceed manually.'],
  1644. );
  1645. $result = $organizationFactory->delete($organizationDeletionRequest);
  1646. $this->assertEquals(
  1647. $organizationDeletionRequest,
  1648. $result
  1649. );
  1650. }
  1651. public function testDeleteOrganizationAccesses(): void
  1652. {
  1653. $organizationFactory = $this->getOrganizationFactoryMockFor('deleteOrganizationAccesses');
  1654. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1655. $access1 = $this->getMockBuilder(Access::class)->getMock();
  1656. $access2 = $this->getMockBuilder(Access::class)->getMock();
  1657. $access_other = $this->getMockBuilder(Access::class)->getMock();
  1658. $person1 = $this->getMockBuilder(Person::class)->getMock();
  1659. $person1->method('getAccesses')->willReturn(new ArrayCollection([$access1]));
  1660. $access1->method('getPerson')->willReturn($person1);
  1661. $person2 = $this->getMockBuilder(Person::class)->getMock();
  1662. $person2->method('getAccesses')->willReturn(new ArrayCollection([$access2, $access_other]));
  1663. $access2->method('getPerson')->willReturn($person2);
  1664. $organization->method('getAccesses')->willReturn(new ArrayCollection([$access1, $access2]));
  1665. $this->entityManager
  1666. ->expects(self::exactly(3))
  1667. ->method('remove')
  1668. ->withConsecutive(
  1669. [$person1],
  1670. [$access1],
  1671. [$access2],
  1672. );
  1673. $organizationFactory->deleteOrganizationAccesses($organization);
  1674. }
  1675. public function testSwitchDolibarrSocietyToProspect(): void
  1676. {
  1677. $organizationFactory = $this->getOrganizationFactoryMockFor('switchDolibarrSocietyToProspect');
  1678. $organization = $this->getMockBuilder(Organization::class)->getMock();
  1679. $organization->method('getId')->willReturn(123);
  1680. $this->dolibarrApiService
  1681. ->expects(self::once())
  1682. ->method('switchSocietyToProspect')
  1683. ->with(123);
  1684. $organizationFactory->switchDolibarrSocietyToProspect($organization);
  1685. }
  1686. }