OrganizationFactoryTest.php 89 KB

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