OrganizationFactoryTest.php 92 KB

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